pax_global_header00006660000000000000000000000064144600220220014502gustar00rootroot0000000000000052 comment=3555aa113d350e94c8d17c5ff519d1acaf9aefb9 HIPCC-rocm-5.7.1/000077500000000000000000000000001446002202200133005ustar00rootroot00000000000000HIPCC-rocm-5.7.1/.github/000077500000000000000000000000001446002202200146405ustar00rootroot00000000000000HIPCC-rocm-5.7.1/.github/dependabot.yml000066400000000000000000000010421446002202200174650ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "pip" # See documentation for possible values directory: "/docs/.sphinx" # Location of package manifests open-pull-requests-limit: 10 schedule: interval: "daily" HIPCC-rocm-5.7.1/.gitignore000066400000000000000000000003431446002202200152700ustar00rootroot00000000000000# Merge files created by git. *.orig # Reject files created by patch. *.rej # Nested build directory. /build* # documentation artifacts build/ _build/ _images/ _static/ _templates/ _toc.yml docBin/ _doxygen/ HIPCC-rocm-5.7.1/.jenkins/000077500000000000000000000000001446002202200150175ustar00rootroot00000000000000HIPCC-rocm-5.7.1/.jenkins/Jenkinsfile000066400000000000000000000110661446002202200172070ustar00rootroot00000000000000def hipBuildTest(String backendLabel) { node(backendLabel) { stage("Source sync ${backendLabel}") { // Checkout hip repository with the PR patch dir("${WORKSPACE}/HIPCC") { checkout scm env.HIPCC_DIR = "${WORKSPACE}" + "/HIPCC" } // Clone HIP repository dir("${WORKSPACE}/hip") { git branch: 'develop', url: 'https://github.com/ROCm-Developer-Tools/HIP' env.HIP_DIR = "${WORKSPACE}" + "/hip" } // Clone clr repository dir("${WORKSPACE}/clr") { git branch: 'develop', credentialsId: 'branch-credentials', url: 'https://github.com/ROCm-Developer-Tools/clr' env.CLR_DIR = "${WORKSPACE}" + "/clr" } // Clone hip-tests repository dir("${WORKSPACE}/hip-tests") { git branch: 'develop', url: 'https://github.com/ROCm-Developer-Tools/hip-tests' } } stage("Build - HIPCC") { // Running the build on HIPCC workspace dir("${WORKSPACE}/HIPCC") { sh """#!/usr/bin/env bash set -x rm -rf build mkdir build cd build/ cmake .. make """ } } stage("BUILD HIP - ${backendLabel}") { // Running the build on clr workspace dir("${WORKSPACE}/clr") { sh """#!/usr/bin/env bash set -x rm -rf build mkdir -p build cd build # Check if backend label contains string "amd" or backend host is a server with amd gpu if [[ $backendLabel =~ amd ]]; then cmake -DHIPCC_BIN_DIR=\$HIPCC_DIR/bin -DCLR_BUILD_HIP=ON -DHIP_PATH=\$PWD/install -DHIP_COMMON_DIR=\$HIP_DIR -DCMAKE_PREFIX_PATH="/opt/rocm/" -DCMAKE_INSTALL_PREFIX=\$PWD/install .. else cmake -DHIPCC_BIN_DIR=\$HIPCC_DIR/bin -DCLR_BUILD_HIP=ON -DHIP_PLATFORM=nvidia -DHIP_COMMON_DIR=\$HIP_DIR -DCMAKE_INSTALL_PREFIX=\$PWD/install .. fi make -j\$(nproc) make install -j\$(nproc) """ } } stage("BUILD HIP TESTS - ${backendLabel}") { // Running the build on HIP TESTS workspace dir("${WORKSPACE}/hip-tests") { env.HIP_PATH = "${CLR_DIR}" + "/build/install" sh """#!/usr/bin/env bash set -x rm -rf build mkdir -p build cd build echo "testing $HIP_PATH" # Check if backend label contains string "amd" or backend host is a server with amd gpu if [[ $backendLabel =~ amd ]]; then cmake -DHIP_PLATFORM=amd ../catch else export HIP_PLATFORM=nvidia cmake -DHIP_PLATFORM=nvidia ../catch fi make -j\$(nproc) build_tests """ } } timeout(time: 1, unit: 'HOURS') { stage("TEST - ${backendLabel}") { dir("${WORKSPACE}/hip-tests") { sh """#!/usr/bin/env bash set -x cd build if [[ $backendLabel =~ amd ]]; then ctest --overwrite BuildDirectory=. --output-junit hiptest_output_catch_amd.xml else ctest --overwrite BuildDirectory=. --output-junit hiptest_output_catch_nvidia.xml -E 'Unit_hipMemcpyHtoD_Positive_Synchronization_Behavior|Unit_hipMemcpy_Positive_Synchronization_Behavior|Unit_hipFreeNegativeHost' fi """ } } } } } timestamps { node('external-bootstrap') { skipDefaultCheckout() // labels belonging to each backend - AMD, NVIDIA String[] labels = ['hip-amd-vg20-ubu1804', 'hip-nvidia-rtx5000-ubu1804'] buildMap = [:] labels.each { backendLabel -> echo "backendLabel: ${backendLabel}" buildMap[backendLabel] = { hipBuildTest(backendLabel) } } buildMap['failFast'] = false parallel buildMap } } HIPCC-rocm-5.7.1/.readthedocs.yaml000066400000000000000000000004171446002202200165310ustar00rootroot00000000000000# Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details version: 2 sphinx: configuration: docs/conf.py formats: [htmlzip] python: version: "3.8" install: - requirements: docs/.sphinx/requirements.txt HIPCC-rocm-5.7.1/CMakeLists.txt000066400000000000000000000106171446002202200160450ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.13.4) project(hipcc VERSION "1.0.0" LANGUAGES C CXX) set(hipcc_NAME "${PROJECT_NAME}") include(CMakePackageConfigHelpers) include(GNUInstallDirs) find_package(ROCM QUIET) if(ROCM_FOUND) include(ROCMSetupVersion) rocm_setup_version(VERSION "${hipcc_VERSION}") endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) set(ADDITIONAL_SHARED_LIBRARIES_TO_LINK libstdc++fs.so) set(HIPCC_BIN hipcc.bin) set(HIPCC_SOURCES src/hipBin.cpp) set(HIPCONFIG_BIN hipconfig.bin) set(HIPCONFIG_SOURCES src/hipBin.cpp) add_executable(${HIPCC_BIN} ${HIPCC_SOURCES}) if(NOT WIN32) # C++17 does not require std lib linking. target_link_libraries(${HIPCC_BIN} ${ADDITIONAL_SHARED_LIBRARIES_TO_LINK}) endif() add_executable(${HIPCONFIG_BIN} ${HIPCONFIG_SOURCES}) if(NOT WIN32) # C++17 does not require std lib linking. target_link_libraries(${HIPCONFIG_BIN} ${ADDITIONAL_SHARED_LIBRARIES_TO_LINK}) endif() # Copy scripts and batch files to build directory. file(COPY ${PROJECT_SOURCE_DIR}/bin/ DESTINATION ${PROJECT_BINARY_DIR}) set(CPACK_GENERATOR "DEB;RPM;ZIP" CACHE STRING "Default packaging generators") set(CPACK_PACKAGE_CONTACT "ROCm Compiler Support ") set(CPACK_PACKAGE_DESCRIPTION "HIP Compiler Driver") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_PACKAGE_VENDOR "Advanced Micro Devices, Inc.") set(CPACK_PACKAGE_VERSION_MAJOR "${hipcc_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${hipcc_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${hipcc_VERSION_PATCH}") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt") # Debian-specific packaging variables. set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") set(CPACK_DEBIAN_PACKAGE_DEPENDS "perl (>= 5.0), libfile-basedir-perl, hip-dev, rocm-core, rocm-llvm") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/ROCm-Developer-Tools/HIPCC") if(DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE}) set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE}) else() set(CPACK_DEBIAN_PACKAGE_RELEASE "local") endif() # RPM-specific packaging variables. set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") set(CPACK_RPM_PACKAGE_LICENSE "MIT") set(CPACK_RPM_PACKAGE_REQUIRES "perl >= 5.0, perl-File-BaseDir, hip-devel, rocm-core, rocm-llvm") set(CPACK_RPM_PACKAGE_AUTOREQPROV 0) if(DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE}) set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE}) else() set(CPACK_RPM_PACKAGE_RELEASE "local") endif() if(CPACK_RPM_PACKAGE_RELEASE) set(CPACK_RPM_PACKAGE_RELEASE_DIST ON) endif() # ROCM versioning. set(ROCM_VERSION_FOR_PACKAGE "") if(DEFINED ENV{ROCM_LIBPATCH_VERSION}) set(ROCM_VERSION_FOR_PACKAGE $ENV{ROCM_LIBPATCH_VERSION}) elseif(DEFINED ENV{ROCM_VERSION}) string(REGEX REPLACE "." "" ROCM_VERSION_FOR_PACKAGE $ENV{ROCM_VERSION}) else() set(ROCM_VERSION_FOR_PACKAGE "99999") endif() set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.${ROCM_VERSION_FOR_PACKAGE}") # Exclude Windows specific BAT scripts from install/packaging for Linux. if (NOT WIN32) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin DESTINATION . USE_SOURCE_PERMISSIONS DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE FILES_MATCHING PATTERN "*" PATTERN "*.bat" EXCLUDE) else () install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin DESTINATION . USE_SOURCE_PERMISSIONS DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endif() install(FILES "LICENSE.txt" "README.md" COMPONENT ${hipcc_NAME} DESTINATION ${CMAKE_INSTALL_DOCDIR}) install(TARGETS ${HIPCC_BIN} COMPONENT ${hipcc_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS ${HIPCONFIG_BIN} COMPONENT ${hipcc_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # TODO: WIN32 check need to be removed if backward # compatibility is required for WIN32. option(HIPCC_BACKWARD_COMPATIBILITY "Enable HIPCC backward compatibility" ON) if(NOT WIN32) if(HIPCC_BACKWARD_COMPATIBILITY) include(hipcc-backward-compat.cmake) endif() endif() if(NOT ROCM_DEP_ROCMCORE) string(REGEX REPLACE ",? ?rocm-core" "" CPACK_DEBIAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS}) string(REGEX REPLACE ",? ?rocm-core" "" CPACK_RPM_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES}) endif() include(CPack) HIPCC-rocm-5.7.1/LICENSE.txt000066400000000000000000000020671446002202200151300ustar00rootroot00000000000000Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. HIPCC-rocm-5.7.1/README.md000066400000000000000000000056651446002202200145730ustar00rootroot00000000000000# HIP compiler driver (hipcc) ## Table of Contents - [hipcc](#hipcc) * [Documentation](#documentation) * [Environment Variables](#envVar) * [Usage](#hipcc-usage) * [Building](#building) * [Testing](#testing) ## hipcc `hipcc` is a compiler driver utility that will call clang or nvcc, depending on target, and pass the appropriate include and library options for the target compiler and HIP infrastructure. Historically, `hipcc` was provided as a script in the HIP repo ( https://github.com/ROCm-Developer-Tools/HIP/blob/main/bin/hipcc ). The `hipcc` provided in this project provides the same functionality, but is a binary rather than a script. At some point in the future, the hipcc script will be deprecated and ultimately removed from the HIP repo. `hipcc` will pass-through options to the target compiler. The tools calling hipcc must ensure the compiler options are appropriate for the target compiler. ## Documentation Run the steps below to build documentation locally. ``` cd docs pip3 install -r .sphinx/requirements.txt python3 -m sphinx -T -E -b html -d _build/doctrees -D language=en . _build/html ``` ### Environment Variables The environment variable HIP_PLATFORM may be used to specify amd/nvidia: - HIP_PLATFORM='amd' or HIP_PLATFORM='nvidia'. - If HIP_PLATFORM is not set, then hipcc will attempt to auto-detect based on if nvcc is found. Other environment variable controls: - HIP_PATH : Path to HIP directory, default is one dir level above location of hipcc. - CUDA_PATH : Path to CUDA SDK (default /usr/local/cuda). Used on NVIDIA platforms only. - HSA_PATH : Path to HSA dir (defaults to ../../hsa relative to abs_path of hipcc). Used on AMD platforms only. - HIP_ROCCLR_HOME : Path to HIP/ROCclr directory. Used on AMD platforms only. - HIP_CLANG_PATH : Path to HIP-Clang (default to ../../llvm/bin relative to hipcc's abs_path). Used on AMD platforms only. ### hipcc: usage The built executables can be used the same way as the hipcc/hipconfig perl scripts. To use the newly built executables from the build folder use ./ in front of the executable name - Example: ```shell ./hipconfig --help ./hipcc --help ./hipcc --version ./hipconfig --full ``` when the excutables are copied to /opt/rocm/hip/bin or hip/bin. The ./ is not required as the HIP path is added to the envirnoment variables list. ### hipcc: building ```bash mkdir build cd build cmake .. make -j ``` The hipcc and hipconfig executables are created in the current build folder. These executables need to be copied to /opt/rocm/hip/bin folder location. Packaging and installing will be handled in future releases. ### hipcc: testing Currently hipcc/hipconfig executables are tested by building and executing HIP tests. Separate tests for hipcc/hipconfig is currently not planned. HIPCC-rocm-5.7.1/bin/000077500000000000000000000000001446002202200140505ustar00rootroot00000000000000HIPCC-rocm-5.7.1/bin/hipcc000077500000000000000000000047671446002202200151020ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # Need perl > 5.10 to use logic-defined or use 5.006; use v5.10.1; use warnings; use File::Basename; use File::Spec::Functions 'catfile'; # TODO: By default select perl script until change incorporated in HIP build script. my $USE_PERL_SCRIPT = $ENV{'HIP_USE_PERL_SCRIPTS'}; $USE_PERL_SCRIPT //= 1; # use defined-or assignment operator. Use env var, but if not defined default to 1. my $isWindows = ($^O eq 'MSWin32' or $^O eq 'msys'); # escapes args with quotes SWDEV-341955 foreach $arg (@ARGV) { if ($isWindows) { $arg =~ s/[^-a-zA-Z0-9_=+,.:\/\\ ]/\\$&/g; } } my $SCRIPT_DIR=dirname(__FILE__); if ($USE_PERL_SCRIPT) { #Invoke hipcc.pl my $HIPCC_PERL=catfile($SCRIPT_DIR, '/hipcc.pl'); system($^X, $HIPCC_PERL, @ARGV); } else { $BIN_NAME="/hipcc.bin"; if ($isWindows) { $BIN_NAME="/hipcc.bin.exe"; } my $HIPCC_BIN=catfile($SCRIPT_DIR, $BIN_NAME); if ( -e $HIPCC_BIN ) { #Invoke hipcc.bin system($HIPCC_BIN, @ARGV); } else { print "hipcc.bin not present; install HIPCC binaries before proceeding\n"; exit(-1); } } # Because of this wrapper we need to check # the output of the system command for perl and bin # else the failures are ignored and build fails silently if ($? == -1) { exit($?); } elsif ($? & 127) { exit($?); } else { $CMD_EXIT_CODE = $? >> 8; } exit($CMD_EXIT_CODE); HIPCC-rocm-5.7.1/bin/hipcc.bat000077500000000000000000000000511446002202200156250ustar00rootroot00000000000000@set HIPCC="%~dp0hipcc" @perl %HIPCC% %* HIPCC-rocm-5.7.1/bin/hipcc.pl000077500000000000000000000522611446002202200155040ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # Need perl > 5.10 to use logic-defined or use 5.006; use v5.10.1; use warnings; use File::Basename; use File::Temp qw/ :mktemp /; use Cwd; use Cwd 'abs_path'; # HIP compiler driver # Will call clang or nvcc (depending on target) and pass the appropriate include and library options for # the target compiler and HIP infrastructure. # Will pass-through options to the target compiler. The tools calling HIPCC must ensure the compiler # options are appropriate for the target compiler. # Environment variable HIP_PLATFORM is to detect amd/nvidia path: # HIP_PLATFORM='nvidia' or HIP_PLATFORM='amd'. # If HIP_PLATFORM is not set hipcc will attempt auto-detect based on if nvcc is found. # # Other environment variable controls: # HIP_PATH : Path to HIP directory, default is one dir level above location of this script. # CUDA_PATH : Path to CUDA SDK (default /usr/local/cuda). Used on NVIDIA platforms only. # HIP_ROCCLR_HOME : Path to HIP/ROCclr directory. Used on AMD platforms only. # HIP_CLANG_PATH : Path to HIP-Clang (default to ../../llvm/bin relative to this # script's abs_path). Used on AMD platforms only. if(scalar @ARGV == 0){ print "No Arguments passed, exiting ...\n"; exit(-1); } # retrieve --rocm-path hipcc option from command line. # We need to respect this over the env var ROCM_PATH for this compilation. sub get_path_options { my $rocm_path=""; my $hip_path=""; my @CLArgs = @ARGV; foreach $arg (@CLArgs) { if (index($arg,"--rocm-path=") != -1) { ($rocm_path) = $arg=~ /=\s*(.*)\s*$/; next; } if (index($arg,"--hip-path=") != -1) { ($hip_path) = $arg=~ /=\s*(.*)\s*$/; next; } } return ($rocm_path, $hip_path); } $verbose = $ENV{'HIPCC_VERBOSE'} // 0; # Verbose: 0x1=commands, 0x2=paths, 0x4=hipcc args $HIPCC_COMPILE_FLAGS_APPEND=$ENV{'HIPCC_COMPILE_FLAGS_APPEND'}; $HIPCC_LINK_FLAGS_APPEND=$ENV{'HIPCC_LINK_FLAGS_APPEND'}; # Known Features @knownFeatures = ('sramecc-', 'sramecc+', 'xnack-', 'xnack+'); $HIP_LIB_PATH=$ENV{'HIP_LIB_PATH'}; $DEVICE_LIB_PATH=$ENV{'DEVICE_LIB_PATH'}; $HIP_CLANG_HCC_COMPAT_MODE=$ENV{'HIP_CLANG_HCC_COMPAT_MODE'}; # HCC compatibility mode $HIP_COMPILE_CXX_AS_HIP=$ENV{'HIP_COMPILE_CXX_AS_HIP'} // "1"; #--- # Temporary directories my @tmpDirs = (); #--- # Create a new temporary directory and return it sub get_temp_dir { my $tmpdir = mkdtemp("/tmp/hipccXXXXXXXX"); push (@tmpDirs, $tmpdir); return $tmpdir; } #--- # Delete all created temporary directories sub delete_temp_dirs { if (@tmpDirs) { system ('rm -rf ' . join (' ', @tmpDirs)); } return 0; } my $base_dir; BEGIN { $base_dir = dirname(Cwd::realpath(__FILE__) ); my ($rocm_path, $hip_path) = get_path_options(); if ($rocm_path ne '') { # --rocm-path takes precedence over ENV{ROCM_PATH} $ENV{ROCM_PATH}=$rocm_path; } if ($hip_path ne '') { # --rocm-path takes precedence over ENV{ROCM_PATH} $ENV{HIP_PATH}=$hip_path; } } use lib "$base_dir/"; use hipvars; $isWindows = $hipvars::isWindows; $HIP_RUNTIME = $hipvars::HIP_RUNTIME; $HIP_PLATFORM = $hipvars::HIP_PLATFORM; $HIP_COMPILER = $hipvars::HIP_COMPILER; $HIP_CLANG_PATH = $hipvars::HIP_CLANG_PATH; $CUDA_PATH = $hipvars::CUDA_PATH; $HIP_PATH = $hipvars::HIP_PATH; $ROCM_PATH = $hipvars::ROCM_PATH; $HIP_VERSION = $hipvars::HIP_VERSION; $HIP_ROCCLR_HOME = $hipvars::HIP_ROCCLR_HOME; if ($HIP_PLATFORM eq "amd") { $HIP_INCLUDE_PATH = "$HIP_ROCCLR_HOME/include"; if (!defined $HIP_LIB_PATH) { $HIP_LIB_PATH = "$HIP_ROCCLR_HOME/lib"; } } if ($verbose & 0x2) { print ("HIP_PATH=$HIP_PATH\n"); print ("HIP_PLATFORM=$HIP_PLATFORM\n"); print ("HIP_COMPILER=$HIP_COMPILER\n"); print ("HIP_RUNTIME=$HIP_RUNTIME\n"); } # set if user explicitly requests -stdlib=libc++. (else we default to libstdc++ for better interop with g++): $setStdLib = 0; # TODO - set to 0 $default_amdgpu_target = 1; if ($HIP_PLATFORM eq "amd") { $execExtension = ""; if($isWindows) { $execExtension = ".exe"; } $HIPCC="$HIP_CLANG_PATH/clang++" . $execExtension; # If $HIPCC clang++ is not compiled, use clang instead if ( ! -e $HIPCC ) { $HIPCC="$HIP_CLANG_PATH/clang" . $execExtension; $HIPLDFLAGS = "--driver-mode=g++"; } # to avoid using dk linker or MSVC linker if($isWindows) { $HIPLDFLAGS .= " -fuse-ld=lld"; $HIPLDFLAGS .= " --ld-path=$HIP_CLANG_PATH/lld-link.exe"; # escape possible spaces in path name $HIPCC =~ s/\s/\\$&/g; } # get Clang RT Builtin path $HIP_CLANG_RT_LIB = `$HIPCC --print-runtime-dir`; chomp($HIP_CLANG_RT_LIB); if (! defined $HIP_INCLUDE_PATH) { $HIP_INCLUDE_PATH = "$HIP_PATH/include"; } if (! defined $HIP_LIB_PATH) { $HIP_LIB_PATH = "$HIP_PATH/lib"; } if ($verbose & 0x2) { print ("ROCM_PATH=$ROCM_PATH\n"); if (defined $HIP_ROCCLR_HOME) { print ("HIP_ROCCLR_HOME=$HIP_ROCCLR_HOME\n"); } print ("HIP_CLANG_PATH=$HIP_CLANG_PATH\n"); print ("HIP_INCLUDE_PATH=$HIP_INCLUDE_PATH\n"); print ("HIP_LIB_PATH=$HIP_LIB_PATH\n"); print ("DEVICE_LIB_PATH=$DEVICE_LIB_PATH\n"); print ("HIP_CLANG_RT_LIB=$HIP_CLANG_RT_LIB\n"); } if ($HIP_CLANG_HCC_COMPAT_MODE) { ## Allow __fp16 as function parameter and return type. $HIPCXXFLAGS .= " -Xclang -fallow-half-arguments-and-returns -D__HIP_HCC_COMPAT_MODE__=1"; } } elsif ($HIP_PLATFORM eq "nvidia") { $CUDA_PATH=$ENV{'CUDA_PATH'} // '/usr/local/cuda'; $HIP_INCLUDE_PATH = "$HIP_PATH/include"; if ($verbose & 0x2) { print ("CUDA_PATH=$CUDA_PATH\n"); } $HIPCC="$CUDA_PATH/bin/nvcc"; $HIPCXXFLAGS .= " -Wno-deprecated-gpu-targets "; $HIPCXXFLAGS .= " -isystem $CUDA_PATH/include"; $HIPCFLAGS .= " -isystem $CUDA_PATH/include"; $HIPLDFLAGS = " -Wno-deprecated-gpu-targets -lcuda -lcudart -L$CUDA_PATH/lib64"; } else { printf ("error: unknown HIP_PLATFORM = '$HIP_PLATFORM'"); printf (" or HIP_COMPILER = '$HIP_COMPILER'"); exit (-1); } # Add paths to common HIP includes: $HIPCXXFLAGS .= " -isystem \"$HIP_INCLUDE_PATH\"" ; $HIPCFLAGS .= " -isystem \"$HIP_INCLUDE_PATH\"" ; my $compileOnly = 0; my $needCXXFLAGS = 0; # need to add CXX flags to compile step my $needCFLAGS = 0; # need to add C flags to compile step my $needLDFLAGS = 1; # need to add LDFLAGS to compile step. my $fileTypeFlag = 0; # to see if -x flag is mentioned my $hasOMPTargets = 0; # If OMP targets is mentioned my $hasC = 0; # options contain a c-style file my $hasCXX = 0; # options contain a cpp-style file (NVCC must force recognition as GPU file) my $hasCU = 0; # options contain a cu-style file (HCC must force recognition as GPU file) my $hasHIP = 0; # options contain a hip-style file (HIP-Clang must pass offloading options) my $printHipVersion = 0; # print HIP version my $printCXXFlags = 0; # print HIPCXXFLAGS my $printLDFlags = 0; # print HIPLDFLAGS my $runCmd = 1; my $buildDeps = 0; my $hsacoVersion = 0; my $funcSupp = 0; # enable function support my $rdc = 0; # whether -fgpu-rdc is on my @options = (); my @inputs = (); if ($verbose & 0x4) { print "hipcc-args: ", join (" ", @ARGV), "\n"; } # Handle code object generation my $ISACMD=""; if($HIP_PLATFORM eq "nvidia"){ $ISACMD .= "$HIP_PATH/bin/hipcc -ptx "; if($ARGV[0] eq "--genco"){ foreach $isaarg (@ARGV[1..$#ARGV]){ $ISACMD .= " "; # ignore --rocm-path=xxxx on nvcc nvidia platform if ($isaarg !~ /--rocm-path/) { $ISACMD .= $isaarg; } else { print "Ignoring --rocm-path= on nvidia nvcc platform.\n"; } } if ($verbose & 0x1) { print "hipcc-cmd: ", $ISACMD, "\n"; } system($ISACMD) and die(); exit(0); } } # TODO: convert toolArgs to an array rather than a string my $toolArgs = ""; # arguments to pass to the clang or nvcc tool my $optArg = ""; # -O args # TODO: hipcc uses --amdgpu-target for historical reasons. It should be replaced # by clang option --offload-arch. my @targetOpts = ('--offload-arch=', '--amdgpu-target='); my $targetsStr = ""; my $skipOutputFile = 0; # file followed by -o should not contibute in picking compiler flags my $prevArg = ""; # previous argument foreach $arg (@ARGV) { # Save $arg, it can get changed in the loop. $trimarg = $arg; # TODO: figure out why this space removal is wanted. # TODO: If someone has gone to the effort of quoting the spaces to the shell # TODO: why are we removing it here? $trimarg =~ s/^\s+|\s+$//g; # Remive whitespace my $swallowArg = 0; my $escapeArg = 1; if ($arg eq '-c' or $arg eq '--genco' or $arg eq '-E') { $compileOnly = 1; $needLDFLAGS = 0; } if ($skipOutputFile) { # TODO: handle filename with shell metacharacters $toolArgs .= " \"$arg\""; $prevArg = $arg; $skipOutputFile = 0; next; } if ($arg eq '-o') { $needLDFLAGS = 1; $skipOutputFile = 1; } if(($trimarg eq '-stdlib=libc++') and ($setStdLib eq 0)) { $HIPCXXFLAGS .= " -stdlib=libc++"; $setStdLib = 1; } # Check target selection option: --offload-arch= and --amdgpu-target=... foreach my $targetOpt (@targetOpts) { if (substr($arg, 0, length($targetOpt)) eq $targetOpt) { if ($targetOpt eq '--amdgpu-target=') { print "Warning: The --amdgpu-target option has been deprecated and will be removed in the future. Use --offload-arch instead.\n"; } # If targets string is not empty, add a comma before adding new target option value. $targetsStr .= ($targetsStr ? ',' : ''); $targetsStr .= substr($arg, length($targetOpt)); $default_amdgpu_target = 0; # Collect the GPU arch options and pass them to clang later. if ($HIP_PLATFORM eq "amd") { $swallowArg = 1; } } } if (($arg =~ /--genco/) and $HIP_PLATFORM eq 'amd' ) { $arg = "--cuda-device-only"; } if($trimarg eq '--version') { $printHipVersion = 1; } if($trimarg eq '--short-version') { $printHipVersion = 1; $runCmd = 0; } if($trimarg eq '--cxxflags') { $printCXXFlags = 1; $runCmd = 0; } if($trimarg eq '--ldflags') { $printLDFlags = 1; $runCmd = 0; } if($trimarg eq '-M') { $compileOnly = 1; $buildDeps = 1; } if($trimarg eq '-use-staticlib') { print "Warning: The -use-staticlib option has been deprecated and is no longer needed.\n" } if($trimarg eq '-use-sharedlib') { print "Warning: The -use-sharedlib option has been deprecated and is no longer needed.\n" } if($arg =~ m/^-O/) { $optArg = $arg; } if($arg =~ '--amdhsa-code-object-version=') { print "Warning: The --amdhsa-code-object-version option has been deprecated and will be removed in the future. Use -mllvm -mcode-object-version instead.\n"; $arg =~ s/--amdhsa-code-object-version=//; $hsacoVersion = $arg; $swallowArg = 1; } # nvcc does not handle standard compiler options properly # This can prevent hipcc being used as standard CXX/C Compiler # To fix this we need to pass -Xcompiler for options if (($arg eq '-fPIC' or $arg =~ '-Wl,') and $HIP_COMPILER eq 'nvcc') { $HIPCXXFLAGS .= " -Xcompiler ".$arg; $swallowArg = 1; } if ($arg eq '-x') { $fileTypeFlag = 1; } elsif (($arg eq 'c' and $prevArg eq '-x') or ($arg eq '-xc')) { $fileTypeFlag = 1; $hasC = 1; $hasCXX = 0; $hasHIP = 0; } elsif (($arg eq 'c++' and $prevArg eq '-x') or ($arg eq '-xc++')) { $fileTypeFlag = 1; $hasC = 0; $hasCXX = 1; $hasHIP = 0; } elsif (($arg eq 'hip' and $prevArg eq '-x') or ($arg eq '-xhip')) { $fileTypeFlag = 1; $hasC = 0; $hasCXX = 0; $hasHIP = 1; } elsif ($arg =~ '-fopenmp-targets=') { $hasOMPTargets = 1; } elsif ($arg =~ m/^-/) { # options start with - if ($arg eq '-fgpu-rdc') { $rdc = 1; } elsif ($arg eq '-fno-gpu-rdc') { $rdc = 0; } # Process HIPCC options here: if ($arg =~ m/^--hipcc/) { $swallowArg = 1; if ($arg eq "--hipcc-func-supp") { print "Warning: The --hipcc-func-supp option has been deprecated and will be removed in the future.\n"; $funcSupp = 1; } elsif ($arg eq "--hipcc-no-func-supp") { print "Warning: The --hipcc-no-func-supp option has been deprecated and will be removed in the future.\n"; $funcSupp = 0; } } else { push (@options, $arg); } #print "O: <$arg>\n"; } elsif ($prevArg ne '-o') { # input files and libraries # Skip guessing if `-x {c|c++|hip}` is already specified. # Add proper file extension before each file type # File Extension -> Flag # .c -> -x c # .cpp/.cxx/.cc/.cu/.cuh/.hip -> -x hip if ($fileTypeFlag eq 0) { if ($arg =~ /\.c$/) { $hasC = 1; $needCFLAGS = 1; $toolArgs .= " -x c"; } elsif (($arg =~ /\.cpp$/) or ($arg =~ /\.cxx$/) or ($arg =~ /\.cc$/) or ($arg =~ /\.C$/)) { $needCXXFLAGS = 1; if ($HIP_COMPILE_CXX_AS_HIP eq '0' or $HIP_PLATFORM ne "amd" or $hasOMPTargets eq 1) { $hasCXX = 1; } elsif ($HIP_PLATFORM eq "amd") { $hasHIP = 1; $toolArgs .= " -x hip"; } } elsif ((($arg =~ /\.cu$/ or $arg =~ /\.cuh$/) and $HIP_COMPILE_CXX_AS_HIP ne '0') or ($arg =~ /\.hip$/)) { $needCXXFLAGS = 1; if ($HIP_PLATFORM eq "amd") { $hasHIP = 1; $toolArgs .= " -x hip"; } else { $hasCU = 1; } } } if ($hasC) { $needCFLAGS = 1; } elsif ($hasCXX or $hasHIP) { $needCXXFLAGS = 1; } push (@inputs, $arg); #print "I: <$arg>\n"; } # Produce a version of $arg where characters significant to the shell are # quoted. One could quote everything of course but don't bother for # common characters such as alphanumerics. # Do the quoting here because sometimes the $arg is changed in the loop # Important to have all of '-Xlinker' in the set of unquoted characters. if (not $isWindows and $escapeArg) { $arg =~ s/[^-a-zA-Z0-9_=+,.\/]/\\$&/g; } if ($isWindows and $escapeArg) { $arg =~ s/[^-a-zA-Z0-9_=+,.:\/\\]/\\$&/g; } $toolArgs .= " $arg" unless $swallowArg; $prevArg = $arg; } if($HIP_PLATFORM eq "amd"){ # No AMDGPU target specified at commandline. So look for HCC_AMDGPU_TARGET if($default_amdgpu_target eq 1) { if (defined $ENV{HCC_AMDGPU_TARGET}) { $targetsStr = $ENV{HCC_AMDGPU_TARGET}; } elsif (not $isWindows) { # Else try using rocm_agent_enumerator $ROCM_AGENT_ENUM = "${ROCM_PATH}/bin/rocm_agent_enumerator"; $targetsStr = `${ROCM_AGENT_ENUM} -t GPU`; $targetsStr =~ s/\n/,/g; } $default_amdgpu_target = 0; } # Parse the targets collected in targetStr and set corresponding compiler options. my @targets = split(',', $targetsStr); $GPU_ARCH_OPT = " --offload-arch="; foreach my $val (@targets) { # Ignore 'gfx000' target reported by rocm_agent_enumerator. if ($val ne 'gfx000') { my @procAndFeatures = split(':', $val); $len = scalar @procAndFeatures; my $procName; if($len ge 1 and $len le 3) { # proc and features $procName = $procAndFeatures[0]; for my $i (1 .. $#procAndFeatures) { if (grep($procAndFeatures[$i], @knownFeatures) eq 0) { print "Warning: The Feature: $procAndFeatures[$i] is unknown. Correct compilation is not guaranteed.\n"; } } } else { $procName = $val; } $GPU_ARCH_ARG = $GPU_ARCH_OPT . $val; $HIPLDARCHFLAGS .= $GPU_ARCH_ARG; if ($HIP_PLATFORM eq 'amd' and $hasHIP) { $HIPCXXFLAGS .= $GPU_ARCH_ARG; } } } if ($hsacoVersion > 0) { if ($compileOnly eq 0) { $HIPLDFLAGS .= " -mcode-object-version=$hsacoVersion"; } else { $HIPCXXFLAGS .= " -mcode-object-version=$hsacoVersion"; } } # rocm_agent_enumerator failed! Throw an error and die if linking is required if ($default_amdgpu_target eq 1 and $compileOnly eq 0) { print "No valid AMD GPU target was either specified or found. Please specify a valid target using --offload-arch=.\n" and die(); } $ENV{HCC_EXTRA_LIBRARIES}="\n"; } if ($hasCXX and $HIP_PLATFORM eq 'nvidia') { $HIPCXXFLAGS .= " -x cu"; } if ($buildDeps and $HIP_PLATFORM eq 'nvidia') { $HIPCXXFLAGS .= " -M -D__CUDACC__"; $HIPCFLAGS .= " -M -D__CUDACC__"; } if ($buildDeps and $HIP_PLATFORM eq 'amd') { $HIPCXXFLAGS .= " --cuda-host-only"; } # hipcc currrently requires separate compilation of source files, ie it is not possible to pass # CPP files combined with .O files # Reason is that NVCC uses the file extension to determine whether to compile in CUDA mode or # pass-through CPP mode. if ($HIP_PLATFORM eq "amd") { # Set default optimization level to -O3 for hip-clang. if ($optArg eq "") { $HIPCXXFLAGS .= " -O3"; $HIPCFLAGS .= " -O3"; $HIPLDFLAGS .= " -O3"; } if (!$funcSupp and $optArg ne "-O0" and $hasHIP) { $HIPCXXFLAGS .= " -mllvm -amdgpu-early-inline-all=true -mllvm -amdgpu-function-calls=false"; if ($needLDFLAGS and not $needCXXFLAGS) { $HIPLDFLAGS .= " -mllvm -amdgpu-early-inline-all=true -mllvm -amdgpu-function-calls=false"; } } # If the HIP_PATH env var is defined, pass that path to Clang if ($ENV{'HIP_PATH'}) { my $hip_path_flag = " --hip-path=\"$HIP_PATH\""; $HIPCXXFLAGS .= $hip_path_flag; $HIPLDFLAGS .= $hip_path_flag; } if ($hasHIP) { if (defined $DEVICE_LIB_PATH) { $HIPCXXFLAGS .= " --hip-device-lib-path=\"$DEVICE_LIB_PATH\""; } } if (!$compileOnly) { $HIPLDFLAGS .= " --hip-link"; if ($rdc) { $HIPLDFLAGS .= $HIPLDARCHFLAGS; } if (not $isWindows) { $HIPLDFLAGS .= " --rtlib=compiler-rt -unwindlib=libgcc"; } } } if ($HIPCC_COMPILE_FLAGS_APPEND) { $HIPCXXFLAGS .= " $HIPCC_COMPILE_FLAGS_APPEND"; $HIPCFLAGS .= " $HIPCC_COMPILE_FLAGS_APPEND"; } if ($HIPCC_LINK_FLAGS_APPEND) { $HIPLDFLAGS .= " $HIPCC_LINK_FLAGS_APPEND"; } # TODO: convert CMD to an array rather than a string my $CMD="$HIPCC"; if ($needCFLAGS) { $CMD .= " $HIPCFLAGS"; } if ($needCXXFLAGS) { $CMD .= " $HIPCXXFLAGS"; } if ($needLDFLAGS and not $compileOnly) { $CMD .= " $HIPLDFLAGS"; } $CMD .= " $toolArgs"; if ($verbose & 0x1) { print "hipcc-cmd: ", $CMD, "\n"; } if ($printHipVersion) { if ($runCmd) { print "HIP version: " } print $HIP_VERSION, "\n"; } if ($printCXXFlags) { print $HIPCXXFLAGS; } if ($printLDFlags) { print $HIPLDFLAGS; } if ($runCmd) { system ("$CMD"); if ($? == -1) { print "failed to execute: $!\n"; exit($?); } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; exit($?); } else { $CMD_EXIT_CODE = $? >> 8; } $? or delete_temp_dirs (); exit($CMD_EXIT_CODE); } # vim: ts=4:sw=4:expandtab:smartindent HIPCC-rocm-5.7.1/bin/hipconfig000077500000000000000000000046251446002202200157530ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # Need perl > 5.10 to use logic-defined or use 5.006; use v5.10.1; use warnings; use File::Basename; use File::Spec::Functions 'catfile'; #TODO: By default select perl script until change incorporated in HIP build script my $USE_PERL_SCRIPT = $ENV{'HIP_USE_PERL_SCRIPTS'}; $USE_PERL_SCRIPT //= 1; # use defined-or assignment operator. Use env var, but if not defined default to 1. my $isWindows = ($^O eq 'MSWin32' or $^O eq 'msys'); my $SCRIPT_DIR=dirname(__FILE__); if ($USE_PERL_SCRIPT) { #Invoke hipconfig.pl my $HIPCONFIG_PERL=catfile($SCRIPT_DIR, '/hipconfig.pl'); system($^X, $HIPCONFIG_PERL, @ARGV); } else { $BIN_NAME="/hipconfig.bin"; if ($isWindows) { $BIN_NAME="/hipconfig.bin.exe"; } my $HIPCONFIG_BIN=catfile($SCRIPT_DIR, $BIN_NAME); if ( -e $HIPCONFIG_BIN ) { #Invoke hipconfig.bin system($HIPCONFIG_BIN, @ARGV); } else { print "hipconfig.bin not present; Install HIPCC binaries before proceeding"; exit(-1); } } # Because of this wrapper we need to check # the output of the system command for perl and bin # else the failures are ignored and build fails silently if ($? == -1) { exit($?); } elsif ($? & 127) { exit($?); } else { $CMD_EXIT_CODE = $? >> 8; } exit($CMD_EXIT_CODE); HIPCC-rocm-5.7.1/bin/hipconfig.bat000077500000000000000000000000651446002202200165120ustar00rootroot00000000000000@set HIPCONFIG="%~dp0hipconfig" @perl %HIPCONFIG% %* HIPCC-rocm-5.7.1/bin/hipconfig.pl000077500000000000000000000165631446002202200163710ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # Need perl > 5.10 to use logic-defined or use 5.006; use v5.10.1; use warnings; use Getopt::Long; use Cwd; # Return name of HIP compiler - either 'clang' or 'nvcc' # use Getopt::Long; use File::Basename; my $base_dir; BEGIN { $base_dir = dirname( Cwd::realpath(__FILE__) ); } use lib "$base_dir/"; use hipvars; $isWindows = $hipvars::isWindows; $HIP_RUNTIME = $hipvars::HIP_RUNTIME; $HIP_PLATFORM = $hipvars::HIP_PLATFORM; $HIP_COMPILER = $hipvars::HIP_COMPILER; $HIP_CLANG_PATH = $hipvars::HIP_CLANG_PATH; $CUDA_PATH = $hipvars::CUDA_PATH; $HIP_PATH = $hipvars::HIP_PATH; $ROCM_PATH = $hipvars::ROCM_PATH; $HIP_VERSION = $hipvars::HIP_VERSION; Getopt::Long::Configure ( qw{bundling no_ignore_case}); GetOptions( "help|h" => \$p_help ,"path|p" => \$p_path ,"rocmpath|R" => \$p_rocmpath ,"compiler|c" => \$p_compiler ,"platform|P" => \$p_platform ,"runtime|r" => \$p_runtime ,"hipclangpath|l" => \$p_hipclangpath ,"cpp_config|cxx_config|C" => \$p_cpp_config ,"full|f|info" => \$p_full, ,"version|v" => \$p_version, ,"check" => \$p_check, ,"newline|n" => \$p_newline ); if ($HIP_COMPILER eq "clang") { $HIP_CLANG_INCLUDE = ""; if($isWindows) { $HIP_CLANG_INCLUDE = `\"$HIP_CLANG_PATH/clang++\" --print-resource-dir`; } else { $HIP_CLANG_INCLUDE = `$HIP_CLANG_PATH/clang++ --print-resource-dir`; } $CPP_CONFIG = " -D__HIP_PLATFORM_HCC__= -D__HIP_PLATFORM_AMD__="; $HIP_PATH_INCLUDE = $HIP_PATH."/include"; if($isWindows) { $CPP_CONFIG .= " -I\"$HIP_PATH_INCLUDE\" -I\"$HIP_CLANG_INCLUDE\""; } else { $CPP_CONFIG .= " -I$HIP_PATH_INCLUDE -I$HIP_CLANG_INCLUDE "; } } if ($HIP_PLATFORM eq "nvidia") { $CPP_CONFIG = " -D__HIP_PLATFORM_NVCC__= -D__HIP_PLATFORM_NVIDIA__= -I$HIP_PATH/include -I$CUDA_PATH/include"; }; if ($p_help) { print "usage: hipconfig [OPTIONS]\n"; print " --path, -p : print HIP_PATH (use env var if set, else determine from hipconfig path)\n"; print " --rocmpath, -R : print ROCM_PATH (use env var if set, else determine from hip path or /opt/rocm)\n"; print " --cpp_config, -C : print C++ compiler options\n"; print " --compiler, -c : print compiler (clang or nvcc)\n"; print " --platform, -P : print platform (amd or nvidia)\n"; print " --runtime, -r : print runtime (rocclr or cuda)\n"; print " --hipclangpath, -l : print HIP_CLANG_PATH\n"; print " --full, -f : print full config\n"; print " --version, -v : print hip version\n"; print " --check : check configuration\n"; print " --newline, -n : print newline\n"; print " --help, -h : print help message\n"; exit(); } if ($p_path) { print "$HIP_PATH"; $printed = 1; } if ($p_rocmpath) { print "$ROCM_PATH"; $printed = 1; } if ($p_cpp_config) { print $CPP_CONFIG; $printed = 1; } if ($p_compiler) { print $HIP_COMPILER; $printed = 1; } if ($p_platform) { print $HIP_PLATFORM; $printed = 1; } if ($p_runtime) { print $HIP_RUNTIME; $printed = 1; } if ($p_hipclangpath) { if (defined $HIP_CLANG_PATH) { print $HIP_CLANG_PATH; } $printed = 1; } if ($p_version) { print $HIP_VERSION; $printed = 1; } if (!$printed or $p_full) { print "HIP version : ", $HIP_VERSION, "\n\n"; print "== hipconfig\n"; print "HIP_PATH : ", $HIP_PATH, "\n"; print "ROCM_PATH : ", $ROCM_PATH, "\n"; print "HIP_COMPILER : ", $HIP_COMPILER, "\n"; print "HIP_PLATFORM : ", $HIP_PLATFORM, "\n"; print "HIP_RUNTIME : ", $HIP_RUNTIME, "\n"; print "CPP_CONFIG : ", $CPP_CONFIG, "\n"; if ($HIP_PLATFORM eq "amd") { print "\n" ; if ($HIP_COMPILER eq "clang") { print "== hip-clang\n"; print ("HIP_CLANG_PATH : $HIP_CLANG_PATH\n"); if ($isWindows) { system("\"$HIP_CLANG_PATH/clang++\" --version"); system("\"$HIP_CLANG_PATH/llc\" --version"); printf("hip-clang-cxxflags : "); $win_output = `perl \"$HIP_PATH/bin/hipcc\" --cxxflags`; printf("$win_output \n"); printf("hip-clang-ldflags : "); $win_output = `perl \"$HIP_PATH/bin/hipcc\" --ldflags`; printf("$win_output \n"); } else { system("$HIP_CLANG_PATH/clang++ --version"); system("$HIP_CLANG_PATH/llc --version"); print ("hip-clang-cxxflags : "); system("$HIP_PATH/bin/hipcc --cxxflags"); printf("\n"); print ("hip-clang-ldflags : "); system("$HIP_PATH/bin/hipcc --ldflags"); printf("\n"); } } else { print ("Unexpected HIP_COMPILER: $HIP_COMPILER\n"); } } if ($HIP_PLATFORM eq "nvidia") { print "\n" ; print "== nvcc\n"; print "CUDA_PATH : ", $CUDA_PATH, "\n"; system("$CUDA_PATH/bin/nvcc --version"); } print "\n" ; print "=== Environment Variables\n"; if ($isWindows) { print ("PATH=$ENV{PATH}\n"); system("set | findstr //B //C:\"HIP\" //C:\"CUDA\" //C:\"LD_LIBRARY_PATH\""); } else { system("echo PATH=\$PATH"); system("env | egrep '^HIP|^CUDA|^LD_LIBRARY_PATH'"); } print "\n" ; if ($isWindows) { print "== Windows Display Drivers\n"; print "Hostname : "; system ("hostname"); system ("wmic path win32_VideoController get AdapterCompatibility,InstalledDisplayDrivers,Name | findstr //B //C:\"Advanced Micro Devices\""); } else { print "== Linux Kernel\n"; print "Hostname : "; system ("hostname"); system ("uname -a"); } if (-e "/usr/bin/lsb_release") { system ("/usr/bin/lsb_release -a"); } print "\n" ; $printed = 1; } if ($p_check) { print "\nCheck system installation:\n"; printf ("%-70s", "check hipconfig in PATH..."); # Safer to use which hipconfig instead of invoking hipconfig if (system ("which hipconfig > /dev/null 2>&1") != 0) { print "FAIL\n"; } else { printf "good\n"; } } if ($p_newline) { print "\n"; } HIPCC-rocm-5.7.1/bin/hipvars.pm000066400000000000000000000141001446002202200160560ustar00rootroot00000000000000#!/usr/bin/env perl # Copyright (c) 2020 - 2021 Advanced Micro Devices, Inc. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. package hipvars; use warnings; use Getopt::Long; use Cwd; use File::Basename; $HIP_BASE_VERSION_MAJOR = "5"; $HIP_BASE_VERSION_MINOR = "7"; $HIP_BASE_VERSION_PATCH = "0"; #--- # Function to parse config file sub parse_config_file { my ($file, $config) = @_; if (open (CONFIG, "$file")) { while () { my $config_line=$_; chop ($config_line); $config_line =~ s/^\s*//; $config_line =~ s/\s*$//; if (($config_line !~ /^#/) && ($config_line ne "")) { my ($name, $value) = split (/=/, $config_line); $$config{$name} = $value; } } close(CONFIG); } } #--- # Function to check if executable can be run sub can_run { my ($exe) = @_; `$exe --version 2>&1`; if ($? == 0) { return 1; } else { return 0; } } $isWindows = ($^O eq 'MSWin32' or $^O eq 'msys'); # # TODO: Fix rpath LDFLAGS settings # # Since this hipcc script gets installed at two uneven hierarchical levels, # linked by symlink, the absolute path of this script should be used to # derive HIP_PATH, as dirname $0 could be /opt/rocm/bin or /opt/rocm/hip/bin # depending on how it gets invoked. # ROCM_PATH which points to is determined based on whether # we find bin/rocm_agent_enumerator in the parent of HIP_PATH or not. If it is found, # ROCM_PATH is defined relative to HIP_PATH else it is hardcoded to /opt/rocm. # $HIP_PATH=$ENV{'HIP_PATH'} // dirname(Cwd::abs_path("$0/../")); # use parent directory of hipcc if (-e "$HIP_PATH/bin/rocm_agent_enumerator") { $ROCM_PATH=$ENV{'ROCM_PATH'} // "$HIP_PATH"; # use HIP_PATH }elsif (-e "$HIP_PATH/../bin/rocm_agent_enumerator") { # case for backward compatibility $ROCM_PATH=$ENV{'ROCM_PATH'} // dirname("$HIP_PATH"); # use parent directory of HIP_PATH } else { $ROCM_PATH=$ENV{'ROCM_PATH'} // "/opt/rocm"; } $CUDA_PATH=$ENV{'CUDA_PATH'} // '/usr/local/cuda'; # Windows/Distro's have a different structure, all binaries are with hipcc if (-e "$HIP_PATH/bin/clang" or -e "$HIP_PATH/bin/clang.exe") { $HIP_CLANG_PATH=$ENV{'HIP_CLANG_PATH'} // "$HIP_PATH/bin"; } else { $HIP_CLANG_PATH=$ENV{'HIP_CLANG_PATH'} // "$ROCM_PATH/llvm/bin"; } # HIP_ROCCLR_HOME is used by Windows builds $HIP_ROCCLR_HOME=$ENV{'HIP_ROCCLR_HOME'}; if (defined $HIP_ROCCLR_HOME) { $HIP_INFO_PATH= "$HIP_ROCCLR_HOME/lib/.hipInfo"; } else { $HIP_INFO_PATH= "$HIP_PATH/lib/.hipInfo"; # use actual file } #--- #HIP_PLATFORM controls whether to use nvidia or amd platform: $HIP_PLATFORM=$ENV{'HIP_PLATFORM'}; # Read .hipInfo my %hipInfo = (); parse_config_file("$HIP_INFO_PATH", \%hipInfo); # Prioritize Env first, otherwise use the hipInfo config file $HIP_COMPILER = $ENV{'HIP_COMPILER'} // $hipInfo{'HIP_COMPILER'} // "clang"; $HIP_RUNTIME = $ENV{'HIP_RUNTIME'} // $hipInfo{'HIP_RUNTIME'} // "rocclr"; # If using ROCclr runtime, need to find HIP_ROCCLR_HOME if (defined $HIP_RUNTIME and $HIP_RUNTIME eq "rocclr" and !defined $HIP_ROCCLR_HOME) { my $hipvars_dir = dirname(Cwd::abs_path($0)); if (-e "$hipvars_dir/../lib/bitcode") { $HIP_ROCCLR_HOME = Cwd::abs_path($hipvars_dir . "/.."); #FILE_REORG Backward compatibility } elsif (-e "$hipvars_dir/lib/bitcode") { $HIP_ROCCLR_HOME = Cwd::abs_path($hipvars_dir); } else { $HIP_ROCCLR_HOME = $HIP_PATH; # use HIP_PATH } } if (not defined $HIP_PLATFORM) { if (can_run("$HIP_CLANG_PATH/clang++") or can_run("clang++")) { $HIP_PLATFORM = "amd"; } elsif (can_run("$CUDA_PATH/bin/nvcc") or can_run("nvcc")) { $HIP_PLATFORM = "nvidia"; $HIP_COMPILER = "nvcc"; $HIP_RUNTIME = "cuda"; } else { # Default to amd for now $HIP_PLATFORM = "amd"; } } elsif ($HIP_PLATFORM eq "hcc") { $HIP_PLATFORM = "amd"; warn("Warning: HIP_PLATFORM=hcc is deprecated. Please use HIP_PLATFORM=amd. \n") } elsif ($HIP_PLATFORM eq "nvcc") { $HIP_PLATFORM = "nvidia"; $HIP_COMPILER = "nvcc"; $HIP_RUNTIME = "cuda"; warn("Warning: HIP_PLATFORM=nvcc is deprecated. Please use HIP_PLATFORM=nvidia. \n") } if ($HIP_COMPILER eq "clang") { # Windows does not have clang at linux default path if (defined $HIP_ROCCLR_HOME and (-e "$HIP_ROCCLR_HOME/bin/clang" or -e "$HIP_ROCCLR_HOME/bin/clang.exe")) { $HIP_CLANG_PATH = "$HIP_ROCCLR_HOME/bin"; } } #--- # Read .hipVersion my %hipVersion = (); if ($isWindows) { parse_config_file("$hipvars::HIP_PATH/bin/.hipVersion", \%hipVersion); } else { parse_config_file("$hipvars::HIP_PATH/share/hip/version", \%hipVersion); } $HIP_VERSION_MAJOR = $hipVersion{'HIP_VERSION_MAJOR'} // $HIP_BASE_VERSION_MAJOR; $HIP_VERSION_MINOR = $hipVersion{'HIP_VERSION_MINOR'} // $HIP_BASE_VERSION_MINOR; $HIP_VERSION_PATCH = $hipVersion{'HIP_VERSION_PATCH'} // $HIP_BASE_VERSION_PATCH; $HIP_VERSION_GITHASH = $hipVersion{'HIP_VERSION_GITHASH'} // 0; $HIP_VERSION="$HIP_VERSION_MAJOR.$HIP_VERSION_MINOR.$HIP_VERSION_PATCH-$HIP_VERSION_GITHASH"; HIPCC-rocm-5.7.1/docs/000077500000000000000000000000001446002202200142305ustar00rootroot00000000000000HIPCC-rocm-5.7.1/docs/.sphinx/000077500000000000000000000000001446002202200156175ustar00rootroot00000000000000HIPCC-rocm-5.7.1/docs/.sphinx/_toc.yml.in000066400000000000000000000003451446002202200176750ustar00rootroot00000000000000# Anywhere {branch} is used, the branch name will be substituted. # These comments will also be removed. root: index subtrees: - numbered: False entries: - file: env - file: usage - file: build - file: test HIPCC-rocm-5.7.1/docs/.sphinx/requirements.in000066400000000000000000000000271446002202200206710ustar00rootroot00000000000000rocm-docs-core==0.14.0 HIPCC-rocm-5.7.1/docs/.sphinx/requirements.txt000066400000000000000000000055751446002202200211170ustar00rootroot00000000000000# # This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # pip-compile requirements.in # accessible-pygments==0.0.3 # via pydata-sphinx-theme alabaster==0.7.13 # via sphinx babel==2.12.1 # via # pydata-sphinx-theme # sphinx beautifulsoup4==4.11.2 # via pydata-sphinx-theme breathe==4.34.0 # via rocm-docs-core certifi==2022.12.7 # via requests cffi==1.15.1 # via # cryptography # pynacl charset-normalizer==3.1.0 # via requests click==8.1.3 # via sphinx-external-toc cryptography==40.0.2 # via pyjwt deprecated==1.2.13 # via pygithub docutils==0.19 # via # breathe # myst-parser # pydata-sphinx-theme # sphinx fastjsonschema==2.17.1 # via rocm-docs-core gitdb==4.0.10 # via gitpython gitpython==3.1.31 # via rocm-docs-core idna==3.4 # via requests imagesize==1.4.1 # via sphinx jinja2==3.1.2 # via # myst-parser # sphinx linkify-it-py==1.0.3 # via myst-parser markdown-it-py==2.2.0 # via # mdit-py-plugins # myst-parser markupsafe==2.1.2 # via jinja2 mdit-py-plugins==0.3.5 # via myst-parser mdurl==0.1.2 # via markdown-it-py myst-parser[linkify]==1.0.0 # via rocm-docs-core packaging==23.0 # via # pydata-sphinx-theme # sphinx pycparser==2.21 # via cffi pydata-sphinx-theme==0.13.3 # via # rocm-docs-core # sphinx-book-theme pygithub==1.58.1 # via rocm-docs-core pygments==2.14.0 # via # accessible-pygments # pydata-sphinx-theme # sphinx pyjwt[crypto]==2.6.0 # via pygithub pynacl==1.5.0 # via pygithub pyyaml==6.0 # via # myst-parser # rocm-docs-core # sphinx-external-toc requests==2.28.2 # via # pygithub # sphinx rocm-docs-core==0.14.0 # via -r requirements.in smmap==5.0.0 # via gitdb snowballstemmer==2.2.0 # via sphinx soupsieve==2.4 # via beautifulsoup4 sphinx==5.3.0 # via # breathe # myst-parser # pydata-sphinx-theme # rocm-docs-core # sphinx-book-theme # sphinx-copybutton # sphinx-design # sphinx-external-toc # sphinx-notfound-page sphinx-book-theme==1.0.1 # via rocm-docs-core sphinx-copybutton==0.5.1 # via rocm-docs-core sphinx-design==0.4.1 # via rocm-docs-core sphinx-external-toc==0.3.1 # via rocm-docs-core sphinx-notfound-page==0.8.3 # via rocm-docs-core sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx sphinxcontrib-htmlhelp==2.0.1 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx typing-extensions==4.5.0 # via pydata-sphinx-theme uc-micro-py==1.0.1 # via linkify-it-py urllib3==1.26.15 # via requests wrapt==1.15.0 # via deprecated HIPCC-rocm-5.7.1/docs/build.md000066400000000000000000000004251446002202200156520ustar00rootroot00000000000000# Building ```bash mkdir build cd build cmake .. make -j ``` The hipcc and hipconfig executables are created in the current build folder. These executables need to be copied to /opt/rocm/hip/bin folder location. Packaging and installing will be handled in future releases. HIPCC-rocm-5.7.1/docs/conf.py000066400000000000000000000006531446002202200155330ustar00rootroot00000000000000# Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html from rocm_docs import ROCmDocs docs_core = ROCmDocs("HIPCC Documentation") docs_core.setup() for sphinx_var in ROCmDocs.SPHINX_VARS: globals()[sphinx_var] = getattr(docs_core, sphinx_var) HIPCC-rocm-5.7.1/docs/env.md000066400000000000000000000012351446002202200153430ustar00rootroot00000000000000# Environment Variables The environment variable HIP_PLATFORM may be used to specify amd/nvidia: - HIP_PLATFORM='amd' or HIP_PLATFORM='nvidia'. - If HIP_PLATFORM is not set, then hipcc will attempt to auto-detect based on if nvcc is found. Other environment variable controls: - HIP_PATH : Path to HIP directory, default is one dir level above location of hipcc. - CUDA_PATH : Path to CUDA SDK (default /usr/local/cuda). Used on NVIDIA platforms only. - HIP_ROCCLR_HOME : Path to HIP/ROCclr directory. Used on AMD platforms only. - HIP_CLANG_PATH : Path to HIP-Clang (default to ../../llvm/bin relative to hipcc's abs_path). Used on AMD platforms only. HIPCC-rocm-5.7.1/docs/index.md000066400000000000000000000007431446002202200156650ustar00rootroot00000000000000# HIPCC `hipcc` is a compiler driver utility that will call clang or nvcc, depending on target, and pass the appropriate include and library options for the target compiler and HIP infrastructure. There is both a Perl version, and a C++ executable version of the hipcc/hipconfig compiler driver utilities provided. Currently, by default the Perl version is used when 'hipcc' is called. To enable the C++ executable versions, set the environment variable `HIP_USE_PERL_SCRIPTS=0`. HIPCC-rocm-5.7.1/docs/test.md000066400000000000000000000002411446002202200155260ustar00rootroot00000000000000# Testing Currently hipcc/hipconfig executables are tested by building and executing HIP tests. Separate tests for hipcc/hipconfig is currently not planned. HIPCC-rocm-5.7.1/docs/usage.md000066400000000000000000000004351446002202200156600ustar00rootroot00000000000000# Usage The built executables can be used the same way as the hipcc/hipconfig perl scripts. To use the newly built executables from the build folder use ./ in front of the executable name - Example: ```shell ./hipconfig --help ./hipcc --help ./hipcc --version ./hipconfig --full ``` HIPCC-rocm-5.7.1/hipcc-backward-compat.cmake000066400000000000000000000043101446002202200204230ustar00rootroot00000000000000# Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved. # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. cmake_minimum_required(VERSION 3.16.8) set(HIPCC_WRAPPER_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}/wrapper_dir/bin) set(HIPCC_SRC_BIN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin) #function to create symlink to binaries function(create_binary_symlink) file(MAKE_DIRECTORY ${HIPCC_WRAPPER_BIN_DIR}) #get all binaries file(GLOB binary_files ${HIPCC_SRC_BIN_DIR}/*) foreach(binary_file ${binary_files}) get_filename_component(file_name ${binary_file} NAME) add_custom_target(link_${file_name} ALL WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_COMMAND} -E create_symlink ../../${CMAKE_INSTALL_BINDIR}/${file_name} ${HIPCC_WRAPPER_BIN_DIR}/${file_name}) endforeach() endfunction() # Create symlink to binaries create_binary_symlink() # TODO: Following has to modified if component based installation is required if (NOT WIN32) install(DIRECTORY ${HIPCC_WRAPPER_BIN_DIR} DESTINATION hip) else() install(DIRECTORY ${HIPCC_WRAPPER_BIN_DIR} DESTINATION hip FILES_MATCHING PATTERN "*" PATTERN "*.bat" EXCLUDE ) endif() HIPCC-rocm-5.7.1/src/000077500000000000000000000000001446002202200140675ustar00rootroot00000000000000HIPCC-rocm-5.7.1/src/hipBin.cpp000066400000000000000000000141671446002202200160150ustar00rootroot00000000000000/* Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "hipBin_util.h" #include "hipBin_amd.h" #include "hipBin_nvidia.h" #include #include #include class HipBinUtil; class HipBinBase; class HipBinAmd; class HipBinNvidia; class HipBin; class HipBin { private: HipBinUtil* hipBinUtilPtr_; vector hipBinBasePtrs_; vector platformVec_; HipBinBase* hipBinNVPtr_; HipBinBase* hipBinAMDPtr_; public: HipBin(); ~HipBin(); vector& getHipBinPtrs(); vector& getPlaformInfo(); void executeHipBin(string filename, int argc, char* argv[]); void executeHipConfig(int argc, char* argv[]); void executeHipCC(int argc, char* argv[]); }; // Implementation ================================================ //=========================================================================== HipBin::HipBin() { hipBinUtilPtr_ = hipBinUtilPtr_->getInstance(); hipBinNVPtr_ = new HipBinNvidia(); hipBinAMDPtr_ = new HipBinAmd(); bool platformDetected = false; if (hipBinAMDPtr_->detectPlatform()) { // populates the struct with AMD info const PlatformInfo& platformInfo = hipBinAMDPtr_->getPlatformInfo(); platformVec_.push_back(platformInfo); hipBinBasePtrs_.push_back(hipBinAMDPtr_); platformDetected = true; } else if (hipBinNVPtr_->detectPlatform()) { // populates the struct with Nvidia info const PlatformInfo& platformInfo = hipBinNVPtr_->getPlatformInfo(); platformVec_.push_back(platformInfo); hipBinBasePtrs_.push_back(hipBinNVPtr_); platformDetected = true; } // if no device is detected, then it is defaulted to AMD if (!platformDetected) { std::cerr << "Device not supported - Defaulting to AMD" << endl; // populates the struct with AMD info const PlatformInfo& platformInfo = hipBinAMDPtr_->getPlatformInfo(); platformVec_.push_back(platformInfo); hipBinBasePtrs_.push_back(hipBinAMDPtr_); } } HipBin::~HipBin() { delete hipBinNVPtr_; delete hipBinAMDPtr_; // clearing the vector so no one accesses the pointers hipBinBasePtrs_.clear(); // clearing the platform vector as the pointers are deleted platformVec_.clear(); delete hipBinUtilPtr_; } vector& HipBin::getPlaformInfo() { return platformVec_; // Return the populated platform info. } vector& HipBin::getHipBinPtrs() { return hipBinBasePtrs_; // Return the populated device pointers. } void HipBin::executeHipBin(string filename, int argc, char* argv[]) { if (hipBinUtilPtr_->substringPresent(filename, "hipconfig")) { executeHipConfig(argc, argv); } else if (hipBinUtilPtr_->substringPresent(filename, "hipcc")) { executeHipCC(argc, argv); } else { std::cerr << "Command " << filename << " not supported. Name the exe as hipconfig" << " or hipcc and then try again ..." << endl; exit(-1); } } void HipBin::executeHipCC(int argc, char* argv[]) { vector& platformPtrs = getHipBinPtrs(); vector argvcc; for (int i = 0; i < argc; i++) { argvcc.push_back(argv[i]); } // 0th index points to the first platform detected. // In the near future this vector will contain mulitple devices platformPtrs.at(0)->executeHipCCCmd(argvcc); } void HipBin::executeHipConfig(int argc, char* argv[]) { vector& platformPtrs = getHipBinPtrs(); for (unsigned int j = 0; j < platformPtrs.size(); j++) { if (argc == 1) { platformPtrs.at(j)->printFull(); } for (int i = 1; i < argc; ++i) { HipBinCommand cmd; cmd = platformPtrs.at(j)->gethipconfigCmd(argv[i]); switch (cmd) { case help: platformPtrs.at(j)->printUsage(); break; case path: cout << platformPtrs.at(j)->getHipPath(); break; case roccmpath: cout << platformPtrs.at(j)->getRoccmPath(); break; case cpp_config: cout << platformPtrs.at(j)->getCppConfig(); break; case compiler: cout << CompilerTypeStr(( platformPtrs.at(j)->getPlatformInfo()).compiler); break; case platform: cout << PlatformTypeStr(( platformPtrs.at(j)->getPlatformInfo()).platform); break; case runtime: cout << RuntimeTypeStr(( platformPtrs.at(j)->getPlatformInfo()).runtime); break; case hipclangpath: cout << platformPtrs.at(j)->getCompilerPath(); break; case full: platformPtrs.at(j)->printFull(); break; case version: cout << platformPtrs.at(j)->getHipVersion(); break; case check: platformPtrs.at(j)->checkHipconfig(); break; case newline: platformPtrs.at(j)->printFull(); cout << endl; break; default: platformPtrs.at(j)->printUsage(); break; } } } } //=========================================================================== //=========================================================================== int main(int argc, char* argv[]) { fs::path filename(argv[0]); filename = filename.filename(); HipBin hipBin; hipBin.executeHipBin(filename.string(), argc, argv); } HIPCC-rocm-5.7.1/src/hipBin_amd.h000066400000000000000000000720771446002202200163070ustar00rootroot00000000000000/* Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef SRC_HIPBIN_AMD_H_ #define SRC_HIPBIN_AMD_H_ #include "hipBin_base.h" #include "hipBin_util.h" #include #include #include #include #include // Use (void) to silent unused warnings. #define assertm(exp, msg) assert(((void)msg, exp)) // Known Features std::unordered_set knownFeatures = { "sramecc-" , "sramecc+", "xnack-", "xnack+" }; class HipBinAmd : public HipBinBase { private: HipBinUtil* hipBinUtilPtr_; string hipClangPath_ = ""; string roccmPathEnv_, hipRocclrPathEnv_, hsaPathEnv_; PlatformInfo platformInfoAMD_; string hipCFlags_, hipCXXFlags_, hipLdFlags_; void constructRocclrHomePath(); void constructHsaPath(); public: HipBinAmd(); virtual ~HipBinAmd() = default; virtual bool detectPlatform(); virtual void constructCompilerPath(); virtual const string& getCompilerPath() const; virtual const PlatformInfo& getPlatformInfo() const; virtual string getCppConfig(); virtual void printFull(); virtual void printCompilerInfo() const; virtual string getCompilerVersion(); virtual void checkHipconfig(); virtual string getDeviceLibPath() const; virtual string getHipLibPath() const; virtual string getHipCC() const; virtual string getHipInclude() const; virtual void initializeHipCXXFlags(); virtual void initializeHipCFlags(); virtual void initializeHipLdFlags(); virtual const string& getHipCXXFlags() const; virtual const string& getHipCFlags() const; virtual const string& getHipLdFlags() const; virtual void executeHipCCCmd(vector argv); // non virtual functions const string& getHsaPath() const; const string& getRocclrHomePath() const; }; HipBinAmd::HipBinAmd() { PlatformInfo platformInfo; platformInfo.os = getOSInfo(); platformInfo.platform = amd; platformInfo.runtime = rocclr; platformInfo.compiler = clang; platformInfoAMD_ = platformInfo; } // returns the Rocclr Home path void HipBinAmd::constructRocclrHomePath() { fs::path full_path(fs::current_path()); fs::path hipvars_dir = full_path; fs::path bitcode = hipvars_dir; string rocclrHomePath = getEnvVariables().hipRocclrPathEnv_; if (rocclrHomePath.empty()) { bitcode /= "../lib/bitcode"; if (!fs::exists(bitcode)) { rocclrHomePath = getHipPath(); } else { hipvars_dir /= ".."; rocclrHomePath = hipvars_dir.string(); } } hipRocclrPathEnv_ = rocclrHomePath; } // construct hsa Path void HipBinAmd::constructHsaPath() { fs::path hsaPathfs; string hsaPath = getEnvVariables().hsaPathEnv_; if (hsaPath.empty()) { hsaPath = getRoccmPath(); hsaPathfs = hsaPath; hsaPathfs /= "hsa"; hsaPath = hsaPathfs.string(); hsaPathEnv_ = hsaPath; } else { hsaPathEnv_ = hsaPath; } } // returns the Rocclr Home path const string& HipBinAmd::getRocclrHomePath() const { return hipRocclrPathEnv_; } // returns hsa Path const string& HipBinAmd::getHsaPath() const { // return variables_.hsaPathEnv_; return hsaPathEnv_; } const string& HipBinAmd::getHipCFlags() const { return hipCFlags_; } const string& HipBinAmd::getHipLdFlags() const { return hipLdFlags_; } void HipBinAmd::initializeHipLdFlags() { string hipLdFlags; const string& hipClangPath = getCompilerPath(); // If $HIPCC clang++ is not compiled, use clang instead string hipCC = "\"" + hipClangPath + "/clang++"; if (!fs::exists(hipCC)) { hipLdFlags = "--driver-mode=g++"; } hipLdFlags_ = hipLdFlags; } void HipBinAmd::initializeHipCFlags() { string hipCFlags; const OsType& os = getOSInfo(); if (os != windows) { string hsaPath; hsaPath = getHsaPath(); hipCFlags += " -isystem " + hsaPath + "/include"; } string hipIncludePath; hipIncludePath = getHipInclude(); hipCFlags += " -isystem \"" + hipIncludePath + "\""; hipCFlags_ = hipCFlags; } const string& HipBinAmd::getHipCXXFlags() const { return hipCXXFlags_; } string HipBinAmd::getHipInclude() const { const string& rocclrHomePath = getRocclrHomePath(); fs::path hipIncludefs = rocclrHomePath; hipIncludefs /= "include"; if (hipIncludefs.string().empty()) { const string& hipPath = getHipPath(); hipIncludefs = hipPath; hipIncludefs /= "include"; } string hipInclude = hipIncludefs.string(); return hipInclude; } void HipBinAmd::initializeHipCXXFlags() { string hipCXXFlags; const OsType& os = getOSInfo(); const EnvVariables& var = getEnvVariables(); // Allow __fp16 as function parameter and return type. if (var.hipClangHccCompactModeEnv_.compare("1") == 0) { hipCXXFlags += " -Xclang -fallow-half-arguments-and-returns -D__HIP_HCC_COMPAT_MODE__=1"; } if (os != windows) { const string& hsaPath = getHsaPath(); hipCXXFlags += " -isystem " + hsaPath + "/include"; } // Add paths to common HIP includes: string hipIncludePath; hipIncludePath = getHipInclude(); hipCXXFlags += " -isystem \"" + hipIncludePath + "\""; hipCXXFlags_ = hipCXXFlags; } // populates clang path. void HipBinAmd::constructCompilerPath() { string complierPath; const EnvVariables& envVariables = getEnvVariables(); if (envVariables.hipClangPathEnv_.empty()) { fs::path hipClangPath; const OsType& osInfo = getOSInfo(); if (osInfo == windows) { complierPath = getHipPath(); hipClangPath = complierPath; } else { complierPath = getRoccmPath(); hipClangPath = complierPath; } if (fs::exists("llvm/bin/clang++")) { hipClangPath /= "llvm/bin"; } else { hipClangPath /= "bin"; } complierPath = hipClangPath.string(); } else { complierPath = envVariables.hipClangPathEnv_; } hipClangPath_ = complierPath; } // returns clang path. const string& HipBinAmd::getCompilerPath() const { return hipClangPath_; } void HipBinAmd::printCompilerInfo() const { const OsType& os = getOSInfo(); const string& hipClangPath = getCompilerPath(); const string& hipPath = getHipPath(); if (os == windows) { string cmd = hipClangPath + "/clang++ --version"; system(cmd.c_str()); // hipclang version cout << "llc-version :" << endl; cmd = hipClangPath + "/llc --version"; system(cmd.c_str()); // llc version cout << "hip-clang-cxxflags :" << endl; cmd = hipPath + "/bin/hipcc --cxxflags"; system(cmd.c_str()); // cxx flags cout << endl << "hip-clang-ldflags :" << endl; cmd = hipPath + "/bin/hipcc --ldflags"; system(cmd.c_str()); // ld flags cout << endl; } else { string cmd = hipClangPath + "/clang++ --version"; system(cmd.c_str()); // hipclang version cmd = hipClangPath + "/llc --version"; system(cmd.c_str()); // llc version cout << "hip-clang-cxxflags :" << endl; cmd = hipPath + "/bin/hipcc --cxxflags"; system(cmd.c_str()); // cxx flags cout << endl << "hip-clang-ldflags :" << endl; cmd = hipPath + "/bin/hipcc --ldflags"; system(cmd.c_str()); // ldflags version cout << endl; } } string HipBinAmd::getCompilerVersion() { string out, complierVersion; const string& hipClangPath = getCompilerPath(); fs::path cmdAmd = hipClangPath; cmdAmd /= "clang++"; if (canRunCompiler(cmdAmd.string(), out) || canRunCompiler("clang++", out)) { regex regexp("([0-9.]+)"); smatch m; if (regex_search(out, m, regexp)) { if (m.size() > 1) { // get the index =1 match, 0=whole match we ignore std::ssub_match sub_match = m[1]; complierVersion = sub_match.str(); } } } else { std::cerr << "Hip Clang Compiler not found" << endl; } return complierVersion; } const PlatformInfo& HipBinAmd::getPlatformInfo() const { return platformInfoAMD_; } string HipBinAmd::getCppConfig() { string cppConfig = " -D__HIP_PLATFORM_HCC__= -D__HIP_PLATFORM_AMD__="; string compilerVersion; compilerVersion = getCompilerVersion(); fs::path hipPathInclude, cppConfigFs; const string& hipPath = getHipPath(); hipPathInclude = hipPath; hipPathInclude /= "include"; const OsType& osInfo = getOSInfo(); if (osInfo == windows) { cppConfig += " -I" + hipPathInclude.string(); cppConfigFs = cppConfig; cppConfigFs /= "/"; } else { const string& hsaPath = getHsaPath(); cppConfig += " -I" + hipPathInclude.string() + " -I" + hsaPath; cppConfigFs = cppConfig; cppConfigFs /= "include"; cppConfig = cppConfigFs.string(); } return cppConfig; } string HipBinAmd::getDeviceLibPath() const { const EnvVariables& var = getEnvVariables(); string deviceLibPath = var.deviceLibPathEnv_; return deviceLibPath; } bool HipBinAmd::detectPlatform() { string out; const string& hipClangPath = getCompilerPath(); fs::path cmdAmd = hipClangPath; cmdAmd /= "clang++"; const EnvVariables& var = getEnvVariables(); bool detected = false; if (var.hipPlatformEnv_.empty()) { if (canRunCompiler(cmdAmd.string(), out) || (canRunCompiler("clang++", out))) { detected = true; } } else { if (var.hipPlatformEnv_ == "amd" || var.hipPlatformEnv_ == "hcc") { detected = true; if (var.hipPlatformEnv_ == "hcc") std::cerr << "Warning: HIP_PLATFORM=hcc is deprecated."<< "Please use HIP_PLATFORM=amd." << endl; } } return detected; } string HipBinAmd::getHipLibPath() const { string hipLibPath; const EnvVariables& env = getEnvVariables(); if (!env.hipLibPathEnv_.empty()) { hipLibPath = env.hipLibPathEnv_; } else if (!env.hipPathEnv_.empty()) { fs::path p = env.hipLibPathEnv_; p /= "lib"; hipLibPath = p.string(); } return hipLibPath; } string HipBinAmd::getHipCC() const { string hipCC; const string& hipClangPath = getCompilerPath(); fs::path compiler = hipClangPath; compiler /= "clang++"; if (!fs::exists(compiler)) { fs::path compiler = hipClangPath; compiler /= "clang"; } hipCC = compiler.string(); return hipCC; } void HipBinAmd::checkHipconfig() { printFull(); cout << endl << "Check system installation: " << endl; cout << "check hipconfig in PATH..." << endl; if (system("which hipconfig > /dev/null 2>&1") != 0) { std::cerr << "FAIL " << endl; } else { cout << "good" << endl; } string ldLibraryPath; const EnvVariables& env = getEnvVariables(); ldLibraryPath = env.ldLibraryPathEnv_; const string& hsaPath = getHsaPath(); cout << "check LD_LIBRARY_PATH (" << ldLibraryPath << ") contains HSA_PATH (" << hsaPath << ")..." << endl; if (ldLibraryPath.find(hsaPath) == string::npos) { std::cerr << "FAIL" << endl; } else { cout << "good" << endl; } } void HipBinAmd::printFull() { const string& hipVersion = getHipVersion(); const string& hipPath = getHipPath(); const string& roccmPath = getRoccmPath(); const PlatformInfo& platformInfo = getPlatformInfo(); const string& ccpConfig = getCppConfig(); const string& hsaPath = getHsaPath(); const string& hipClangPath = getCompilerPath(); cout << "HIP version: " << hipVersion << endl; cout << endl << "==hipconfig" << endl; cout << "HIP_PATH :" << hipPath << endl; cout << "ROCM_PATH :" << roccmPath << endl; cout << "HIP_COMPILER :" << CompilerTypeStr( platformInfo.compiler) << endl; cout << "HIP_PLATFORM :" << PlatformTypeStr( platformInfo.platform) << endl; cout << "HIP_RUNTIME :" << RuntimeTypeStr( platformInfo.runtime) << endl; cout << "CPP_CONFIG :" << ccpConfig << endl; cout << endl << "==hip-clang" << endl; cout << "HSA_PATH :" << hsaPath << endl; cout << "HIP_CLANG_PATH :" << hipClangPath << endl; printCompilerInfo(); cout << endl << "== Envirnoment Variables" << endl; printEnvironmentVariables(); getSystemInfo(); if (fs::exists("/usr/bin/lsb_release")) system("/usr/bin/lsb_release -a"); cout << endl; } void HipBinAmd::executeHipCCCmd(vector argv) { if (argv.size() < 2) { cout<< "No Arguments passed, exiting ...\n"; exit(EXIT_SUCCESS); } const EnvVariables& var = getEnvVariables(); int verbose = 0; if (!var.verboseEnv_.empty()) verbose = stoi(var.verboseEnv_); // Verbose: 0x1=commands, 0x2=paths, 0x4=hipcc args // set if user explicitly requests -stdlib=libc++ // (else we default to libstdc++ for better interop with g++) bool setStdLib = 0; bool default_amdgpu_target = 1; bool compileOnly = 0; bool needCXXFLAGS = 0; // need to add CXX flags to compile step bool needCFLAGS = 0; // need to add C flags to compile step bool needLDFLAGS = 1; // need to add LDFLAGS to compile step. bool fileTypeFlag = 0; // to see if -x flag is mentioned bool hasOMPTargets = 0; // If OMP targets is mentioned bool hasC = 0; // options contain a c-style file // options contain a cpp-style file (NVCC must force recognition as GPU file) bool hasCXX = 0; // options contain a hip-style file (HIP-Clang must pass offloading options) bool hasHIP = 0; bool printHipVersion = 0; // print HIP version bool printCXXFlags = 0; // print HIPCXXFLAGS bool printLDFlags = 0; // print HIPLDFLAGS bool runCmd = 1; bool buildDeps = 0; string hsacoVersion; bool funcSupp = 0; // enable function support bool rdc = 0; // whether -fgpu-rdc is on string prevArg; // previous argument // TODO(hipcc): convert toolArgs to an array rather than a string string toolArgs; // arguments to pass to the clang or nvcc tool string optArg; // -O args vector options, inputs; // TODO(hipcc): hipcc uses --amdgpu-target for historical reasons. // It should be replaced // by clang option --offload-arch. vector targetOpts = {"--offload-arch=", "--amdgpu-target="}; string targetsStr; // file followed by -o should not contibute in picking compiler flags bool skipOutputFile = false; const OsType& os = getOSInfo(); string hip_compile_cxx_as_hip; if (var.hipCompileCxxAsHipEnv_.empty()) { hip_compile_cxx_as_hip = "1"; } else { hip_compile_cxx_as_hip = var.hipCompileCxxAsHipEnv_; } string HIPLDARCHFLAGS; string HIPCXXFLAGS, HIPCFLAGS, HIPLDFLAGS; // ARGV Processing Loop // TODO(hipcc): create a proper Options Processing function/routine for (unsigned int argcount = 1; argcount < argv.size(); argcount++) { // Save $arg, it can get changed in the loop. string arg = argv.at(argcount); // TODO(hipcc): figure out why this space removal is wanted. // TODO(hipcc): If someone has gone to the effort of // quoting the spaces to the shell // TODO(hipcc): why are we removing it here? regex toRemove("\\s+"); // Remove whitespace string trimarg = hipBinUtilPtr_->replaceRegex(arg, toRemove, ""); bool swallowArg = false; bool escapeArg = true; if (arg == "-c" || arg == "--genco" || arg == "-E") { compileOnly = true; needLDFLAGS = false; } if (skipOutputFile) { // TODO(hipcc): handle filename with shell metacharacters toolArgs += " \"" + arg +"\""; prevArg = arg; skipOutputFile = 0; continue; } if (arg == "-o") { needLDFLAGS = 1; skipOutputFile = 1; } if ((trimarg == "-stdlib=libc++") && (setStdLib == 0)) { HIPCXXFLAGS += " -stdlib=libc++"; setStdLib = 1; } // Process --rocm-path option const string& rocmPathOption = "--rocm-path="; if (arg.compare(0,rocmPathOption.length(),rocmPathOption) == 0) rocm_pathOption_ = arg.substr(rocmPathOption.length()); // Check target selection option: --offload-arch= and --amdgpu-target=... for (unsigned int i = 0; i stringRegexMatch(arg, pattern)) { if (targetOpt == "--amdgpu-target=") { std::cerr << "Warning: The --amdgpu-target option has been deprecated and will be removed in the future." << " Use --offload-arch instead.\n"; } // If targets string is not empty, // add a comma before adding new target option value. targetsStr.size() >0 ? targetsStr += ",": targetsStr += ""; targetsStr += arg.substr(targetOpt.size()); // argument of targetOpts default_amdgpu_target = 0; // Collect the GPU arch options and pass them to clang later. swallowArg = 1; } } // end of for targetOpts for loop if (hipBinUtilPtr_->substringPresent(arg, "--genco")) { arg = "--cuda-device-only"; } if (trimarg == "--version") { printHipVersion = 1; } if (trimarg == "--short-version") { printHipVersion = 1; runCmd = 0; } if (trimarg == "--cxxflags") { printCXXFlags = 1; runCmd = 0; } if (trimarg == "--ldflags") { printLDFlags = 1; runCmd = 0; } if (trimarg == "-M") { compileOnly = 1; buildDeps = 1; } if ((trimarg == "-use-staticlib")) { std::cerr << "Warning: The -use-staticlib option has been deprecated and is no longer needed.\n"; swallowArg = true; } if ((trimarg == "-use-sharedlib")) { std::cerr << "Warning: The -use-sharedlib option has been deprecated and is no longer needed.\n"; swallowArg = true; } if (hipBinUtilPtr_->stringRegexMatch(arg, "^-O.*")) { optArg = arg; } if (hipBinUtilPtr_->substringPresent( arg, "--amdhsa-code-object-version=")) { std::cerr << "Warning: The --amdhsa-code-object-version option has been deprecated and will be removed in the future." << " Use -mllvm -mcode-object-version instead.\n"; arg = hipBinUtilPtr_->replaceStr( arg, "--amdhsa-code-object-version=", ""); hsacoVersion = arg; swallowArg = 1; } if (arg == "-x") { fileTypeFlag = 1; } else if ((arg == "c" && prevArg == "-x") || (arg == "-xc")) { fileTypeFlag = 1; hasC = 1; hasCXX = 0; hasHIP = 0; } else if ((arg == "c++" && prevArg == "-x") || (arg == "-xc++")) { fileTypeFlag = 1; hasC = 0; hasCXX = 1; hasHIP = 0; } else if ((arg == "hip" && prevArg == "-x") || (arg == "-xhip")) { fileTypeFlag = 1; hasC = 0; hasCXX = 0; hasHIP = 1; } else if (hipBinUtilPtr_->substringPresent(arg, "-fopenmp-targets=")) { hasOMPTargets = 1; // options start with - } else if (hipBinUtilPtr_->stringRegexMatch(arg, "^-.*")) { if (arg == "-fgpu-rdc") { rdc = 1; } else if (arg == "-fno-gpu-rdc") { rdc = 0; } //# Process HIPCC options here: if (hipBinUtilPtr_->stringRegexMatch(arg, "^--hipcc.*")) { swallowArg = 1; if (arg == "--hipcc-func-supp") { std::cerr << "Warning: The --hipcc-func-supp option has been deprecated and will be removed in the future.\n"; funcSupp = 1; } else if (arg == "--hipcc-no-func-supp") { std::cerr << "Warning: The --hipcc-no-func-supp option has been deprecated and will be removed in the future.\n"; funcSupp = 0; } } else { options.push_back(arg); } // print "O: <$arg>\n"; } else if (prevArg != "-o") { // input files and libraries // Skip guessing if `-x {c|c++|hip}` is already specified. // Add proper file extension before each file type // File Extension -> Flag // .c -> -x c // .cpp/.cxx/.cc/.cu/.cuh/.hip -> -x hip if (fileTypeFlag == 0) { if (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.c$")) { hasC = 1; needCFLAGS = 1; toolArgs += " -x c"; } else if ((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cpp$")) || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cxx$")) || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cc$")) || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.C$"))) { needCXXFLAGS = 1; if (hip_compile_cxx_as_hip == "0" || hasOMPTargets == 1) { hasCXX = 1; } else { hasHIP = 1; toolArgs += " -x hip"; } } else if (((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cu$") || hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cuh$")) && hip_compile_cxx_as_hip != "0") || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.hip$"))) { needCXXFLAGS = 1; hasHIP = 1; toolArgs += " -x hip"; } } if (hasC) { needCFLAGS = 1; } else if (hasCXX || hasHIP) { needCXXFLAGS = 1; } inputs.push_back(arg); // print "I: <$arg>\n"; } // Produce a version of $arg where characters significant to the shell are // quoted. One could quote everything of course but don't bother for // common characters such as alphanumerics. // Do the quoting here because sometimes the $arg is changed in the loop // Important to have all of '-Xlinker' in the set of unquoted characters. // Windows needs different quoting, ignore for now if (os != windows && escapeArg) { regex reg("[^-a-zA-Z0-9_=+,.\\/]"); arg = regex_replace(arg, reg, "\\$&"); } if (!swallowArg) toolArgs += " " + arg; prevArg = arg; } // end of ARGV Processing Loop // now construct Paths ... constructRoccmPath(); // constructs Roccm Path constructHipPath(); // constructs HIP Path readHipVersion(); // stores the hip version constructCompilerPath(); constructRocclrHomePath(); constructHsaPath(); initializeHipCXXFlags(); initializeHipCFlags(); initializeHipLdFlags(); HIPCFLAGS = getHipCFlags(); HIPCXXFLAGS = getHipCXXFlags(); HIPLDFLAGS = getHipLdFlags(); string hipLibPath; string hipIncludePath, deviceLibPath; hipLibPath = getHipLibPath(); const string& roccmPath = getRoccmPath(); const string& hipPath = getHipPath(); const PlatformInfo& platformInfo = getPlatformInfo(); const string& rocclrHomePath = getRocclrHomePath(); const string& hipClangPath = getCompilerPath(); hipIncludePath = getHipInclude(); deviceLibPath = getDeviceLibPath(); const string& hipVersion = getHipVersion(); if (verbose & 0x2) { cout << "HIP_PATH=" << hipPath << endl; cout << "HIP_PLATFORM=" << PlatformTypeStr(platformInfo.platform) <exec(targetsStr.c_str()); regex toReplace("\n+"); targetsStr = hipBinUtilPtr_->replaceRegex(sysOut.out, toReplace, ","); } default_amdgpu_target = 0; } // Parse the targets collected in targetStr // and set corresponding compiler options. vector targets = hipBinUtilPtr_->splitStr(targetsStr, ','); string GPU_ARCH_OPT = " --offload-arch="; for (auto &val : targets) { // Ignore 'gfx000' target reported by rocm_agent_enumerator. if (val != "gfx000") { vector procAndFeatures = hipBinUtilPtr_->splitStr(val, ':'); size_t len = procAndFeatures.size(); // proc and features assertm(procAndFeatures.size() >= 1, "Pass the correct device/feature"); for (size_t i = 1; i < len; i++) { // fixme: currently it checks only for validity of the feature string. // does not check if the device supports the feature or not // e.g. vega10 does not support sramecc if (knownFeatures.find(procAndFeatures.at(i)) == knownFeatures.end()) { std::cerr << "Warning: The Feature: "<< procAndFeatures.at(i) << " is unknown. Correct compilation is not guaranteed.\n"; } } string GPU_ARCH_ARG; GPU_ARCH_ARG = GPU_ARCH_OPT + val; HIPLDARCHFLAGS += GPU_ARCH_ARG; if (hasHIP) { HIPCXXFLAGS += GPU_ARCH_ARG; } } // end of val != "gfx000" } // end of targets for loop string HCC_EXTRA_LIBRARIES; if (hsacoVersion.size() > 0) { if (compileOnly == 0) { HIPLDFLAGS += " -mcode-object-version=" + hsacoVersion; } else { HIPCXXFLAGS += " -mcode-object-version=" + hsacoVersion; } } // rocm_agent_enumerator failed! Throw an error and die if linking is required if (default_amdgpu_target == 1 && compileOnly == 0) { // TODO(agunashe) exit from function std::cerr << "No valid AMD GPU target was either specified or found." << "Please specify a valid target using --offload-arch=.\n"; } HCC_EXTRA_LIBRARIES ="\n"; // TODO(agunashe) write to env if (buildDeps) { HIPCXXFLAGS += " --cuda-host-only"; } // hipcc currrently requires separate compilation of source files, // ie it is not possible to pass // CPP files combined with .O files // Reason is that NVCC uses the file extension to determine // whether to compile in CUDA mode or // pass-through CPP mode. // Set default optimization level to -O3 for hip-clang. if (optArg.empty()) { HIPCXXFLAGS += " -O3"; HIPCFLAGS += " -O3"; HIPLDFLAGS += " -O3"; } if (!funcSupp && optArg != "-O0" && hasHIP) { HIPCXXFLAGS += " -mllvm -amdgpu-early-inline-all=true -mllvm -amdgpu-function-calls=false"; if (needLDFLAGS && !needCXXFLAGS) { HIPLDFLAGS += " -mllvm -amdgpu-early-inline-all=true" " -mllvm -amdgpu-function-calls=false"; } } if (hasHIP) { if (!deviceLibPath.empty()) { string hip_device_lib_str = " --hip-device-lib-path=\"" + deviceLibPath + "\""; HIPCXXFLAGS += hip_device_lib_str; } } if (!compileOnly) { string hip_path = getHipLibPath(); if (!hip_path.empty()) { HIPLDFLAGS += " -L" + hip_path; } HIPLDFLAGS += " --hip-link"; if (rdc) { HIPLDFLAGS += HIPLDARCHFLAGS; } if (!windows) { HIPLDFLAGS += " --rtlib=compiler-rt -unwindlib=libgcc"; } } if (!var.hipccCompileFlagsAppendEnv_.empty()) { HIPCXXFLAGS += " " + var.hipccCompileFlagsAppendEnv_ + " "; HIPCFLAGS += " " + var.hipccCompileFlagsAppendEnv_ + " "; } if (!var.hipccLinkFlagsAppendEnv_.empty()) { HIPLDFLAGS += " " + var.hipccLinkFlagsAppendEnv_ + " "; } // TODO(hipcc): convert CMD to an array rather than a string string compiler; compiler = getHipCC(); string CMD = compiler; if (needCFLAGS) { CMD += " " + HIPCFLAGS; } if (needCXXFLAGS) { CMD += " " + HIPCXXFLAGS; } if (needLDFLAGS && !compileOnly) { CMD += " " + HIPLDFLAGS; } CMD += " " + toolArgs; if (verbose & 0x1) { cout << "hipcc-cmd: " << CMD << "\n"; } if (printHipVersion) { if (runCmd) { cout << "HIP version: "; } cout << hipVersion << endl; } if (printCXXFlags) { cout << HIPCXXFLAGS; } if (printLDFlags) { cout << HIPLDFLAGS; } if (runCmd) { SystemCmdOut sysOut; sysOut = hipBinUtilPtr_->exec(CMD.c_str(), true); string cmdOut = sysOut.out; int CMD_EXIT_CODE = sysOut.exitCode; if (CMD_EXIT_CODE !=0) { std::cerr << "failed to execute:" << CMD << std::endl; } exit(CMD_EXIT_CODE); } // end of runCmd section } // end of function #endif // SRC_HIPBIN_AMD_H_ HIPCC-rocm-5.7.1/src/hipBin_base.h000066400000000000000000000436071446002202200164550ustar00rootroot00000000000000/* Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef SRC_HIPBIN_BASE_H_ #define SRC_HIPBIN_BASE_H_ #include "hipBin_util.h" #include #include #include // All envirnoment variables used in the code # define PATH "PATH" # define HIP_ROCCLR_HOME "HIP_ROCCLR_HOME" # define HIP_PATH "HIP_PATH" # define ROCM_PATH "ROCM_PATH" # define CUDA_PATH "CUDA_PATH" # define HSA_PATH "HSA_PATH" # define HIP_CLANG_PATH "HIP_CLANG_PATH" # define HIP_PLATFORM "HIP_PLATFORM" # define HIP_COMPILER "HIP_COMPILER" # define HIP_RUNTIME "HIP_RUNTIME" # define LD_LIBRARY_PATH "LD_LIBRARY_PATH" // hipcc # define HIPCC_COMPILE_FLAGS_APPEND "HIPCC_COMPILE_FLAGS_APPEND" # define HIPCC_LINK_FLAGS_APPEND "HIPCC_LINK_FLAGS_APPEND" # define HIP_LIB_PATH "HIP_LIB_PATH" # define DEVICE_LIB_PATH "DEVICE_LIB_PATH" # define HIP_CLANG_HCC_COMPAT_MODE "HIP_CLANG_HCC_COMPAT_MODE" # define HIP_COMPILE_CXX_AS_HIP "HIP_COMPILE_CXX_AS_HIP" # define HIPCC_VERBOSE "HIPCC_VERBOSE" # define HCC_AMDGPU_TARGET "HCC_AMDGPU_TARGET" # define HIP_BASE_VERSION_MAJOR "4" # define HIP_BASE_VERSION_MINOR "4" # define HIP_BASE_VERSION_PATCH "0" # define HIP_BASE_VERSION_GITHASH "0" enum PlatformType { amd = 0, nvidia, // add new platform types to be added here }; string PlatformTypeStr(PlatformType platform) { switch (platform) { case amd: return "amd"; case nvidia: return "nvidia"; // add new platform types to be added here default: return "invalid platform"; } } enum CompilerType { clang = 0, nvcc // add new compiler types to be added here }; string CompilerTypeStr(CompilerType compiler) { switch (compiler) { case clang: return "clang"; case nvcc: return "nvcc"; // add new compiler types to be added here default: return "invalid CompilerType"; } } enum RuntimeType { rocclr = 0, cuda // add new runtime types to be added here }; string RuntimeTypeStr(RuntimeType runtime) { switch (runtime) { case rocclr: return "rocclr"; case cuda: return "cuda"; // add new runtime types to be added here default: return "invalid RuntimeType"; } } enum OsType { lnx = 0, windows // add new OS types to be added here }; string OsTypeStr(OsType os) { switch (os) { case lnx: return "linux"; case windows: return "windows"; // add new OS types to be added here default: return "invalid OsType"; } } struct PlatformInfo { PlatformType platform; CompilerType compiler; RuntimeType runtime; OsType os; }; struct EnvVariables { string path_ = ""; string hipPathEnv_ = ""; string hipRocclrPathEnv_ = ""; string roccmPathEnv_ = ""; string cudaPathEnv_ = ""; string hsaPathEnv_ = ""; string hipClangPathEnv_ = ""; string hipPlatformEnv_ = ""; string hipCompilerEnv_ = ""; string hipRuntimeEnv_ = ""; string ldLibraryPathEnv_ = ""; string verboseEnv_ = ""; string hipccCompileFlagsAppendEnv_ = ""; string hipccLinkFlagsAppendEnv_ = ""; string hipLibPathEnv_ = ""; string deviceLibPathEnv_ = ""; string hipClangHccCompactModeEnv_ = ""; string hipCompileCxxAsHipEnv_ = ""; string hccAmdGpuTargetEnv_ = ""; friend std::ostream& operator <<(std::ostream& os, const EnvVariables& var) { os << "Path: " << var.path_ << endl; os << "Hip Path: " << var.hipPathEnv_ << endl; os << "Hip Rocclr Path: " << var.hipRocclrPathEnv_ << endl; os << "Roccm Path: " << var.roccmPathEnv_ << endl; os << "Cuda Path: " << var.cudaPathEnv_ << endl; os << "Hsa Path: " << var.hsaPathEnv_ << endl; os << "Hip Clang Path: " << var.hipClangPathEnv_ << endl; os << "Hip Platform: " << var.hipPlatformEnv_ << endl; os << "Hip Compiler: " << var.hipCompilerEnv_ << endl; os << "Hip Runtime: " << var.hipRuntimeEnv_ << endl; os << "LD Library Path: " << var.ldLibraryPathEnv_ << endl; os << "Verbose: " << var.verboseEnv_ << endl; os << "Hipcc Compile Flags Append: " << var.hipccCompileFlagsAppendEnv_ << endl; os << "Hipcc Link Flags Append: " << var.hipccLinkFlagsAppendEnv_ << endl; os << "Hip lib Path: " << var.hipLibPathEnv_ << endl; os << "Device lib Path: " << var.deviceLibPathEnv_ << endl; os << "Hip Clang HCC Compact mode: " << var.hipClangHccCompactModeEnv_ << endl; os << "Hip Compile Cxx as Hip: " << var.hipCompileCxxAsHipEnv_ << endl; os << "Hcc Amd Gpu Target: " << var.hccAmdGpuTargetEnv_ << endl; return os; } }; enum HipBinCommand { unknown = -1, path, roccmpath, cpp_config, compiler, platform, runtime, hipclangpath, full, version, check, newline, help, }; class HipBinBase { public: HipBinBase(); // Interface functions virtual void constructCompilerPath() = 0; virtual void printFull() = 0; virtual bool detectPlatform() = 0; virtual const string& getCompilerPath() const = 0; virtual void printCompilerInfo() const = 0; virtual string getCompilerVersion() = 0; virtual const PlatformInfo& getPlatformInfo() const = 0; virtual string getCppConfig() = 0; virtual void checkHipconfig() = 0; virtual string getDeviceLibPath() const = 0; virtual string getHipLibPath() const = 0; virtual string getHipCC() const = 0; virtual string getHipInclude() const = 0; virtual void initializeHipCXXFlags() = 0; virtual void initializeHipCFlags() = 0; virtual void initializeHipLdFlags() = 0; virtual const string& getHipCXXFlags() const = 0; virtual const string& getHipCFlags() const = 0; virtual const string& getHipLdFlags() const = 0; virtual void executeHipCCCmd(vector argv) = 0; // Common functions used by all platforms void getSystemInfo() const; void printEnvironmentVariables() const; const EnvVariables& getEnvVariables() const; const OsType& getOSInfo() const; const string& getHipPath() const; const string& getRoccmPath() const; const string& getHipVersion() const; void printUsage() const; bool canRunCompiler(string exeName, string& cmdOut); HipBinCommand gethipconfigCmd(string argument); const string& getrocm_pathOption() const; protected: // hipBinUtilPtr used by derived platforms // so therefore its protected HipBinUtil* hipBinUtilPtr_; string rocm_pathOption_ = ""; void readOSInfo(); void readEnvVariables(); void constructHipPath(); void constructRoccmPath(); void readHipVersion(); private: EnvVariables envVariables_, variables_; OsType osInfo_; string hipVersion_; }; HipBinBase::HipBinBase() { hipBinUtilPtr_ = hipBinUtilPtr_->getInstance(); readOSInfo(); // detects if windows or linux readEnvVariables(); // reads the environment variables } // detects the OS information void HipBinBase::readOSInfo() { #if defined _WIN32 || defined _WIN64 osInfo_ = windows; #elif defined __unix || defined __linux__ osInfo_ = lnx; #endif } // reads envirnoment variables void HipBinBase::readEnvVariables() { if (const char* path = std::getenv(PATH)) envVariables_.path_ = path; if (const char* hip = std::getenv(HIP_PATH)) envVariables_.hipPathEnv_ = hip; if (const char* hip_rocclr = std::getenv(HIP_ROCCLR_HOME)) envVariables_.hipRocclrPathEnv_ = hip_rocclr; if (const char* roccm = std::getenv(ROCM_PATH)) envVariables_.roccmPathEnv_ = roccm; if (const char* cuda = std::getenv(CUDA_PATH)) envVariables_.cudaPathEnv_ = cuda; if (const char* hsa = std::getenv(HSA_PATH)) envVariables_.hsaPathEnv_ = hsa; if (const char* hipClang = std::getenv(HIP_CLANG_PATH)) envVariables_.hipClangPathEnv_ = hipClang; if (const char* hipPlatform = std::getenv(HIP_PLATFORM)) envVariables_.hipPlatformEnv_ = hipPlatform; if (const char* hipCompiler = std::getenv(HIP_COMPILER)) envVariables_.hipCompilerEnv_ = hipCompiler; if (const char* hipRuntime = std::getenv(HIP_RUNTIME)) envVariables_.hipRuntimeEnv_ = hipRuntime; if (const char* ldLibaryPath = std::getenv(LD_LIBRARY_PATH)) envVariables_.ldLibraryPathEnv_ = ldLibaryPath; if (const char* hccAmdGpuTarget = std::getenv(HCC_AMDGPU_TARGET)) envVariables_.hccAmdGpuTargetEnv_ = hccAmdGpuTarget; if (const char* verbose = std::getenv(HIPCC_VERBOSE)) envVariables_.verboseEnv_ = verbose; if (const char* hipccCompileFlagsAppend = std::getenv(HIPCC_COMPILE_FLAGS_APPEND)) envVariables_.hipccCompileFlagsAppendEnv_ = hipccCompileFlagsAppend; if (const char* hipccLinkFlagsAppend = std::getenv(HIPCC_LINK_FLAGS_APPEND)) envVariables_.hipccLinkFlagsAppendEnv_ = hipccLinkFlagsAppend; if (const char* hipLibPath = std::getenv(HIP_LIB_PATH)) envVariables_.hipLibPathEnv_ = hipLibPath; if (const char* deviceLibPath = std::getenv(DEVICE_LIB_PATH)) envVariables_.deviceLibPathEnv_ = deviceLibPath; if (const char* hipClangHccCompactMode = std::getenv(HIP_CLANG_HCC_COMPAT_MODE)) envVariables_.hipClangHccCompactModeEnv_ = hipClangHccCompactMode; if (const char* hipCompileCxxAsHip = std::getenv(HIP_COMPILE_CXX_AS_HIP)) envVariables_.hipCompileCxxAsHipEnv_ = hipCompileCxxAsHip; } // constructs the HIP path void HipBinBase::constructHipPath() { fs::path full_path(hipBinUtilPtr_->getSelfPath()); if (envVariables_.hipPathEnv_.empty()) variables_.hipPathEnv_ = (full_path.parent_path()).string(); else variables_.hipPathEnv_ = envVariables_.hipPathEnv_; } // constructs the ROCM path void HipBinBase::constructRoccmPath() { // we need to use --rocm-path option string rocm_path_name = getrocm_pathOption(); // chose the --rocm-path option first, if specified. if (!rocm_path_name.empty()) variables_.roccmPathEnv_ = rocm_path_name; else if (envVariables_.roccmPathEnv_.empty()) { const string& hipPath = getHipPath(); fs::path roccm_path(hipPath); roccm_path = roccm_path.parent_path(); fs::path rocm_agent_enumerator_file(roccm_path); rocm_agent_enumerator_file /= "bin/rocm_agent_enumerator"; if (!fs::exists(rocm_agent_enumerator_file)) { roccm_path = "/opt/rocm"; } } else { variables_.roccmPathEnv_ = envVariables_.roccmPathEnv_;} } // reads the Hip Version void HipBinBase::readHipVersion() { string hipVersion; const string& hipPath = getHipPath(); fs::path hipVersionPath = hipPath; hipVersionPath /= "bin/.hipVersion"; map hipVersionMap; hipVersionMap = hipBinUtilPtr_->parseConfigFile(hipVersionPath); string hip_version_major, hip_version_minor, hip_version_patch, hip_version_githash; hip_version_major = hipBinUtilPtr_->readConfigMap( hipVersionMap, "HIP_VERSION_MAJOR", HIP_BASE_VERSION_MAJOR); hip_version_minor = hipBinUtilPtr_->readConfigMap( hipVersionMap, "HIP_VERSION_MINOR", HIP_BASE_VERSION_MINOR); hip_version_patch = hipBinUtilPtr_->readConfigMap( hipVersionMap, "HIP_VERSION_PATCH", HIP_BASE_VERSION_PATCH); hip_version_githash = hipBinUtilPtr_->readConfigMap( hipVersionMap, "HIP_VERSION_GITHASH", HIP_BASE_VERSION_GITHASH); hipVersion = hip_version_major + "." + hip_version_minor + "." + hip_version_patch + "-" + hip_version_githash; hipVersion_ = hipVersion; } // prints system information void HipBinBase::getSystemInfo() const { const OsType& os = getOSInfo(); if (os == windows) { cout << endl << "== Windows Display Drivers" << endl; cout << "Hostname :"; system("hostname"); system("wmic path win32_VideoController get AdapterCompatibility," "InstalledDisplayDrivers,Name | findstr /B /C:\"Advanced Micro Devices\""); } else { assert(os == lnx); cout << endl << "== Linux Kernel" << endl; cout << "Hostname :" << endl; system("hostname"); system("uname -a"); } } // prints the envirnoment variables void HipBinBase::printEnvironmentVariables() const { const OsType& os = getOSInfo(); if (os == windows) { cout << "PATH=" << envVariables_.path_ << "\n" << endl; system("set | findstr" " /B /C:\"HIP\" /C:\"HSA\" /C:\"CUDA\" /C:\"LD_LIBRARY_PATH\""); } else { string cmd = "echo PATH ="; cmd += envVariables_.path_; system(cmd.c_str()); system("env | egrep '^HIP|^HSA|^CUDA|^LD_LIBRARY_PATH'"); } } // returns envirnoment variables const EnvVariables& HipBinBase::getEnvVariables() const { return envVariables_; } // returns the os information const OsType& HipBinBase::getOSInfo() const { return osInfo_; } // returns the HIP path const string& HipBinBase::getHipPath() const { return variables_.hipPathEnv_; } // returns the Roccm path const string& HipBinBase::getRoccmPath() const { return variables_.roccmPathEnv_; } // returns the Hip Version const string& HipBinBase::getHipVersion() const { return hipVersion_; } // prints the help text void HipBinBase::printUsage() const { cout << "usage: hipconfig [OPTIONS]\n"; cout << " --path, -p :" " print HIP_PATH (use env var if set, else determine from hipconfig path)\n"; cout << " --rocmpath, -R :" " print ROCM_PATH (use env var if set," " else determine from hip path or /opt/rocm)\n"; cout << " --cpp_config, -C : print C++ compiler options\n"; cout << " --compiler, -c : print compiler (clang or nvcc)\n"; cout << " --platform, -P : print platform (amd or nvidia)\n"; cout << " --runtime, -r : print runtime (rocclr or cuda)\n"; cout << " --hipclangpath, -l : print HIP_CLANG_PATH\n"; cout << " --full, -f : print full config\n"; cout << " --version, -v : print hip version\n"; cout << " --check : check configuration\n"; cout << " --newline, -n : print newline\n"; cout << " --help, -h : print help message\n"; } // compiler canRun or not bool HipBinBase::canRunCompiler(string exeName, string& cmdOut) { string complierName = exeName; string temp_dir = hipBinUtilPtr_->getTempDir(); fs::path templateFs = temp_dir; templateFs /= "canRunXXXXXX"; string tmpFileName = hipBinUtilPtr_->mktempFile(templateFs.string()); complierName += " --version > " + tmpFileName + " 2>&1"; bool executable = false; if (system(const_cast(complierName.c_str()))) { executable = false; } else { string myline; ifstream fp; fp.open(tmpFileName); if (fp.is_open()) { while (std::getline(fp, myline)) { cmdOut += myline; } } fp.close(); executable = true; } return executable; } HipBinCommand HipBinBase::gethipconfigCmd(string argument) { vector pathStrs = { "-p", "--path", "-path", "--p" }; if (hipBinUtilPtr_->checkCmd(pathStrs, argument)) return path; vector rocmPathStrs = { "-R", "--rocmpath", "-rocmpath", "--R" }; if (hipBinUtilPtr_->checkCmd(rocmPathStrs, argument)) return roccmpath; vector cppConfigStrs = { "-C", "--cpp_config", "-cpp_config", "--C", }; if (hipBinUtilPtr_->checkCmd(cppConfigStrs, argument)) return cpp_config; vector CompilerStrs = { "-c", "--compiler", "-compiler", "--c" }; if (hipBinUtilPtr_->checkCmd(CompilerStrs, argument)) return compiler; vector platformStrs = { "-P", "--platform", "-platform", "--P" }; if (hipBinUtilPtr_->checkCmd(platformStrs, argument)) return platform; vector runtimeStrs = { "-r", "--runtime", "-runtime", "--r" }; if (hipBinUtilPtr_->checkCmd(runtimeStrs, argument)) return runtime; vector hipClangPathStrs = { "-l", "--hipclangpath", "-hipclangpath", "--l" }; if (hipBinUtilPtr_->checkCmd(hipClangPathStrs, argument)) return hipclangpath; vector fullStrs = { "-f", "--full", "-full", "--f" }; if (hipBinUtilPtr_->checkCmd(fullStrs, argument)) return full; vector versionStrs = { "-v", "--version", "-version", "--v" }; if (hipBinUtilPtr_->checkCmd(versionStrs, argument)) return version; vector checkStrs = { "--check", "-check" }; if (hipBinUtilPtr_->checkCmd(checkStrs, argument)) return check; vector newlineStrs = { "--n", "-n", "--newline", "-newline" }; if (hipBinUtilPtr_->checkCmd(newlineStrs, argument)) return newline; vector helpStrs = { "-h", "--help", "-help", "--h" }; if (hipBinUtilPtr_->checkCmd(helpStrs, argument)) return help; return full; // default is full. return full if no commands are matched } const string& HipBinBase::getrocm_pathOption() const { return rocm_pathOption_; } #endif // SRC_HIPBIN_BASE_H_ HIPCC-rocm-5.7.1/src/hipBin_nvidia.h000066400000000000000000000451331446002202200170110ustar00rootroot00000000000000/* Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef SRC_HIPBIN_NVIDIA_H_ #define SRC_HIPBIN_NVIDIA_H_ #include "hipBin_base.h" #include "hipBin_util.h" #include #include #include class HipBinNvidia : public HipBinBase { private: HipBinUtil* hipBinUtilPtr_; string cudaPath_ = ""; PlatformInfo platformInfoNV_; string hipCFlags_, hipCXXFlags_, hipLdFlags_; public: HipBinNvidia(); virtual ~HipBinNvidia() = default; virtual bool detectPlatform(); virtual void constructCompilerPath(); virtual const string& getCompilerPath() const; virtual const PlatformInfo& getPlatformInfo() const; virtual string getCppConfig(); virtual void printFull(); virtual void printCompilerInfo() const; virtual string getCompilerVersion(); virtual void checkHipconfig(); virtual string getDeviceLibPath() const; virtual string getHipLibPath() const; virtual string getHipCC() const; virtual string getCompilerIncludePath(); virtual string getHipInclude() const; virtual void initializeHipCXXFlags(); virtual void initializeHipCFlags(); virtual void initializeHipLdFlags(); virtual const string& getHipCXXFlags() const; virtual const string& getHipCFlags() const; virtual const string& getHipLdFlags() const; virtual void executeHipCCCmd(vector argv); }; HipBinNvidia::HipBinNvidia() { PlatformInfo platformInfo; platformInfo.os = getOSInfo(); platformInfo.platform = nvidia; platformInfo.runtime = cuda; platformInfo.compiler = nvcc; platformInfoNV_ = platformInfo; constructCompilerPath(); } // detects if cuda is installed bool HipBinNvidia::detectPlatform() { string out; const string& nvccPath = getCompilerPath(); fs::path cmdNv = nvccPath; cmdNv /= "bin/nvcc"; const OsType& os = getOSInfo(); const EnvVariables& var = getEnvVariables(); bool detected = false; if (var.hipPlatformEnv_.empty()) { if (canRunCompiler(cmdNv.string(), out) || (canRunCompiler("nvcc", out))) { detected = true; } } else { if (var.hipPlatformEnv_ == "nvidia" || var.hipPlatformEnv_ == "nvcc") { detected = true; if (var.hipPlatformEnv_ == "nvcc") std::cerr << "Warning: HIP_PLATFORM=nvcc is deprecated." << "Please use HIP_PLATFORM=nvidia." << endl; } } return detected; } // returns device lib path string HipBinNvidia::getDeviceLibPath() const { cout << "TODO Not required for now" << endl; return ""; } // returns compiler path string HipBinNvidia::getHipCC() const { string hipCC; const string& cudaPath = getCompilerPath(); fs::path hipCCPath; hipCCPath = cudaPath; hipCCPath /= "bin/nvcc"; hipCC = hipCCPath.string(); return hipCC; } // returns compiler include path string HipBinNvidia::getCompilerIncludePath() { cout << "TODO Not required for now" << endl; return ""; } // checks Hipconfig void HipBinNvidia::checkHipconfig() { cout << endl << "Check system installation: " << endl; cout << "check hipconfig in PATH..." << endl; if (system("which hipconfig > /dev/null 2>&1") != 0) { std::cerr << "FAIL " << endl; } else { cout << "good" << endl; } } // prints full void HipBinNvidia::printFull() { const string& hipVersion = getHipVersion(); const string& hipPath = getHipPath(); const string& roccmPath = getRoccmPath(); const PlatformInfo& platformInfo = getPlatformInfo(); const string& ccpConfig = getCppConfig(); const string& cudaPath = getCompilerPath(); cout << "HIP version: " << hipVersion << endl; cout << endl << "==hipconfig" << endl; cout << "HIP_PATH :" << hipPath << endl; cout << "ROCM_PATH :" << roccmPath << endl; cout << "HIP_COMPILER :" << CompilerTypeStr( platformInfo.compiler) << endl; cout << "HIP_PLATFORM :" << PlatformTypeStr( platformInfo.platform) << endl; cout << "HIP_RUNTIME :" << RuntimeTypeStr( platformInfo.runtime) << endl; cout << "CPP_CONFIG :" << ccpConfig << endl; cout << endl << "== nvcc" << endl; cout << "CUDA_PATH :" << cudaPath < argv) { if (argv.size() < 2) { cout<< "No Arguments passed, exiting ...\n"; exit(EXIT_SUCCESS); } const EnvVariables& var = getEnvVariables(); int verbose = 0; if (!var.verboseEnv_.empty()) verbose = stoi(var.verboseEnv_); // Verbose: 0x1=commands, 0x2=paths, 0x4=hipcc args // set if user explicitly requests -stdlib=libc++. // (else we default to libstdc++ for better interop with g++): bool setStdLib = 0; bool default_amdgpu_target = 1; bool compileOnly = 0; bool needCXXFLAGS = 0; // need to add CXX flags to compile step bool needCFLAGS = 0; // need to add C flags to compile step bool needLDFLAGS = 1; // need to add LDFLAGS to compile step. bool fileTypeFlag = 0; // to see if -x flag is mentioned bool hasOMPTargets = 0; // If OMP targets is mentioned bool hasC = 0; // options contain a c-style file // options contain a cpp-style file (NVCC must force recognition as GPU file) bool hasCXX = 0; // options contain a cu-style file (HCC must force recognition as GPU file) bool hasCU = 0; // options contain a hip-style file (HIP-Clang must pass offloading options) bool hasHIP = 0; bool printHipVersion = 0; // print HIP version bool printCXXFlags = 0; // print HIPCXXFLAGS bool printLDFlags = 0; // print HIPLDFLAGS bool runCmd = 1; bool buildDeps = 0; bool linkType = 1; bool setLinkType = 0; string hsacoVersion; bool funcSupp = 0; // enable function support bool rdc = 0; // whether -fgpu-rdc is on string prevArg; // TODO(hipcc): convert toolArgs to an array rather than a string string toolArgs; string optArg; vector options, inputs; // TODO(hipcc): hipcc uses --amdgpu-target for historical reasons. // It should be replaced by clang option --offload-arch. vector targetOpts = {"--offload-arch=", "--amdgpu-target="}; string targetsStr; bool skipOutputFile = false; const OsType& os = getOSInfo(); string hip_compile_cxx_as_hip; if (var.hipCompileCxxAsHipEnv_.empty()) { hip_compile_cxx_as_hip = "1"; } else { hip_compile_cxx_as_hip = var.hipCompileCxxAsHipEnv_; } string HIPLDARCHFLAGS; initializeHipCXXFlags(); initializeHipCFlags(); initializeHipLdFlags(); string HIPCXXFLAGS, HIPCFLAGS, HIPLDFLAGS; HIPCFLAGS = getHipCFlags(); HIPCXXFLAGS = getHipCXXFlags(); HIPLDFLAGS = getHipLdFlags(); string hipPath; hipPath = getHipPath(); const PlatformInfo& platformInfo = getPlatformInfo(); const string& nvccPath = getCompilerPath(); const string& hipVersion = getHipVersion(); if (verbose & 0x2) { cout << "HIP_PATH=" << hipPath << endl; cout << "HIP_PLATFORM=" << PlatformTypeStr(platformInfo.platform) <substringPresent(isaarg,"--rocm-path=")) { ISACMD += isaarg; } } if (verbose & 0x1) { cout<< "hipcc-cmd: " << ISACMD << "\n"; } system(ISACMD.c_str()); exit(EXIT_SUCCESS); } for (unsigned int argcount = 1; argcount < argv.size(); argcount++) { // Save $arg, it can get changed in the loop. string arg = argv.at(argcount); regex toRemove("\\s+"); // TODO(hipcc): figure out why this space removal is wanted. // TODO(hipcc): If someone has gone to the effort of quoting // the spaces to the shell // TODO(hipcc): why are we removing it here? string trimarg = hipBinUtilPtr_->replaceRegex(arg, toRemove, ""); bool swallowArg = false; bool escapeArg = true; if (arg == "-c" || arg == "--genco" || arg == "-E") { compileOnly = true; needLDFLAGS = false; } if (skipOutputFile) { // TODO(hipcc): handle filename with shell metacharacters toolArgs += " \"" + arg +"\""; prevArg = arg; skipOutputFile = 0; continue; } if (arg == "-o") { needLDFLAGS = 1; skipOutputFile = 1; } if ((trimarg == "-stdlib=libc++") && (setStdLib == 0)) { HIPCXXFLAGS += " -stdlib=libc++"; setStdLib = 1; } // Check target selection option: --offload-arch= and --amdgpu-target=... for (unsigned int i = 0; i stringRegexMatch(arg, pattern)) { // If targets string is not empty, add a comma before // adding new target option value. targetsStr.size() >0 ? targetsStr += ",": targetsStr += ""; targetsStr += arg.substr(targetOpt.size()); default_amdgpu_target = 0; } } if (trimarg == "--version") { printHipVersion = 1; } if (trimarg == "--short-version") { printHipVersion = 1; runCmd = 0; } if (trimarg == "--cxxflags") { printCXXFlags = 1; runCmd = 0; } if (trimarg == "--ldflags") { printLDFlags = 1; runCmd = 0; } if (trimarg == "-M") { compileOnly = 1; buildDeps = 1; } if (trimarg == "-use_fast_math") { HIPCXXFLAGS += " -DHIP_FAST_MATH "; HIPCFLAGS += " -DHIP_FAST_MATH "; } if ((trimarg == "-use-staticlib") && (setLinkType == 0)) { linkType = 0; setLinkType = 1; swallowArg = 1; } if ((trimarg == "-use-sharedlib") && (setLinkType == 0)) { linkType = 1; setLinkType = 1; } if (hipBinUtilPtr_->stringRegexMatch(arg, "^-O.*")) { optArg = arg; } if (hipBinUtilPtr_->substringPresent( arg, "--amdhsa-code-object-version=")) { arg = hipBinUtilPtr_->replaceStr( arg, "--amdhsa-code-object-version=", ""); hsacoVersion = arg; swallowArg = 1; } // nvcc does not handle standard compiler options properly // This can prevent hipcc being used as standard CXX/C Compiler // To fix this we need to pass -Xcompiler for options if (arg == "-fPIC" || hipBinUtilPtr_->substringPresent(arg, "-Wl,")) { HIPCXXFLAGS += " -Xcompiler "+ arg; swallowArg = 1; } if (arg == "-x") { fileTypeFlag = 1; } else if ((arg == "c" && prevArg == "-x") || (arg == "-xc")) { fileTypeFlag = 1; hasC = 1; hasCXX = 0; hasHIP = 0; } else if ((arg == "c++" && prevArg == "-x") || (arg == "-xc++")) { fileTypeFlag = 1; hasC = 0; hasCXX = 1; hasHIP = 0; } else if ((arg == "hip" && prevArg == "-x") || (arg == "-xhip")) { fileTypeFlag = 1; hasC = 0; hasCXX = 0; hasHIP = 1; } else if (hipBinUtilPtr_->substringPresent(arg, "-fopenmp-targets=")) { hasOMPTargets = 1; } else if (hipBinUtilPtr_->stringRegexMatch(arg, "^-.*")) { if (arg == "-fgpu-rdc") { rdc = 1; } else if (arg == "-fno-gpu-rdc") { rdc = 0; } if (hipBinUtilPtr_->stringRegexMatch(arg, "^--hipcc.*")) { swallowArg = 1; if (arg == "--hipcc-func-supp") { funcSupp = 1; } else if (arg == "--hipcc-no-func-supp") { funcSupp = 0; } } else { options.push_back(arg); } } else if (prevArg != "-o") { if (fileTypeFlag == 0) { if (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.c$")) { hasC = 1; needCFLAGS = 1; toolArgs += " -x c"; } else if ((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cpp$")) || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cxx$")) || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cc$")) || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.C$"))) { needCXXFLAGS = 1; hasCXX = 1; } else if (((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cu$") || hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cuh$")) && hip_compile_cxx_as_hip != "0") || (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.hip$"))) { needCXXFLAGS = 1; hasCU = 1; } } if (hasC) { needCFLAGS = 1; } else if (hasCXX || hasHIP) { needCXXFLAGS = 1; } inputs.push_back(arg); } // Windows needs different quoting, ignore for now if (os != windows && escapeArg) { regex reg("[^-a-zA-Z0-9_=+,.\\/]"); arg = regex_replace(arg, reg, "\\$&"); } if (!swallowArg) toolArgs += " " + arg; prevArg = arg; } // end of for loop if (hasCXX) { HIPCXXFLAGS += " -x cu"; } if (buildDeps) { HIPCXXFLAGS += " -M -D__CUDACC__"; HIPCFLAGS += " -M -D__CUDACC__"; } if (!var.hipccCompileFlagsAppendEnv_.empty()) { HIPCXXFLAGS += "\" " + var.hipccCompileFlagsAppendEnv_ + "\""; HIPCFLAGS += "\" " + var.hipccCompileFlagsAppendEnv_ + "\""; } if (!var.hipccLinkFlagsAppendEnv_.empty()) { HIPLDFLAGS += "\" " + var.hipccLinkFlagsAppendEnv_ + "\""; } string compiler; compiler = getHipCC(); string CMD = compiler; if (needCFLAGS) { CMD += " " + HIPCFLAGS; } if (needCXXFLAGS) { CMD += " " + HIPCXXFLAGS; } if (needLDFLAGS && !compileOnly) { CMD += " " + HIPLDFLAGS; } CMD += " " + toolArgs; if (verbose & 0x1) { cout << "hipcc-cmd: " << CMD << "\n"; } if (printHipVersion) { if (runCmd) { cout << "HIP version: "; } cout << hipVersion << endl; } if (printCXXFlags) { cout << HIPCXXFLAGS; } if (printLDFlags) { cout << HIPLDFLAGS; } if (runCmd) { SystemCmdOut sysOut; sysOut = hipBinUtilPtr_->exec(CMD.c_str(), true); string cmdOut = sysOut.out; int CMD_EXIT_CODE = sysOut.exitCode; if (CMD_EXIT_CODE !=0) { cout << "failed to execute:" << CMD << std::endl; } exit(CMD_EXIT_CODE); } } // end of function #endif // SRC_HIPBIN_NVIDIA_H_ HIPCC-rocm-5.7.1/src/hipBin_util.h000066400000000000000000000256751446002202200165250ustar00rootroot00000000000000/* Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef SRC_HIPBIN_UTIL_H_ #define SRC_HIPBIN_UTIL_H_ // We haven't checked which filesystem to include yet #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL // Check for feature test macro for #if defined(__cpp_lib_filesystem) #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 // Check for feature test macro for #elif defined(__cpp_lib_experimental_filesystem) #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 // We can't check if headers exist... // Let's assume experimental to be safe #elif !defined(__has_include) #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 // Check if the header "" exists #elif __has_include() // If we're compiling on Visual Studio and are not compiling with C++17, // we need to use experimental #ifdef _MSC_VER // Check and include header that defines "_HAS_CXX17" #if __has_include() #include // Check for enabled C++17 support #if defined(_HAS_CXX17) && _HAS_CXX17 // We're using C++17, so let's use the normal version #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 #endif #endif // If the marco isn't defined yet, that means any of the other // VS specific checks failed, so we need to use experimental #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 #endif // Not on Visual Studio. Let's use the normal version #else // #ifdef _MSC_VER #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 #endif // Check if the header "" exists #elif __has_include() #define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 // Fail if neither header is available with a nice error message #else #error Could not find system header "" || "" #endif // We priously determined that we need the exprimental version #if INCLUDE_STD_FILESYSTEM_EXPERIMENTAL // Include it #include // We need the alias from std::experimental::filesystem to std::filesystem namespace fs = std::experimental::filesystem; // We have a decent compiler and can use the normal version #else // Include it #include namespace fs = std::filesystem; #endif #endif // #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL #include #include #include #include #include #include #include #include #include #include #include #if defined(_WIN32) || defined(_WIN64) #include #include #include #ifdef _UNICODE typedef wchar_t TCHAR; typedef std::wstring TSTR; typedef std::wstring::size_type TSIZE; #define ENDLINE L"/\\" #else typedef char TCHAR; typedef std::string TSTR; typedef std::string::size_type TSIZE; #define ENDLINE "/\\" #endif #else #include #endif using std::cout; using std::endl; using std::vector; using std::string; using std::ifstream; using std::ofstream; using std::regex; using std::regex_match; using std::regex_search; using std::regex_replace; using std::map; using std::smatch; using std::stringstream; struct SystemCmdOut { string out; int exitCode = 0; }; class HipBinUtil { public: static HipBinUtil* getInstance() { if (!instance) instance = new HipBinUtil; return instance; } virtual ~HipBinUtil(); // Common helper functions string getSelfPath() const; vector splitStr(string fullStr, char delimiter) const; string replaceStr(const string& s, const string& toReplace, const string& replaceWith) const; string replaceRegex(const string& s, regex toReplace, string replaceWith) const; SystemCmdOut exec(const char* cmd, bool printConsole) const; string getTempDir(); void deleteTempFiles(); string mktempFile(string name); string trim(string str) const; string readConfigMap(map hipVersionMap, string keyName, string defaultValue) const; map parseConfigFile(fs::path configPath) const; bool substringPresent(string fullString, string subString) const; bool stringRegexMatch(string fullString, string pattern) const; bool checkCmd(const vector& commands, const string& argument); private: HipBinUtil() {} vector tmpFiles_; static HipBinUtil *instance; }; HipBinUtil *HipBinUtil::instance = 0; // deleting temp files created HipBinUtil::~HipBinUtil() { deleteTempFiles(); } // create temp file with the template name string HipBinUtil::mktempFile(string name) { string fileName; #if defined(_WIN32) || defined(_WIN64) fileName = _mktemp(&name[0]); #else fileName = mkdtemp(&name[0]); #endif tmpFiles_.push_back(fileName); return fileName; } // gets the path of the executable name string HipBinUtil::getSelfPath() const { int MAX_PATH_CHAR = 1024; int bufferSize = 0; string path; #if defined(_WIN32) || defined(_WIN64) TCHAR buffer[MAX_PATH] = { 0 }; bufferSize = GetModuleFileName(NULL, buffer, MAX_PATH_CHAR); TSIZE pos = TSTR(buffer).find_last_of(ENDLINE); TSTR wide = TSTR(buffer).substr(0, pos); path = string(wide.begin(), wide.end()); #else char buff[MAX_PATH_CHAR]; ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff) - 1); if (len > 0) { buff[len] = '\0'; path = string(buff); fs::path exePath(path); path = exePath.parent_path().string(); } else { std::cerr << "readlink: Error reading the exe path" << endl; perror("readlink"); exit(-1); } #endif return path; } // removes the empty spaces and end lines string HipBinUtil::trim(string str) const { string strChomp = str; strChomp.erase(str.find_last_not_of(" \n\r\t")+1); return strChomp; } // matches the pattern in the string bool HipBinUtil::stringRegexMatch(string fullString, string pattern) const { return regex_match(fullString, regex(pattern)); } // subtring is present in string bool HipBinUtil::substringPresent(string fullString, string subString) const { return fullString.find(subString) != string::npos; } // splits the string with the delimiter vector HipBinUtil::splitStr(string fullStr, char delimiter) const { vector tokens; stringstream check1(fullStr); string intermediate; while (getline(check1, intermediate, delimiter)) { tokens.push_back(intermediate); } return tokens; } // replaces the toReplace string with replaceWith string. Returns the new string string HipBinUtil::replaceStr(const string& s, const string& toReplace, const string& replaceWith) const { string out = s; std::size_t pos = out.find(toReplace); if (pos == string::npos) return out; return out.replace(pos, toReplace.length(), replaceWith); } // replaces the toReplace regex pattern with replaceWith string. // Returns the new string string HipBinUtil::replaceRegex(const string& s, regex toReplace, string replaceWith) const { string out = s; while (regex_search(out, toReplace)) { out = regex_replace(out, toReplace, replaceWith); } return out; } // reads the config file and stores it in a map for access map HipBinUtil::parseConfigFile(fs::path configPath) const { map configMap; ifstream isFile(configPath.string()); string line; if (isFile.is_open()) { while (std::getline(isFile, line)) { std::istringstream is_line(line); string key; if (std::getline(is_line, key, '=')) { string value; if (std::getline(is_line, value)) { configMap.insert({ key, value }); } } } isFile.close(); } return configMap; } // Delete all created temporary files void HipBinUtil::deleteTempFiles() { // Deleting temp files vs the temp directory for (unsigned int i = 0; i < tmpFiles_.size(); i++) { try { if (!fs::remove(tmpFiles_.at(i))) std::cerr << "Error deleting temp name: "<< tmpFiles_.at(i) < hipVersionMap, string keyName, string defaultValue) const { auto it = hipVersionMap.find(keyName); if (it != hipVersionMap.end()) { return it->second; } return defaultValue; } bool HipBinUtil::checkCmd(const vector& commands, const string& argument) { bool found = false; for (unsigned int i = 0; i < commands.size(); i++) { if (argument.compare(commands.at(i)) == 0) { found = true; break; } } return found; } #endif // SRC_HIPBIN_UTIL_H_