diff --git a/amd/hipcc/.github/dependabot.yml b/amd/hipcc/.github/dependabot.yml new file mode 100644 index 00000000000000..9cdf2d670c3584 --- /dev/null +++ b/amd/hipcc/.github/dependabot.yml @@ -0,0 +1,12 @@ +# 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" diff --git a/amd/hipcc/.gitignore b/amd/hipcc/.gitignore new file mode 100644 index 00000000000000..3c2e3103578a16 --- /dev/null +++ b/amd/hipcc/.gitignore @@ -0,0 +1,17 @@ +# 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/ diff --git a/amd/hipcc/.jenkins/Jenkinsfile b/amd/hipcc/.jenkins/Jenkinsfile index a785c95a496169..d4fe13c5732787 100644 --- a/amd/hipcc/.jenkins/Jenkinsfile +++ b/amd/hipcc/.jenkins/Jenkinsfile @@ -15,24 +15,18 @@ def hipBuildTest(String backendLabel) { env.HIP_DIR = "${WORKSPACE}" + "/hip" } - // Clone hipamd repository - dir("${WORKSPACE}/hipamd") { + // Clone clr repository + dir("${WORKSPACE}/clr") { git branch: 'develop', - url: 'https://github.com/ROCm-Developer-Tools/hipamd' + credentialsId: 'branch-credentials', + url: 'https://github.com/ROCm-Developer-Tools/clr' + env.CLR_DIR = "${WORKSPACE}" + "/clr" } - // Clone vdi and opencl for only amd backend server - if (backendLabel =~ /.*amd.*/) { - dir("${WORKSPACE}/ROCm-OpenCL-Runtime") { - git branch:'develop', - url: 'https://github.com/RadeonOpenCompute/ROCm-OpenCL-Runtime' - env.OPENCL_DIR = "${WORKSPACE}" + "/ROCm-OpenCL-Runtime" - } - dir("${WORKSPACE}/ROCclr") { - git branch:'develop', - url: 'https://github.com/ROCm-Developer-Tools/ROCclr' - env.ROCclr_DIR = "${WORKSPACE}" + "/ROCclr" - } + // Clone hip-tests repository + dir("${WORKSPACE}/hip-tests") { + git branch: 'develop', + url: 'https://github.com/ROCm-Developer-Tools/hip-tests' } } @@ -50,43 +44,61 @@ def hipBuildTest(String backendLabel) { } } - stage("Build - Catch2 framework") { - // Running the build on hipamd workspace - dir("${WORKSPACE}/hipamd") { + 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 -DHIP_CATCH_TEST=1 -DHIP_PATH=\$PWD/install -DHIPCC_BIN_DIR=\$HIPCC_DIR/build -DHIP_COMMON_DIR=\$HIP_DIR -DAMD_OPENCL_PATH=\$OPENCL_DIR -DROCCLR_PATH=\$ROCclr_DIR -DCMAKE_PREFIX_PATH="/opt/rocm/" -DCMAKE_INSTALL_PREFIX=\$PWD/install .. + 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 - export HIP_PLATFORM=nvidia - export HIP_COMPILER=nvcc - export HIP_RUNTIME=cuda - cmake -DHIP_CATCH_TEST=1 -DHIP_PATH=\$PWD/install -DHIPCC_BIN_DIR=\$HIPCC_DIR/build -DHIP_COMMON_DIR=$HIP_DIR -DCMAKE_INSTALL_PREFIX=\$PWD/install .. + 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) - if [[ $backendLabel =~ amd ]]; then - make build_tests -j\$(nproc) - else - HIP_COMPILER=nvcc HIP_PLATFORM=nvidia make build_tests -j\$(nproc) - fi """ } } - stage('HIP Unit Tests - Catch2 framework') { - dir("${WORKSPACE}/hipamd/build") { + 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 - LLVM_PATH=/opt/rocm/llvm ctest -E 'Unit_hiprtc_saxpy' + 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 - make test + ctest --overwrite BuildDirectory=. --output-junit hiptest_output_catch_nvidia.xml -E 'Unit_hipMemcpyHtoD_Positive_Synchronization_Behavior|Unit_hipMemcpy_Positive_Synchronization_Behavior|Unit_hipFreeNegativeHost' fi """ + } } } } diff --git a/amd/hipcc/.readthedocs.yaml b/amd/hipcc/.readthedocs.yaml new file mode 100644 index 00000000000000..43a0890c96ead2 --- /dev/null +++ b/amd/hipcc/.readthedocs.yaml @@ -0,0 +1,14 @@ +# 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 diff --git a/amd/hipcc/CMakeLists.txt b/amd/hipcc/CMakeLists.txt index c21f2472f623a2..52da4f0dcff5b2 100644 --- a/amd/hipcc/CMakeLists.txt +++ b/amd/hipcc/CMakeLists.txt @@ -1,22 +1,129 @@ -cmake_minimum_required(VERSION 3.16.3) -project (hipcc.bin) +cmake_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() -# Specify the C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) -set (LINK_LIBS libstdc++fs.so) -add_executable(hipcc.bin src/hipBin.cpp) -if (NOT WIN32) # C++17 does not require the std lib linking - target_link_libraries(hipcc.bin ${LINK_LIBS} ) # for hipcc.bin +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 ${CMAKE_SOURCE_DIR}/bin/ DESTINATION ${CMAKE_CURRENT_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_AUTOREQROV 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) + set(exclusion_pattern "*.bat") +else () + set(exclusion_pattern "") +endif() + +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 ${exclusion_pattern} EXCLUDE ) + +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}) -project (hipconfig.bin) -add_executable(hipconfig.bin src/hipBin.cpp) -if (NOT WIN32) # C++17 does not require the std lib linking - target_link_libraries(hipconfig.bin ${LINK_LIBS} ) # for hipconfig.bin +# 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() -set(HIP_VERSION_MAJOR 4 PARENT_SCOPE) -set(HIP_VERSION_MINOR 4 PARENT_SCOPE) -set(HIP_VERSION_PATCH 4 PARENT_SCOPE) +include(CPack) diff --git a/amd/hipcc/README.md b/amd/hipcc/README.md index 7f5a031c43bed5..6212a9bc0d0241 100644 --- a/amd/hipcc/README.md +++ b/amd/hipcc/README.md @@ -5,12 +5,11 @@ - [hipcc](#hipcc) + * [Documentation](#documentation) * [Environment Variables](#envVar) * [Usage](#hipcc-usage) * [Building](#building) * [Testing](#testing) - * [Linux](#linux) - * [Windows](#windows) @@ -20,6 +19,18 @@ `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: @@ -63,4 +74,4 @@ The hipcc and hipconfig executables are created in the current build folder. The ### hipcc: testing -Currently hipcc/hipconfig executables are tested by building and executing HIP tests. Seperate tests for hipcc/hipconfig is currently not planned. \ No newline at end of file +Currently hipcc/hipconfig executables are tested by building and executing HIP tests. Separate tests for hipcc/hipconfig is currently not planned. diff --git a/amd/hipcc/bin/hipcc b/amd/hipcc/bin/hipcc new file mode 100755 index 00000000000000..4002631b5721c8 --- /dev/null +++ b/amd/hipcc/bin/hipcc @@ -0,0 +1,74 @@ +#!/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); diff --git a/amd/hipcc/bin/hipcc.bat b/amd/hipcc/bin/hipcc.bat new file mode 100755 index 00000000000000..beb67966cd5e24 --- /dev/null +++ b/amd/hipcc/bin/hipcc.bat @@ -0,0 +1,2 @@ +@set HIPCC="%~dp0hipcc" +@perl %HIPCC% %* diff --git a/amd/hipcc/bin/hipcc.pl b/amd/hipcc/bin/hipcc.pl new file mode 100755 index 00000000000000..56dcda2d59870b --- /dev/null +++ b/amd/hipcc/bin/hipcc.pl @@ -0,0 +1,651 @@ +#!/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 diff --git a/amd/hipcc/bin/hipconfig b/amd/hipcc/bin/hipconfig new file mode 100755 index 00000000000000..d50b10b94a9c82 --- /dev/null +++ b/amd/hipcc/bin/hipconfig @@ -0,0 +1,66 @@ +#!/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); diff --git a/amd/hipcc/bin/hipconfig.bat b/amd/hipcc/bin/hipconfig.bat new file mode 100755 index 00000000000000..16e68a14b75ddb --- /dev/null +++ b/amd/hipcc/bin/hipconfig.bat @@ -0,0 +1,2 @@ +@set HIPCONFIG="%~dp0hipconfig" +@perl %HIPCONFIG% %* diff --git a/amd/hipcc/bin/hipconfig.pl b/amd/hipcc/bin/hipconfig.pl new file mode 100755 index 00000000000000..dd03ad67a8c548 --- /dev/null +++ b/amd/hipcc/bin/hipconfig.pl @@ -0,0 +1,241 @@ +#!/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_VERSION = ""; + if($isWindows) { + $HIP_CLANG_VERSION = `\"$HIP_CLANG_PATH/clang++\" --version`; + } else { + $HIP_CLANG_VERSION = `$HIP_CLANG_PATH/clang++ --version`; + } + $HIP_CLANG_VERSION=~/.*clang version (\S+).*/; + $HIP_CLANG_VERSION=$1; + + $CPP_CONFIG = " -D__HIP_PLATFORM_HCC__= -D__HIP_PLATFORM_AMD__="; + + $HIP_PATH_INCLUDE = $HIP_PATH."/include"; + $HIP_CLANG_INCLUDE = $HIP_CLANG_PATH."/../lib/clang/".$HIP_CLANG_VERSION; + 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"; +} diff --git a/amd/hipcc/bin/hipvars.pm b/amd/hipcc/bin/hipvars.pm new file mode 100644 index 00000000000000..bea4ec71cef693 --- /dev/null +++ b/amd/hipcc/bin/hipvars.pm @@ -0,0 +1,158 @@ +#!/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 = "5"; +$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 has a different structure, all binaries are inside hip/bin +if ($isWindows) { + $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 = (); +parse_config_file("$hipvars::HIP_PATH/bin/.hipVersion", \%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"; diff --git a/amd/hipcc/docs/.sphinx/_toc.yml.in b/amd/hipcc/docs/.sphinx/_toc.yml.in new file mode 100644 index 00000000000000..0dbd7788147f51 --- /dev/null +++ b/amd/hipcc/docs/.sphinx/_toc.yml.in @@ -0,0 +1,10 @@ +# 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 diff --git a/amd/hipcc/docs/.sphinx/requirements.in b/amd/hipcc/docs/.sphinx/requirements.in new file mode 100644 index 00000000000000..7f2c40a8e05d29 --- /dev/null +++ b/amd/hipcc/docs/.sphinx/requirements.in @@ -0,0 +1 @@ +rocm-docs-core==0.13.4 diff --git a/amd/hipcc/docs/.sphinx/requirements.txt b/amd/hipcc/docs/.sphinx/requirements.txt new file mode 100644 index 00000000000000..4b247b75c10cf5 --- /dev/null +++ b/amd/hipcc/docs/.sphinx/requirements.txt @@ -0,0 +1,145 @@ +# +# 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.13.4 + # 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 diff --git a/amd/hipcc/docs/build.md b/amd/hipcc/docs/build.md new file mode 100644 index 00000000000000..67a974dca8f00c --- /dev/null +++ b/amd/hipcc/docs/build.md @@ -0,0 +1,12 @@ +# 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. diff --git a/amd/hipcc/docs/conf.py b/amd/hipcc/docs/conf.py new file mode 100644 index 00000000000000..bfd701171c1e54 --- /dev/null +++ b/amd/hipcc/docs/conf.py @@ -0,0 +1,13 @@ +# 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) diff --git a/amd/hipcc/docs/env.md b/amd/hipcc/docs/env.md new file mode 100644 index 00000000000000..09e82e7ae541d7 --- /dev/null +++ b/amd/hipcc/docs/env.md @@ -0,0 +1,11 @@ +# 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. diff --git a/amd/hipcc/docs/index.md b/amd/hipcc/docs/index.md new file mode 100644 index 00000000000000..b5ed99880414a7 --- /dev/null +++ b/amd/hipcc/docs/index.md @@ -0,0 +1,5 @@ +# 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`. diff --git a/amd/hipcc/docs/test.md b/amd/hipcc/docs/test.md new file mode 100644 index 00000000000000..ec376cce19046b --- /dev/null +++ b/amd/hipcc/docs/test.md @@ -0,0 +1,3 @@ +# Testing + +Currently hipcc/hipconfig executables are tested by building and executing HIP tests. Separate tests for hipcc/hipconfig is currently not planned. diff --git a/amd/hipcc/docs/usage.md b/amd/hipcc/docs/usage.md new file mode 100644 index 00000000000000..f928af28fc3b8d --- /dev/null +++ b/amd/hipcc/docs/usage.md @@ -0,0 +1,11 @@ +# 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 +``` diff --git a/amd/hipcc/hipcc-backward-compat.cmake b/amd/hipcc/hipcc-backward-compat.cmake new file mode 100644 index 00000000000000..d426d8be112c6d --- /dev/null +++ b/amd/hipcc/hipcc-backward-compat.cmake @@ -0,0 +1,45 @@ +# 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 +install(DIRECTORY ${HIPCC_WRAPPER_BIN_DIR} DESTINATION hip + FILES_MATCHING + PATTERN "*" + PATTERN ${exclusion_pattern} EXCLUDE ) diff --git a/amd/hipcc/src/hipBin_amd.h b/amd/hipcc/src/hipBin_amd.h index 1cfc6a36e77118..52b5ca21199a4e 100644 --- a/amd/hipcc/src/hipBin_amd.h +++ b/amd/hipcc/src/hipBin_amd.h @@ -144,7 +144,6 @@ const string& HipBinAmd::getHipLdFlags() const { void HipBinAmd::initializeHipLdFlags() { - string hipLibPath; string hipLdFlags; const string& hipClangPath = getCompilerPath(); // If $HIPCC clang++ is not compiled, use clang instead @@ -152,12 +151,6 @@ void HipBinAmd::initializeHipLdFlags() { if (!fs::exists(hipCC)) { hipLdFlags = "--driver-mode=g++"; } - hipLibPath = getHipLibPath(); - hipLdFlags += " -L\"" + hipLibPath + "\""; - const OsType& os = getOSInfo(); - if (os == windows) { - hipLdFlags += " -lamdhip64"; - } hipLdFlags_ = hipLdFlags; } @@ -364,17 +357,13 @@ bool HipBinAmd::detectPlatform() { string HipBinAmd::getHipLibPath() const { string hipLibPath; const EnvVariables& env = getEnvVariables(); - if (env.hipLibPathEnv_.empty()) { - const string& rocclrHomePath = getRocclrHomePath(); - fs::path libPath = rocclrHomePath; - libPath /= "lib"; - hipLibPath = libPath.string(); + if (!env.hipLibPathEnv_.empty()) { + hipLibPath = env.hipLibPathEnv_; } - if (hipLibPath.empty()) { - const string& hipPath = getHipPath(); - fs::path libPath = hipPath; - libPath /= "lib"; - hipLibPath = libPath.string(); + else if (!env.hipPathEnv_.empty()) { + fs::path p = env.hipLibPathEnv_; + p /= "lib"; + hipLibPath = p.string(); } return hipLibPath; } @@ -479,8 +468,6 @@ void HipBinAmd::executeHipCCCmd(vector argv) { 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 @@ -595,14 +582,13 @@ void HipBinAmd::executeHipCCCmd(vector argv) { compileOnly = 1; buildDeps = 1; } - if ((trimarg == "-use-staticlib") && (setLinkType == 0)) { - linkType = 0; - setLinkType = 1; - swallowArg = 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") && (setLinkType == 0)) { - linkType = 1; - setLinkType = 1; + 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; @@ -705,7 +691,7 @@ void HipBinAmd::executeHipCCCmd(vector argv) { // 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_=+,.\/]"); + regex reg("[^-a-zA-Z0-9_=+,.\\/]"); arg = regex_replace(arg, reg, "\\$&"); } if (!swallowArg) @@ -825,11 +811,6 @@ void HipBinAmd::executeHipCCCmd(vector argv) { if (buildDeps) { HIPCXXFLAGS += " --cuda-host-only"; } - // Add --hip-link only if it is compile only and -fgpu-rdc is on. - if (rdc && !compileOnly) { - HIPLDFLAGS += " --hip-link"; - HIPLDFLAGS += HIPLDARCHFLAGS; - } // hipcc currrently requires separate compilation of source files, // ie it is not possible to pass @@ -861,27 +842,21 @@ void HipBinAmd::executeHipCCCmd(vector argv) { HIPCXXFLAGS += hip_device_lib_str; } } - if (os != windows) { - HIPLDFLAGS += " -lgcc_s -lgcc -lpthread -lm -lrt"; - } - if (os != windows && !compileOnly) { - string hipClangVersion, toolArgTemp; - if (linkType == 0) { - toolArgTemp = " -L"+ hipLibPath + "-lamdhip64 -L" + - roccmPath+ "/lib -lhsa-runtime64 -ldl -lnuma " + toolArgs; - toolArgs = toolArgTemp; - } else { - toolArgTemp = toolArgs + " -Wl,-rpath=" + hipLibPath + ":" - + roccmPath+"/lib -lamdhip64 "; - toolArgs = toolArgTemp; + 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"; } - - hipClangVersion = getCompilerVersion(); - // To support __fp16 and _Float16, explicitly link with compiler-rt - toolArgs += " -L" + hipClangPath + "/../lib/clang/" + - hipClangVersion + "/lib/linux -lclang_rt.builtins-x86_64 "; } + if (!var.hipccCompileFlagsAppendEnv_.empty()) { HIPCXXFLAGS += " " + var.hipccCompileFlagsAppendEnv_ + " "; HIPCFLAGS += " " + var.hipccCompileFlagsAppendEnv_ + " "; diff --git a/amd/hipcc/src/hipBin_nvidia.h b/amd/hipcc/src/hipBin_nvidia.h index d9a7b38a1aaf73..b94e14710e4166 100644 --- a/amd/hipcc/src/hipBin_nvidia.h +++ b/amd/hipcc/src/hipBin_nvidia.h @@ -375,7 +375,9 @@ void HipBinNvidia::executeHipCCCmd(vector argv) { for (unsigned int i = 2; i < argv.size(); i++) { string isaarg = argv.at(i); ISACMD += " "; - ISACMD += isaarg; + if (!hipBinUtilPtr_->substringPresent(isaarg,"--rocm-path=")) { + ISACMD += isaarg; + } } if (verbose & 0x1) { cout<< "hipcc-cmd: " << ISACMD << "\n"; @@ -538,7 +540,7 @@ void HipBinNvidia::executeHipCCCmd(vector argv) { } // Windows needs different quoting, ignore for now if (os != windows && escapeArg) { - regex reg("[^-a-zA-Z0-9_=+,.\/]"); + regex reg("[^-a-zA-Z0-9_=+,.\\/]"); arg = regex_replace(arg, reg, "\\$&"); } if (!swallowArg) diff --git a/amd/hipcc/src/hipBin_util.h b/amd/hipcc/src/hipBin_util.h index e7d607989aa0f1..6bc8a250c1cc36 100644 --- a/amd/hipcc/src/hipBin_util.h +++ b/amd/hipcc/src/hipBin_util.h @@ -187,7 +187,7 @@ string HipBinUtil::mktempFile(string name) { #if defined(_WIN32) || defined(_WIN64) fileName = _mktemp(&name[0]); #else - fileName = mktemp(&name[0]); + fileName = mkdtemp(&name[0]); #endif tmpFiles_.push_back(fileName); return fileName;