diff --git a/amd/hipcc/.gitignore b/amd/hipcc/.gitignore new file mode 100644 index 00000000000000..17f1f1fd43525d --- /dev/null +++ b/amd/hipcc/.gitignore @@ -0,0 +1,7 @@ +# Merge files created by git. +*.orig +# Reject files created by patch. +*.rej + +# Nested build directory. +/build* diff --git a/amd/hipcc/CMakeLists.txt b/amd/hipcc/CMakeLists.txt index c21f2472f623a2..841b61b2498423 100644 --- a/amd/hipcc/CMakeLists.txt +++ b/amd/hipcc/CMakeLists.txt @@ -1,22 +1,114 @@ -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() -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 +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 "hip-dev, libfile-basedir-perl, libfile-copy-recursive-perl, libfile-listing-perl, libfile-which-perl, liburi-encode-perl, perl (>= 5.0), 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 "NCSA") +set(CPACK_RPM_PACKAGE_REQUIRES "hip-devel, perl >= 5.0, perl-File-BaseDir, perl-File-Listing, perl-File-Which, perl-URI-Encode, rocm-core, rocm-llvm") +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}") + +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin + DESTINATION . + USE_SOURCE_PERMISSIONS) +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() -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/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 100644 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 100644 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 100644 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/hipcc-backward-compat.cmake b/amd/hipcc/hipcc-backward-compat.cmake new file mode 100644 index 00000000000000..a38d26d320cc8a --- /dev/null +++ b/amd/hipcc/hipcc-backward-compat.cmake @@ -0,0 +1,42 @@ +# 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) diff --git a/amd/hipcc/src/hipBin_amd.h b/amd/hipcc/src/hipBin_amd.h index 9090586b281b84..21102bc4540631 100644 --- a/amd/hipcc/src/hipBin_amd.h +++ b/amd/hipcc/src/hipBin_amd.h @@ -712,7 +712,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) diff --git a/amd/hipcc/src/hipBin_nvidia.h b/amd/hipcc/src/hipBin_nvidia.h index 215be6fcca54e5..b94e14710e4166 100644 --- a/amd/hipcc/src/hipBin_nvidia.h +++ b/amd/hipcc/src/hipBin_nvidia.h @@ -540,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;