From ffe3f9cf81216a482dc295a685ab0132f988171b Mon Sep 17 00:00:00 2001 From: agunashe <86270081+agunashe@users.noreply.github.com> Date: Wed, 9 Feb 2022 08:17:45 -0800 Subject: [PATCH 1/4] SWDEV-273235 - hip change to build catch tests on Windows (#2472) * SWDEV-273235 - hip change to build catch tests on Windows Change-Id: I96de305694609c669cb81480f3572d987ce87d98 * SWDEV-1 - skip failing hipStreamPerThread_DeviceReset_1 test on Linux --- bin/hipcc.bat | 2 +- bin/hipconfig.bat | 2 +- tests/catch/CMakeLists.txt | 10 ++++++++-- tests/catch/hipTestMain/config/config_amd_linux.json | 7 +++++++ tests/catch/multiproc/CMakeLists.txt | 12 +++++------- tests/catch/unit/CMakeLists.txt | 6 ++---- tests/catch/unit/streamperthread/CMakeLists.txt | 8 +++----- 7 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 tests/catch/hipTestMain/config/config_amd_linux.json diff --git a/bin/hipcc.bat b/bin/hipcc.bat index 104e78622d..a19ce9d80f 100644 --- a/bin/hipcc.bat +++ b/bin/hipcc.bat @@ -1,2 +1,2 @@ -@IF DEFINED HIP_PATH (set HIPCC="%HIP_PATH%/bin/hipcc") ELSE (set HIPCC="%CD%/hipcc") +@IF DEFINED HIP_PATH (set HIPCC="%HIP_PATH%/bin/hipcc") ELSE (set HIPCC="%~dp0/hipcc") @perl %HIPCC% %* diff --git a/bin/hipconfig.bat b/bin/hipconfig.bat index 64db66aece..9ba2d4205c 100644 --- a/bin/hipconfig.bat +++ b/bin/hipconfig.bat @@ -1,2 +1,2 @@ -@IF DEFINED HIP_PATH (set HIPCONFIG="%HIP_PATH%/bin/hipconfig") ELSE (set HIPCONFIG="%CD%/hipconfig") +@IF DEFINED HIP_PATH (set HIPCONFIG="%HIP_PATH%/bin/hipconfig") ELSE (set HIPCONFIG="%~dp0/hipconfig") @perl %HIPCONFIG% %* diff --git a/tests/catch/CMakeLists.txt b/tests/catch/CMakeLists.txt index 67f5673d30..db9c0552ce 100644 --- a/tests/catch/CMakeLists.txt +++ b/tests/catch/CMakeLists.txt @@ -1,4 +1,9 @@ cmake_minimum_required(VERSION 3.16.8) + +# to skip the simple compiler test +set(CMAKE_C_COMPILER_WORKS 1) +set(CMAKE_CXX_COMPILER_WORKS 1) + project(hiptests) # Check if platform and compiler are set @@ -32,8 +37,10 @@ else() # Set both compilers else windows cmake complains of mismatch cmake_path(SET CMAKE_CXX_COMPILER "${HIP_PATH}/bin/hipcc.bat") cmake_path(SET CMAKE_C_COMPILER "${HIP_PATH}/bin/hipcc.bat") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${ROCM_PATH}") endif() + if(NOT DEFINED CATCH2_PATH) if(DEFINED ENV{CATCH2_PATH}) set(CATCH2_PATH $ENV{CATCH2_PATH} CACHE STRING "Catch2 Path") @@ -128,10 +135,9 @@ add_subdirectory(unit) add_subdirectory(ABM) add_subdirectory(hipTestMain) add_subdirectory(stress) - +add_subdirectory(TypeQualifiers) if(UNIX) add_subdirectory(multiproc) - add_subdirectory(TypeQualifiers) endif() cmake_policy(POP) diff --git a/tests/catch/hipTestMain/config/config_amd_linux.json b/tests/catch/hipTestMain/config/config_amd_linux.json new file mode 100644 index 0000000000..c11a1b823e --- /dev/null +++ b/tests/catch/hipTestMain/config/config_amd_linux.json @@ -0,0 +1,7 @@ +{ + "DisabledTests": + [ + "Unit_hipStreamPerThread_DeviceReset_1" + ] + +} diff --git a/tests/catch/multiproc/CMakeLists.txt b/tests/catch/multiproc/CMakeLists.txt index 78de21f674..8d690c6734 100644 --- a/tests/catch/multiproc/CMakeLists.txt +++ b/tests/catch/multiproc/CMakeLists.txt @@ -14,10 +14,8 @@ set(LINUX_TEST_SRC hipMemCoherencyTstMProc.cc ) -if(UNIX) - # the last argument linker libraries is required for this test but optional to the function - hip_add_exe_to_target(NAME MultiProc - TEST_SRC ${LINUX_TEST_SRC} - TEST_TARGET_NAME build_tests - LINKER_LIBS ${CMAKE_DL_LIBS}) -endif() +# the last argument linker libraries is required for this test but optional to the function +hip_add_exe_to_target(NAME MultiProc + TEST_SRC ${LINUX_TEST_SRC} + TEST_TARGET_NAME build_tests + LINKER_LIBS ${CMAKE_DL_LIBS}) diff --git a/tests/catch/unit/CMakeLists.txt b/tests/catch/unit/CMakeLists.txt index 0e8b37c993..ff8a0f95fe 100644 --- a/tests/catch/unit/CMakeLists.txt +++ b/tests/catch/unit/CMakeLists.txt @@ -21,7 +21,6 @@ add_subdirectory(memory) add_subdirectory(deviceLib) add_subdirectory(stream) -add_subdirectory(streamperthread) add_subdirectory(event) add_subdirectory(occupancy) add_subdirectory(device) @@ -29,6 +28,5 @@ add_subdirectory(rtc) add_subdirectory(printf) add_subdirectory(printfExe) add_subdirectory(texture) -if(UNIX) - add_subdirectory(graph) -endif() +add_subdirectory(streamperthread) +add_subdirectory(graph) diff --git a/tests/catch/unit/streamperthread/CMakeLists.txt b/tests/catch/unit/streamperthread/CMakeLists.txt index 51a789d426..a47e1e8c69 100644 --- a/tests/catch/unit/streamperthread/CMakeLists.txt +++ b/tests/catch/unit/streamperthread/CMakeLists.txt @@ -6,8 +6,6 @@ set(TEST_SRC hipStreamPerThread_DeviceReset.cc ) -# Create shared lib of all tests -add_library(StreamPerThreadTest SHARED EXCLUDE_FROM_ALL ${TEST_SRC}) - -# Add dependency on build_tests to build it on this custom target -add_dependencies(build_tests StreamPerThreadTest) +hip_add_exe_to_target(NAME StreamPerThreadTest + TEST_SRC ${TEST_SRC} + TEST_TARGET_NAME build_tests) From 0284dfb3bd51961695eb5bb737d17999a78f053a Mon Sep 17 00:00:00 2001 From: agunashe <86270081+agunashe@users.noreply.github.com> Date: Thu, 10 Feb 2022 08:27:05 -0800 Subject: [PATCH 2/4] SWDEV-1 - hip change for Windows applications hipInfo (#2471) BLDSPPT-3818 Change-Id: I624786a0d79678fbd850f0b8bedc7314731a77f4 --- samples/1_Utils/hipInfo/CMakeLists.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/samples/1_Utils/hipInfo/CMakeLists.txt b/samples/1_Utils/hipInfo/CMakeLists.txt index 4314467527..6192c8ecff 100644 --- a/samples/1_Utils/hipInfo/CMakeLists.txt +++ b/samples/1_Utils/hipInfo/CMakeLists.txt @@ -18,10 +18,18 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +# hipcc.bat fails to qualify as a valid compiler for CMAKE_CXX_COMPILER_ID = ROCMClang +# so the simple compiler test is skipped and forced to use hipcc.bat as compiler +set(CMAKE_C_COMPILER_WORKS 1) +set(CMAKE_CXX_COMPILER_WORKS 1) + project(hipInfo) cmake_minimum_required(VERSION 3.10) +# flag is set to ON in compute build for windows +option(HIPINFO_INTERNAL_BUILD "Enable building hipInfo from compute" OFF) + if (NOT DEFINED ROCM_PATH ) set ( ROCM_PATH "/opt/rocm" CACHE STRING "Default ROCM installation directory." ) endif () @@ -29,6 +37,12 @@ endif () # Search for rocm in common locations list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH}) +# need to set rocm_path for windows +# since clang and hip are two different folders during build/install step +if (WIN32 AND HIPINFO_INTERNAL_BUILD) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --rocm-path=${HIP_PATH}") +endif() + # Find hip find_package(hip) @@ -42,3 +56,10 @@ add_executable(hipInfo hipInfo.cpp) # Link with HIP target_link_libraries(hipInfo hip::host) + +# Used only when make install is called +# when hipInfo is built as part of compute project +# hipInfo.exe will be installed to install/hip/bin path +if (WIN32 AND HIPINFO_INTERNAL_BUILD) + install(FILES ${PROJECT_BINARY_DIR}/hipInfo.exe DESTINATION .) +endif() From c447b392d7181248fe3a241288690ed1140cb61b Mon Sep 17 00:00:00 2001 From: Konstantin Zhuravlyov Date: Thu, 10 Feb 2022 12:33:01 -0500 Subject: [PATCH 3/4] SWDEV-314372 - Refactor hipcc and hipconfig scripts (#2476) * SWDEV-314372 - Refactor hipcc and hipconfig scripts - Rename original hipcc to hipcc.pl - Rename original hipconfig to hipconfig.pl - New hipcc to invoke either hipcc.pl or hipcc.bin based on env var - New hipconfig to invoke either hipconfig.pl or hipconfig.bin based on env var * SWDEV-314372 - Add executable permissions to hipcc and hipconfig --- bin/hipcc | 767 ++-------------------------------------------- bin/hipcc.pl | 780 +++++++++++++++++++++++++++++++++++++++++++++++ bin/hipconfig | 242 +-------------- bin/hipconfig.pl | 257 ++++++++++++++++ 4 files changed, 1070 insertions(+), 976 deletions(-) create mode 100755 bin/hipcc.pl create mode 100755 bin/hipconfig.pl diff --git a/bin/hipcc b/bin/hipcc index 7b84067202..32494dd345 100755 --- a/bin/hipcc +++ b/bin/hipcc @@ -21,760 +21,27 @@ # Need perl > 5.10 to use logic-defined or use 5.006; use v5.10.1; + +use strict; use warnings; + use File::Basename; -use File::Temp qw/ :mktemp /; -use Cwd; -use Cwd 'abs_path'; +use File::Spec::Functions 'catfile'; -# 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. +# TODO: By default select perl script until change incorporated in HIP build script. +my $HIPCC_USE_PERL_SCRIPT = 1; -# 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. -# HSA_PATH : Path to HSA dir (defaults to ../../hsa relative to abs_path -# of this script). Used on AMD platforms only. -# HIP_ROCCLR_HOME : Path to HIP/ROCclr directory. Used on AMD platforms only. -# HIP_CLANG_PATH : Path to HIP-Clang (default to ../../llvm/bin relative to this -# script's abs_path). Used on AMD platforms only. - -if(scalar @ARGV == 0){ - print "No Arguments passed, exiting ...\n"; - exit(-1); -} - -$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__) ); -} -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; -$HSA_PATH = $hipvars::HSA_PATH; -$HIP_ROCCLR_HOME = $hipvars::HIP_ROCCLR_HOME; - -if ($HIP_PLATFORM eq "amd") { - # If using ROCclr runtime, need to find HIP_ROCCLR_HOME - if (!defined $DEVICE_LIB_PATH and -e "$HIP_ROCCLR_HOME/lib/bitcode") { - $DEVICE_LIB_PATH = "$HIP_ROCCLR_HOME/lib/bitcode"; - } - $HIP_INCLUDE_PATH = "$HIP_ROCCLR_HOME/include"; - if (!defined $HIP_LIB_PATH) { - $HIP_LIB_PATH = "$HIP_ROCCLR_HOME/lib"; - } - - if (!defined $DEVICE_LIB_PATH) { - if (-e "$ROCM_PATH/amdgcn/bitcode") { - $DEVICE_LIB_PATH = "$ROCM_PATH/amdgcn/bitcode"; - } - else { - # This path is to support an older build of the device library - # TODO: To be removed in the future. - $DEVICE_LIB_PATH = "$ROCM_PATH/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++"; - } - - $HIP_CLANG_VERSION = `$HIPCC --version`; - $HIP_CLANG_VERSION=~/.*clang version (\S+).*/; - $HIP_CLANG_VERSION=$1; - - # Figure out the target with which llvm is configured - $HIP_CLANG_TARGET = `$HIPCC -print-target-triple`; - $HIP_CLANG_TARGET = chomp($HIP_CLANG_TARGET); - - if (! defined $HIP_CLANG_INCLUDE_PATH) { - $HIP_CLANG_INCLUDE_PATH = abs_path("$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/include"); - } - 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_CLANG_INCLUDE_PATH=$HIP_CLANG_INCLUDE_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_TARGET=$HIP_CLANG_TARGET\n"); - } - - if ($isWindows) { - $HIPCXXFLAGS .= " -std=c++14 -fms-extensions -fms-compatibility"; - } else { - $HIPCXXFLAGS .= " -std=c++11"; - } - $HIPCXXFLAGS .= " -isystem \"$HIP_CLANG_INCLUDE_PATH/..\""; - $HIPCFLAGS .= " -isystem \"$HIP_CLANG_INCLUDE_PATH/..\""; - $HIPLDFLAGS .= " -L\"$HIP_LIB_PATH\""; - if ($isWindows) { - $HIPLDFLAGS .= " -lamdhip64"; - } - 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"; - } - - if (not $isWindows) { - $HSA_PATH=$ENV{'HSA_PATH'} // "$ROCM_PATH/hsa"; - $HIPCXXFLAGS .= " -isystem $HSA_PATH/include"; - $HIPCFLAGS .= " -isystem $HSA_PATH/include"; - } - -} 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"; +my $SCRIPT_DIR=dirname(__FILE__); +if ($HIPCC_USE_PERL_SCRIPT) { + #Invoke hipcc.pl + my $HIPCC_PERL=catfile($SCRIPT_DIR, '/hipcc.pl'); + exec($^X, $HIPCC_PERL, @ARGV); } 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 $linkType = 1; -my $setLinkType = 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 .= " "; - $ISACMD .= $isaarg; - } - if ($verbose & 0x1) { - print "hipcc-cmd: ", $ISACMD, "\n"; - } - system($ISACMD) and die(); - exit(0); + #Invoke hipcc.bin + my $HIPCC_BIN=catfile($SCRIPT_DIR, '/hipcc.bin'); + if ( -e $HIPCC_BIN ) { + exec($HIPCC_BIN, @ARGV); + } else { + print "hipcc.bin not present; Install HIPCC binaries before proceeding"; } } - -# 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 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_fast_math') { - $HIPCXXFLAGS .= " -DHIP_FAST_MATH "; - $HIPCFLAGS .= " -DHIP_FAST_MATH "; - } - if(($trimarg eq '-use-staticlib') and ($setLinkType eq 0)) - { - $linkType = 0; - $setLinkType = 1; - $swallowArg = 1; - } - if(($trimarg eq '-use-sharedlib') and ($setLinkType eq 0)) - { - $linkType = 1; - $setLinkType = 1; - } - if($arg =~ m/^-O/) - { - $optArg = $arg; - } - if($arg =~ '--amdhsa-code-object-version=') - { - $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; - } - - ## process linker response file for hip-clang - ## extract object files from static library and pass them directly to - ## hip-clang in command line. - ## ToDo: Remove this after hip-clang switch to lto and lld is able to - ## handle clang-offload-bundler bundles. - if (($arg =~ m/^-Wl,@/ or $arg =~ m/^@/) and - $HIP_PLATFORM eq 'amd') { - my @split_arg = (split /\@/, $arg); # arg will have options type(-Wl,@ or @) and filename - my $file = $split_arg[1]; - open my $in, "<:encoding(utf8)", $file or die "$file: $!"; - my $new_arg = ""; - my $tmpdir = get_temp_dir (); - my $new_file = "$tmpdir/response_file"; - open my $out, ">", $new_file or die "$new_file: $!"; - while (my $line = <$in>) { - chomp $line; - if ($line =~ m/\.a$/ || $line =~ m/\.lo$/) { - my $libFile = $line; - my $path = abs_path($line); - my @objs = split ('\n', `cd $tmpdir; ar xv $path`); - ## Check if all files in .a are object files. - my $allIsObj = 1; - my $realObjs = ""; - foreach my $obj (@objs) { - chomp $obj; - $obj =~ s/^x - //; - $obj = "$tmpdir/$obj"; - my $fileType = `file $obj`; - my $isObj = ($fileType =~ m/ELF/ or $fileType =~ m/COFF/); - $allIsObj = ($allIsObj and $isObj); - if ($isObj) { - $realObjs = ($realObjs . " " . $obj); - } else { - push (@inputs, $obj); - $new_arg = "$new_arg $obj"; - } - } - chomp $realObjs; - if ($allIsObj) { - print $out "$line\n"; - } elsif ($realObjs) { - my($libBaseName, $libDir, $libExt) = fileparse($libFile); - $libBaseName = mktemp($libBaseName . "XXXX") . $libExt; - system("cd $tmpdir; ar rc $libBaseName $realObjs"); - print $out "$tmpdir/$libBaseName\n"; - } - } elsif ($line =~ m/\.o$/) { - my $fileType = `file $line`; - my $isObj = ($fileType =~ m/ELF/ or $fileType =~ m/COFF/); - if ($isObj) { - print $out "$line\n"; - } else { - push (@inputs, $line); - $new_arg = "$new_arg $line"; - } - } else { - print $out "$line\n"; - } - } - close $in; - close $out; - $arg = "$new_arg $split_arg[0]\@$new_file"; - $escapeArg = 0; - } elsif (($arg =~ m/\.a$/ || $arg =~ m/\.lo$/) && - $HIP_PLATFORM eq 'amd') { - ## process static library for hip-clang - ## extract object files from static library and pass them directly to - ## hip-clang. - ## ToDo: Remove this after hip-clang switch to lto and lld is able to - ## handle clang-offload-bundler bundles. - my $new_arg = ""; - my $tmpdir = get_temp_dir (); - my $libFile = $arg; - my $path = abs_path($arg); - my @objs = split ('\n', `cd $tmpdir; ar xv $path`); - ## Check if all files in .a are object files. - my $allIsObj = 1; - my $realObjs = ""; - foreach my $obj (@objs) { - chomp $obj; - $obj =~ s/^x - //; - $obj = "$tmpdir/$obj"; - my $fileType = `file $obj`; - my $isObj = ($fileType =~ m/ELF/ or $fileType =~ m/COFF/); - if ($fileType =~ m/ELF/) { - my $sections = `readelf -e -W $obj`; - $isObj = !($sections =~ m/__CLANG_OFFLOAD_BUNDLE__/); - } - $allIsObj = ($allIsObj and $isObj); - if ($isObj) { - $realObjs = ($realObjs . " " . $obj); - } else { - push (@inputs, $obj); - if ($new_arg ne "") { - $new_arg .= " "; - } - $new_arg .= "$obj"; - } - } - chomp $realObjs; - if ($allIsObj) { - $new_arg = $arg; - } elsif ($realObjs) { - my($libBaseName, $libDir, $libExt) = fileparse($libFile); - $libBaseName = mktemp($libBaseName . "XXXX") . $libExt; - system("cd $tmpdir; ar rc $libBaseName $realObjs"); - $new_arg .= " $tmpdir/$libBaseName"; - } - $arg = "$new_arg"; - $escapeArg = 0; - if ($toolArgs =~ m/-Xlinker$/) { - $toolArgs = substr $toolArgs, 0, -8; - chomp $toolArgs; - } - } elsif ($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_profile") { # Example argument here, hipcc - # - #} - if ($arg eq "--hipcc-func-supp") { - $funcSupp = 1; - } elsif ($arg eq "--hipcc-no-func-supp") { - $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) { # Windows needs different quoting, ignore for now - $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"; -} - -# Add --hip-link only if it is compile only and -fgpu-rdc is on. -if ($rdc and !$compileOnly and $HIP_PLATFORM eq 'amd') { - $HIPLDFLAGS .= " --hip-link"; - $HIPLDFLAGS .= $HIPLDARCHFLAGS; -} - -# 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 ($hasHIP) { - if ($DEVICE_LIB_PATH ne "$ROCM_PATH/amdgcn/bitcode") { - $HIPCXXFLAGS .= " --hip-device-lib-path=\"$DEVICE_LIB_PATH\""; - } - $HIPCXXFLAGS .= " -fhip-new-launch-api"; - } - if (not $isWindows) { - $HIPLDFLAGS .= " -lgcc_s -lgcc -lpthread -lm -lrt"; - } - - if (not $isWindows and not $compileOnly) { - if ($linkType eq 0) { - $toolArgs = " -L$HIP_LIB_PATH -lamdhip64 -L$ROCM_PATH/lib -lhsa-runtime64 -ldl -lnuma " . ${toolArgs}; - } else { - $toolArgs = " -Wl,--enable-new-dtags -Wl,-rpath=$HIP_LIB_PATH:$ROCM_PATH/lib -lamdhip64 " . ${toolArgs}; - } - # To support __fp16 and _Float16, explicitly link with compiler-rt - $HIP_CLANG_BUILTIN_LIB="$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/lib/$HIP_CLANG_TARGET/libclang_rt.builtins.a"; - if (-e $HIP_CLANG_BUILTIN_LIB) { - $toolArgs .= " -L$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/lib/$HIP_CLANG_TARGET -lclang_rt.builtins " - } else { - $toolArgs .= " -L$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/lib/linux -lclang_rt.builtins-x86_64 " - } - } -} - -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/bin/hipcc.pl b/bin/hipcc.pl new file mode 100755 index 0000000000..7b84067202 --- /dev/null +++ b/bin/hipcc.pl @@ -0,0 +1,780 @@ +#!/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. +# HSA_PATH : Path to HSA dir (defaults to ../../hsa relative to abs_path +# of this script). Used on AMD platforms only. +# HIP_ROCCLR_HOME : Path to HIP/ROCclr directory. Used on AMD platforms only. +# HIP_CLANG_PATH : Path to HIP-Clang (default to ../../llvm/bin relative to this +# script's abs_path). Used on AMD platforms only. + +if(scalar @ARGV == 0){ + print "No Arguments passed, exiting ...\n"; + exit(-1); +} + +$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__) ); +} +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; +$HSA_PATH = $hipvars::HSA_PATH; +$HIP_ROCCLR_HOME = $hipvars::HIP_ROCCLR_HOME; + +if ($HIP_PLATFORM eq "amd") { + # If using ROCclr runtime, need to find HIP_ROCCLR_HOME + if (!defined $DEVICE_LIB_PATH and -e "$HIP_ROCCLR_HOME/lib/bitcode") { + $DEVICE_LIB_PATH = "$HIP_ROCCLR_HOME/lib/bitcode"; + } + $HIP_INCLUDE_PATH = "$HIP_ROCCLR_HOME/include"; + if (!defined $HIP_LIB_PATH) { + $HIP_LIB_PATH = "$HIP_ROCCLR_HOME/lib"; + } + + if (!defined $DEVICE_LIB_PATH) { + if (-e "$ROCM_PATH/amdgcn/bitcode") { + $DEVICE_LIB_PATH = "$ROCM_PATH/amdgcn/bitcode"; + } + else { + # This path is to support an older build of the device library + # TODO: To be removed in the future. + $DEVICE_LIB_PATH = "$ROCM_PATH/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++"; + } + + $HIP_CLANG_VERSION = `$HIPCC --version`; + $HIP_CLANG_VERSION=~/.*clang version (\S+).*/; + $HIP_CLANG_VERSION=$1; + + # Figure out the target with which llvm is configured + $HIP_CLANG_TARGET = `$HIPCC -print-target-triple`; + $HIP_CLANG_TARGET = chomp($HIP_CLANG_TARGET); + + if (! defined $HIP_CLANG_INCLUDE_PATH) { + $HIP_CLANG_INCLUDE_PATH = abs_path("$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/include"); + } + 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_CLANG_INCLUDE_PATH=$HIP_CLANG_INCLUDE_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_TARGET=$HIP_CLANG_TARGET\n"); + } + + if ($isWindows) { + $HIPCXXFLAGS .= " -std=c++14 -fms-extensions -fms-compatibility"; + } else { + $HIPCXXFLAGS .= " -std=c++11"; + } + $HIPCXXFLAGS .= " -isystem \"$HIP_CLANG_INCLUDE_PATH/..\""; + $HIPCFLAGS .= " -isystem \"$HIP_CLANG_INCLUDE_PATH/..\""; + $HIPLDFLAGS .= " -L\"$HIP_LIB_PATH\""; + if ($isWindows) { + $HIPLDFLAGS .= " -lamdhip64"; + } + 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"; + } + + if (not $isWindows) { + $HSA_PATH=$ENV{'HSA_PATH'} // "$ROCM_PATH/hsa"; + $HIPCXXFLAGS .= " -isystem $HSA_PATH/include"; + $HIPCFLAGS .= " -isystem $HSA_PATH/include"; + } + +} 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 $linkType = 1; +my $setLinkType = 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 .= " "; + $ISACMD .= $isaarg; + } + 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 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_fast_math') { + $HIPCXXFLAGS .= " -DHIP_FAST_MATH "; + $HIPCFLAGS .= " -DHIP_FAST_MATH "; + } + if(($trimarg eq '-use-staticlib') and ($setLinkType eq 0)) + { + $linkType = 0; + $setLinkType = 1; + $swallowArg = 1; + } + if(($trimarg eq '-use-sharedlib') and ($setLinkType eq 0)) + { + $linkType = 1; + $setLinkType = 1; + } + if($arg =~ m/^-O/) + { + $optArg = $arg; + } + if($arg =~ '--amdhsa-code-object-version=') + { + $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; + } + + ## process linker response file for hip-clang + ## extract object files from static library and pass them directly to + ## hip-clang in command line. + ## ToDo: Remove this after hip-clang switch to lto and lld is able to + ## handle clang-offload-bundler bundles. + if (($arg =~ m/^-Wl,@/ or $arg =~ m/^@/) and + $HIP_PLATFORM eq 'amd') { + my @split_arg = (split /\@/, $arg); # arg will have options type(-Wl,@ or @) and filename + my $file = $split_arg[1]; + open my $in, "<:encoding(utf8)", $file or die "$file: $!"; + my $new_arg = ""; + my $tmpdir = get_temp_dir (); + my $new_file = "$tmpdir/response_file"; + open my $out, ">", $new_file or die "$new_file: $!"; + while (my $line = <$in>) { + chomp $line; + if ($line =~ m/\.a$/ || $line =~ m/\.lo$/) { + my $libFile = $line; + my $path = abs_path($line); + my @objs = split ('\n', `cd $tmpdir; ar xv $path`); + ## Check if all files in .a are object files. + my $allIsObj = 1; + my $realObjs = ""; + foreach my $obj (@objs) { + chomp $obj; + $obj =~ s/^x - //; + $obj = "$tmpdir/$obj"; + my $fileType = `file $obj`; + my $isObj = ($fileType =~ m/ELF/ or $fileType =~ m/COFF/); + $allIsObj = ($allIsObj and $isObj); + if ($isObj) { + $realObjs = ($realObjs . " " . $obj); + } else { + push (@inputs, $obj); + $new_arg = "$new_arg $obj"; + } + } + chomp $realObjs; + if ($allIsObj) { + print $out "$line\n"; + } elsif ($realObjs) { + my($libBaseName, $libDir, $libExt) = fileparse($libFile); + $libBaseName = mktemp($libBaseName . "XXXX") . $libExt; + system("cd $tmpdir; ar rc $libBaseName $realObjs"); + print $out "$tmpdir/$libBaseName\n"; + } + } elsif ($line =~ m/\.o$/) { + my $fileType = `file $line`; + my $isObj = ($fileType =~ m/ELF/ or $fileType =~ m/COFF/); + if ($isObj) { + print $out "$line\n"; + } else { + push (@inputs, $line); + $new_arg = "$new_arg $line"; + } + } else { + print $out "$line\n"; + } + } + close $in; + close $out; + $arg = "$new_arg $split_arg[0]\@$new_file"; + $escapeArg = 0; + } elsif (($arg =~ m/\.a$/ || $arg =~ m/\.lo$/) && + $HIP_PLATFORM eq 'amd') { + ## process static library for hip-clang + ## extract object files from static library and pass them directly to + ## hip-clang. + ## ToDo: Remove this after hip-clang switch to lto and lld is able to + ## handle clang-offload-bundler bundles. + my $new_arg = ""; + my $tmpdir = get_temp_dir (); + my $libFile = $arg; + my $path = abs_path($arg); + my @objs = split ('\n', `cd $tmpdir; ar xv $path`); + ## Check if all files in .a are object files. + my $allIsObj = 1; + my $realObjs = ""; + foreach my $obj (@objs) { + chomp $obj; + $obj =~ s/^x - //; + $obj = "$tmpdir/$obj"; + my $fileType = `file $obj`; + my $isObj = ($fileType =~ m/ELF/ or $fileType =~ m/COFF/); + if ($fileType =~ m/ELF/) { + my $sections = `readelf -e -W $obj`; + $isObj = !($sections =~ m/__CLANG_OFFLOAD_BUNDLE__/); + } + $allIsObj = ($allIsObj and $isObj); + if ($isObj) { + $realObjs = ($realObjs . " " . $obj); + } else { + push (@inputs, $obj); + if ($new_arg ne "") { + $new_arg .= " "; + } + $new_arg .= "$obj"; + } + } + chomp $realObjs; + if ($allIsObj) { + $new_arg = $arg; + } elsif ($realObjs) { + my($libBaseName, $libDir, $libExt) = fileparse($libFile); + $libBaseName = mktemp($libBaseName . "XXXX") . $libExt; + system("cd $tmpdir; ar rc $libBaseName $realObjs"); + $new_arg .= " $tmpdir/$libBaseName"; + } + $arg = "$new_arg"; + $escapeArg = 0; + if ($toolArgs =~ m/-Xlinker$/) { + $toolArgs = substr $toolArgs, 0, -8; + chomp $toolArgs; + } + } elsif ($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_profile") { # Example argument here, hipcc + # + #} + if ($arg eq "--hipcc-func-supp") { + $funcSupp = 1; + } elsif ($arg eq "--hipcc-no-func-supp") { + $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) { # Windows needs different quoting, ignore for now + $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"; +} + +# Add --hip-link only if it is compile only and -fgpu-rdc is on. +if ($rdc and !$compileOnly and $HIP_PLATFORM eq 'amd') { + $HIPLDFLAGS .= " --hip-link"; + $HIPLDFLAGS .= $HIPLDARCHFLAGS; +} + +# 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 ($hasHIP) { + if ($DEVICE_LIB_PATH ne "$ROCM_PATH/amdgcn/bitcode") { + $HIPCXXFLAGS .= " --hip-device-lib-path=\"$DEVICE_LIB_PATH\""; + } + $HIPCXXFLAGS .= " -fhip-new-launch-api"; + } + if (not $isWindows) { + $HIPLDFLAGS .= " -lgcc_s -lgcc -lpthread -lm -lrt"; + } + + if (not $isWindows and not $compileOnly) { + if ($linkType eq 0) { + $toolArgs = " -L$HIP_LIB_PATH -lamdhip64 -L$ROCM_PATH/lib -lhsa-runtime64 -ldl -lnuma " . ${toolArgs}; + } else { + $toolArgs = " -Wl,--enable-new-dtags -Wl,-rpath=$HIP_LIB_PATH:$ROCM_PATH/lib -lamdhip64 " . ${toolArgs}; + } + # To support __fp16 and _Float16, explicitly link with compiler-rt + $HIP_CLANG_BUILTIN_LIB="$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/lib/$HIP_CLANG_TARGET/libclang_rt.builtins.a"; + if (-e $HIP_CLANG_BUILTIN_LIB) { + $toolArgs .= " -L$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/lib/$HIP_CLANG_TARGET -lclang_rt.builtins " + } else { + $toolArgs .= " -L$HIP_CLANG_PATH/../lib/clang/$HIP_CLANG_VERSION/lib/linux -lclang_rt.builtins-x86_64 " + } + } +} + +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/bin/hipconfig b/bin/hipconfig index 5ddb8e9b7d..8ed1ba6f10 100755 --- a/bin/hipconfig +++ b/bin/hipconfig @@ -21,237 +21,27 @@ # Need perl > 5.10 to use logic-defined or use 5.006; use v5.10.1; + +use strict; use warnings; -use Getopt::Long; -use Cwd; -# Return name of HIP compiler - either 'clang' or 'nvcc' -# -use Getopt::Long; use File::Basename; +use File::Spec::Functions 'catfile'; -my $base_dir; -BEGIN { - $base_dir = dirname( Cwd::realpath(__FILE__) ); -} -use lib "$base_dir/"; -use hipvars; +#TODO: By default select perl script until change incorporated in HIP build script +my $HIPCONFIG_USE_PERL_SCRIPT = 1; -$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; -$HSA_PATH = $hipvars::HSA_PATH; - -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`; +my $SCRIPT_DIR=dirname(__FILE__); +if ($HIPCONFIG_USE_PERL_SCRIPT) { + #Invoke hipconfig.pl + my $HIPCONFIG_PERL=catfile($SCRIPT_DIR, '/hipconfig.pl'); + exec($^X, $HIPCONFIG_PERL, @ARGV); +} else { + #Invoke hipconfig.bin + my $HIPCONFIG_BIN=catfile($SCRIPT_DIR, '/hipconfig.bin'); + if ( -e $HIPCONFIG_BIN ) { + exec($HIPCONFIG_BIN, @ARGV); } 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 -I$HSA_PATH/include"; + print "hipconfig.bin not present; Install HIPCC binaries before proceeding"; } } -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"; - if (not $isWindows) { - print ("HSA_PATH : $HSA_PATH\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:\"HSA\" //C:\"CUDA\" //C:\"LD_LIBRARY_PATH\""); - } else { - system("echo PATH=\$PATH"); - system("env | egrep '^HIP|^HSA|^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 ($HIP_PLATFORM eq "amd") { - $LD_LIBRARY_PATH=$ENV{'LD_LIBRARY_PATH'}; - printf("%-70s", "check LD_LIBRARY_PATH ($LD_LIBRARY_PATH) contains HSA_PATH ($HSA_PATH)..."); - if (index($LD_LIBRARY_PATH, $HSA_PATH) == -1) { - print "FAIL\n"; - } else { - printf "good\n"; - } - - # TODO - check hipcc / nvcc found and executable. - } -} - -if ($p_newline) { - print "\n"; -} diff --git a/bin/hipconfig.pl b/bin/hipconfig.pl new file mode 100755 index 0000000000..5ddb8e9b7d --- /dev/null +++ b/bin/hipconfig.pl @@ -0,0 +1,257 @@ +#!/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; +$HSA_PATH = $hipvars::HSA_PATH; + +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 -I$HSA_PATH/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"; + if (not $isWindows) { + print ("HSA_PATH : $HSA_PATH\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:\"HSA\" //C:\"CUDA\" //C:\"LD_LIBRARY_PATH\""); + } else { + system("echo PATH=\$PATH"); + system("env | egrep '^HIP|^HSA|^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 ($HIP_PLATFORM eq "amd") { + $LD_LIBRARY_PATH=$ENV{'LD_LIBRARY_PATH'}; + printf("%-70s", "check LD_LIBRARY_PATH ($LD_LIBRARY_PATH) contains HSA_PATH ($HSA_PATH)..."); + if (index($LD_LIBRARY_PATH, $HSA_PATH) == -1) { + print "FAIL\n"; + } else { + printf "good\n"; + } + + # TODO - check hipcc / nvcc found and executable. + } +} + +if ($p_newline) { + print "\n"; +} From 09583b01835af26bc94d917364ac100e03424adc Mon Sep 17 00:00:00 2001 From: haoyuan2 <98923620+haoyuan2@users.noreply.github.com> Date: Thu, 10 Feb 2022 11:00:25 -0800 Subject: [PATCH 4/4] SWDEV-316128 - HIP surface API support (#2468) --- include/hip/surface_types.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/hip/surface_types.h b/include/hip/surface_types.h index 42a91a5f0b..c7f588de09 100644 --- a/include/hip/surface_types.h +++ b/include/hip/surface_types.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. +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 @@ -30,7 +30,8 @@ THE SOFTWARE. /** * An opaque value that represents a hip surface object */ -typedef unsigned long long hipSurfaceObject_t; +struct __hip_surface; +typedef struct __hip_surface* hipSurfaceObject_t; /** * hip surface reference