3bc69394d0
* FBA-29, FBA-69, multiple rocm support, shared library conflicts Changes to resolve: 1) Multiple rocm release installation support 2) Multiple rocm shared lib conflicts 3) Add the so versioning also
957 خطوط
30 KiB
Perl
Executable File
957 خطوط
30 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
|
|
# Need perl > 5.10 to use logic-defined or
|
|
use 5.006; use v5.10.1;
|
|
use File::Basename;
|
|
use File::Temp qw/ :mktemp /;
|
|
use Cwd;
|
|
use Cwd 'abs_path';
|
|
|
|
# HIP compiler driver
|
|
# Will call NVCC or HCC (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 control compilation path:
|
|
# HIP_PLATFORM='nvcc' or HIP_PLATFORM='hcc'.
|
|
# 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.
|
|
# HCC_HOME : Path to HCC SDK (defaults to ../../hcc relative to this
|
|
# script's abs_path). Used on AMD platforms only.
|
|
# HSA_PATH : Path to HSA dir (defaults to ../../hsa relative to abs_path
|
|
# of this script). Used on AMD platforms only.
|
|
# HIP_VDI_HOME : Path to HIP/VDI directory. Used on AMD platforms only.
|
|
|
|
if(scalar @ARGV == 0){
|
|
print "No Arguments passed, exiting ...\n";
|
|
exit(-1);
|
|
}
|
|
|
|
#---
|
|
# Function to parse config file
|
|
sub parse_config_file {
|
|
my ($file, $config) = @_;
|
|
if (open (CONFIG, "$file")) {
|
|
while (<CONFIG>) {
|
|
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);
|
|
}
|
|
}
|
|
|
|
$verbose = $ENV{'HIPCC_VERBOSE'} // 0;
|
|
# Verbose: 0x1=commands, 0x2=paths, 0x4=hipcc args
|
|
|
|
$isWindows = $^O eq 'MSWin32';
|
|
|
|
$HIPCC_COMPILE_FLAGS_APPEND=$ENV{'HIPCC_COMPILE_FLAGS_APPEND'};
|
|
$HIPCC_LINK_FLAGS_APPEND=$ENV{'HIPCC_LINK_FLAGS_APPEND'};
|
|
|
|
#
|
|
# 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 <rocm_install_dir> is determined based on whether
|
|
# we find .info/version 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/../.info/version") {
|
|
$ROCM_PATH=$ENV{'ROCM_PATH'} // dirname("$HIP_PATH"); # use parent directory of HIP_PATH
|
|
} else {
|
|
$ROCM_PATH=$ENV{'ROCM_PATH'} // "/opt/rocm";
|
|
}
|
|
$HIP_VDI_HOME=$ENV{'HIP_VDI_HOME'};
|
|
$HIP_LIB_PATH=$ENV{'HIP_LIB_PATH'};
|
|
$HIP_CLANG_PATH=$ENV{'HIP_CLANG_PATH'};
|
|
$DEVICE_LIB_PATH=$ENV{'DEVICE_LIB_PATH'};
|
|
$HIP_CLANG_HCC_COMPAT_MODE=$ENV{'HIP_CLANG_HCC_COMPAT_MODE'}; # HCC compatibility mode
|
|
|
|
if (defined $HIP_VDI_HOME) {
|
|
$HIP_INFO_PATH= "$HIP_VDI_HOME/lib/.hipInfo";
|
|
} else {
|
|
$HIP_INFO_PATH= "$HIP_PATH/lib/.hipInfo"; # use actual file
|
|
}
|
|
|
|
#---
|
|
# Read .hipInfo
|
|
my %hipConfig = ();
|
|
parse_config_file("$HIP_INFO_PATH", \%hipConfig);
|
|
|
|
#---
|
|
# 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;
|
|
}
|
|
|
|
#---
|
|
#HIP_PLATFORM controls whether to use NVCC or HCC for compilation:
|
|
$HIP_PLATFORM= `$HIP_PATH/bin/hipconfig --platform` // "hcc";
|
|
$HIP_VERSION= `$HIP_PATH/bin/hipconfig --version`;
|
|
$HIP_COMPILER= $hipConfig{'HIP_COMPILER'};
|
|
$HIP_RUNTIME= $hipConfig{'HIP_RUNTIME'};
|
|
|
|
# If using VDI runtime, need to find HIP_VDI_HOME
|
|
if (defined $HIP_RUNTIME and $HIP_RUNTIME eq "VDI" and !defined $HIP_VDI_HOME) {
|
|
my $hipcc_dir = dirname($0);
|
|
if (-e "$hipcc_dir/../lib/bitcode") {
|
|
$HIP_VDI_HOME = abs_path($hipcc_dir . "/..");
|
|
} else {
|
|
$HIP_VDI_HOME = $HIP_PATH; # use HIP_PATH
|
|
}
|
|
}
|
|
|
|
if (defined $HIP_VDI_HOME) {
|
|
if (!defined $HIP_CLANG_PATH and (-e "$HIP_VDI_HOME/bin/clang" or -e "$HIP_VDI_HOME/bin/clang.exe")) {
|
|
$HIP_CLANG_PATH = "$HIP_VDI_HOME/bin";
|
|
# With HIP_VDI_HOME defined, assume the installation of clang components, including headers.
|
|
if (!defined $HIP_CLANG_INCLUDE_PATH) {
|
|
$HIP_CLANG_INCLUDE_PATH = "$HIP_VDI_HOME/include/clang";
|
|
}
|
|
}
|
|
if (!defined $DEVICE_LIB_PATH and -e "$HIP_VDI_HOME/lib/bitcode") {
|
|
$DEVICE_LIB_PATH = "$HIP_VDI_HOME/lib/bitcode";
|
|
}
|
|
$HIP_INCLUDE_PATH = "$HIP_VDI_HOME/include";
|
|
if (!defined $HIP_LIB_PATH) {
|
|
$HIP_LIB_PATH = "$HIP_VDI_HOME/lib";
|
|
}
|
|
}
|
|
|
|
if (defined $HIP_COMPILER and $HIP_COMPILER eq "clang") {
|
|
$HIP_PLATFORM = "clang";
|
|
if (!defined $HIP_CLANG_PATH) {
|
|
$HIP_CLANG_PATH = "$ROCM_PATH/llvm/bin";
|
|
}
|
|
if (!defined $DEVICE_LIB_PATH) {
|
|
$DEVICE_LIB_PATH = "$ROCM_PATH/lib";
|
|
}
|
|
}
|
|
|
|
if ($verbose & 0x2) {
|
|
print ("HIP_PATH=$HIP_PATH\n");
|
|
print ("HIP_PLATFORM=$HIP_PLATFORM\n");
|
|
}
|
|
|
|
# set if user explicitly requests -stdlib=libc++. (else we default to libstdc++ for better interop with g++):
|
|
$setStdLib = 0; # TODO - set to 0
|
|
|
|
$target_gfx701 = 0;
|
|
$target_gfx801 = 0;
|
|
$target_gfx802 = 0;
|
|
$target_gfx803 = 0;
|
|
$target_gfx900 = 0;
|
|
$target_gfx906 = 0;
|
|
$target_gfx908 = 0;
|
|
$target_gfx1010 = 0;
|
|
$target_gfx1012 = 0;
|
|
$default_amdgpu_target = 1;
|
|
|
|
if ($HIP_PLATFORM eq "clang") {
|
|
$HIPCC="$HIP_CLANG_PATH/clang++";
|
|
|
|
# If $HIPCC clang++ is not compiled, use clang instead
|
|
if ( ! -e $HIPCC ) {
|
|
$HIPCC="$HIP_CLANG_PATH/clang";
|
|
$HIPLDFLAGS = "--driver-mode=g++";
|
|
}
|
|
|
|
$HIP_CLANG_VERSION = `$HIPCC --version`;
|
|
$HIP_CLANG_VERSION=~/.*clang version ([^ ]+).*/;
|
|
$HIP_CLANG_VERSION=$1;
|
|
|
|
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) {
|
|
if (defined $HIP_VDI_HOME) {
|
|
print ("HIP_VDI_HOME=$HIP_VDI_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");
|
|
}
|
|
|
|
if ($isWindows) {
|
|
$HIPCXXFLAGS .= " -std=c++14 -fms-extensions -fms-compatibility";
|
|
} else {
|
|
$HIPCXXFLAGS .= " -std=c++11";
|
|
}
|
|
$HIPCXXFLAGS .= " -isystem $HIP_CLANG_INCLUDE_PATH";
|
|
$HIPLDFLAGS .= " -L$HIP_LIB_PATH";
|
|
if (not $isWindows) {
|
|
$HIPLDFLAGS .= " -Wl,--rpath-link=$HIP_LIB_PATH";
|
|
$HIPLDFLAGS .= " -lhip_hcc";
|
|
} else {
|
|
$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 ($HIP_RUNTIME eq "HCC" ) {
|
|
$HSA_PATH=$ENV{'HSA_PATH'} // "$ROCM_PATH/hsa";
|
|
$HIPCXXFLAGS .= " -isystem $HSA_PATH/include";
|
|
} else {
|
|
$HIPCXXFLAGS .= " -fhip-new-launch-api";
|
|
}
|
|
|
|
} elsif ($HIP_PLATFORM eq "hcc") {
|
|
$HIP_INCLUDE_PATH = "$HIP_PATH/include";
|
|
if (! defined $HIP_LIB_PATH) {
|
|
$HIP_LIB_PATH = "$HIP_PATH/lib";
|
|
}
|
|
$HSA_PATH=$ENV{'HSA_PATH'} // "$ROCM_PATH/hsa";
|
|
|
|
$HCC_HOME=$ENV{'HCC_HOME'} // $hipConfig{'HCC_HOME'} // "$ROCM_PATH/hcc";
|
|
|
|
$HCC_VERSION=`${HCC_HOME}/bin/hcc --version`;
|
|
$HCC_VERSION=~/.*based on HCC ([^ ]+).*/;
|
|
$HCC_VERSION=$1;
|
|
$HCC_VERSION_MAJOR=$HCC_VERSION;
|
|
$HCC_VERSION_MAJOR=~s/\..*//;
|
|
|
|
$HIP_ATP_MARKER=$ENV{'HIP_ATP_MARKER'} // 1;
|
|
$marker_path = "$ROCM_PATH/profiler/CXLActivityLogger";
|
|
|
|
# HCC* may be used to compile src/hip_hcc.o (and also feed the HIPCXXFLAGS below)
|
|
$HCC = "$HCC_HOME/bin/hcc";
|
|
$HCCFLAGS = "-hc -D__HIPCC__ -isystem $HCC_HOME/include ";
|
|
|
|
$HIPCC=$HCC;
|
|
$HIPCXXFLAGS = $HCCFLAGS;
|
|
|
|
$HIPLDFLAGS = `${HCC_HOME}/bin/hcc-config --ldflags`;
|
|
|
|
#### GCC system includes workaround ####
|
|
$HCC_WA_FLAGS = " ";
|
|
$HOST_OSNAME= `cat /etc/os-release | grep "^ID\=" | cut -d= -f2 | tr -d '\n'`;
|
|
if ($HCC_VERSION_MAJOR eq 1) {
|
|
my $GCC_CUR_VER = `gcc -dumpversion`;
|
|
my $GPP_CUR_VER = `g++ -dumpversion`;
|
|
$GCC_CUR_VER =~ s/\R//g;
|
|
$GPP_CUR_VER =~ s/\R//g;
|
|
|
|
my @GPP_VER_FIELDS = split('\.', $GPP_CUR_VER);
|
|
|
|
# Only include the libstdc++ headers and libraries flags explicitly if the g++ is older than version 5.
|
|
# That's because HCC already uses libstdc++ by default if a newer g++/libstdc++ is available
|
|
# Cent OS 7 and RHEL 7.4 cannot use libstdc++ for compilation, default to libc++
|
|
if (${GCC_CUR_VER} eq ${GPP_CUR_VER} and $GPP_VER_FIELDS[0] < 5 and ($HOST_OSNAME ne "\"centos\"") and ($HOST_OSNAME ne "\"rhel\"")) {
|
|
$HCC_WA_FLAGS .= " -stdlib=libstdc++ -isystem /usr/include/x86_64-linux-gnu -isystem /usr/include/x86_64-linux-gnu/c++/${GCC_CUR_VER} -isystem /usr/include/c++/${GCC_CUR_VER} ";
|
|
# Add C++ libs for GCC.
|
|
$HIPLDFLAGS .= " -lstdc++";
|
|
}
|
|
}
|
|
|
|
# Force -stdlib=libc++ on UB14.04
|
|
$HOST_OSVER= `cat /etc/os-release | grep "^VERSION_ID\=" | cut -d= -f2 | tr -d '\n'`;
|
|
if ($HOST_OSNAME eq "ubuntu" and $HOST_OSVER eq "\"14.04\"") {
|
|
$HIPCXXFLAGS .= " -stdlib=libc++";
|
|
$setStdLib = 1;
|
|
}
|
|
|
|
$HIPCXXFLAGS .= " -isystem $HIP_PATH/include/hip/hcc_detail/cuda";
|
|
$HIPCXXFLAGS .= " -isystem $HSA_PATH/include";
|
|
$HIPCXXFLAGS .= " -Wno-deprecated-register";
|
|
|
|
$HIPLDFLAGS .= " -L$HSA_PATH/lib -L$ROCM_PATH/lib -lhsa-runtime64 -lhc_am ";
|
|
# $HIPLDFLAGS .= " -L$HCC_HOME/compiler/lib -lLLVMAMDGPUDesc -lLLVMAMDGPUUtils -lLLVMMC -lLLVMCore -lLLVMSupport ";
|
|
|
|
# Add trace marker library:
|
|
# TODO - once we cleanly separate the HIP API headers from HIP library headers this logic should move to CMakebuild option - apps do not need to see the marker library.
|
|
if ($HIP_ATP_MARKER) {
|
|
$marker_inc_path = "$marker_path/include";
|
|
if (-e $marker_inc_path) {
|
|
$HIPCXXFLAGS .= " -isystem $marker_inc_path";
|
|
}
|
|
}
|
|
|
|
$marker_lib_path = "$marker_path/bin/x86_64";
|
|
if (-e $marker_lib_path) {
|
|
$HIPLDFLAGS .= " -L$marker_lib_path -lCXLActivityLogger -Wl,--rpath=$marker_lib_path";
|
|
}
|
|
|
|
if (not $isWindows) {
|
|
$HIPLDFLAGS .= " -lm";
|
|
}
|
|
|
|
if ($verbose & 0x2) {
|
|
print ("HSA_PATH=$HSA_PATH\n");
|
|
print ("HCC_HOME=$HCC_HOME\n");
|
|
}
|
|
|
|
} elsif ($HIP_PLATFORM eq "nvcc") {
|
|
$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";
|
|
|
|
$HIPLDFLAGS = " -Wno-deprecated-gpu-targets -lcuda -lcudart -L$CUDA_PATH/lib64";
|
|
} else {
|
|
printf ("error: unknown HIP_PLATFORM = '$HIP_PLATFORM'");
|
|
exit (-1);
|
|
}
|
|
|
|
# Add paths to common HIP includes:
|
|
$HIPCXXFLAGS .= " -isystem $HIP_INCLUDE_PATH" ;
|
|
|
|
my $compileOnly = 0;
|
|
my $needCXXFLAGS = 0; # need to add CXX flags to compile step
|
|
my $needLDFLAGS = 1; # need to add LDFLAGS to compile step.
|
|
my $hasC = 0; # options contain a c-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 $needHipHcc = ($HIP_PLATFORM eq 'hcc'); # set if we need to link hip_hcc.o from src tree. (some builds, ie cmake, provide their own)
|
|
my $printHipVersion = 0; # print HIP version
|
|
my $runCmd = 1;
|
|
my $buildDeps = 0;
|
|
my $linkType = 1;
|
|
my $setLinkType = 0;
|
|
|
|
my @options = ();
|
|
my @inputs = ();
|
|
|
|
if ($verbose & 0x4) {
|
|
print "hipcc-args: ", join (" ", @ARGV), "\n";
|
|
}
|
|
|
|
# Handle code object generation
|
|
my $ISACMD="";
|
|
if($HIP_PLATFORM eq "hcc"){
|
|
$ISACMD .= "$HIP_PATH/bin/lpl ";
|
|
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);
|
|
}
|
|
}
|
|
|
|
if(($HIP_PLATFORM eq "hcc")){
|
|
$ENV{HCC_EXTRA_LIBRARIES}="\n";
|
|
}
|
|
|
|
if($HIP_PLATFORM eq "nvcc"){
|
|
$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);
|
|
}
|
|
}
|
|
|
|
my $toolArgs = ""; # arguments to pass to the hcc or nvcc tool
|
|
my $optArg = ""; # -O args
|
|
|
|
foreach $arg (@ARGV)
|
|
{
|
|
$trimarg = $arg;
|
|
$trimarg =~ s/^\s+|\s+$//g; # Remive whitespace
|
|
my $swallowArg = 0;
|
|
if ($arg eq '-c' or $arg eq '--genco') {
|
|
$compileOnly = 1;
|
|
$needCXXFLAGS = 1;
|
|
$needLDFLAGS = 0;
|
|
}
|
|
if ($arg eq '-o') {
|
|
$needLDFLAGS = 1;
|
|
}
|
|
|
|
if(($trimarg eq '-stdlib=libc++') and ($setStdLib eq 0))
|
|
{
|
|
$HIPCXXFLAGS .= " -stdlib=libc++";
|
|
$setStdLib = 1;
|
|
}
|
|
|
|
# TODO: Add support for comma separated list like HCC_AMDGPU_TARGET
|
|
if($arg eq '--amdgpu-target=gfx701')
|
|
{
|
|
$target_gfx701 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx801')
|
|
{
|
|
$target_gfx801 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx802')
|
|
{
|
|
$target_gfx802 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx803')
|
|
{
|
|
$target_gfx803 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx900')
|
|
{
|
|
$target_gfx900 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx906')
|
|
{
|
|
$target_gfx906 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx908')
|
|
{
|
|
$target_gfx908 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx1010')
|
|
{
|
|
$target_gfx1010 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($arg eq '--amdgpu-target=gfx1012')
|
|
{
|
|
$target_gfx1012 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
|
|
# hip-clang does not accept --amdgpu-target= options.
|
|
if (($arg =~ /--amdgpu-target=/) and $HIP_PLATFORM eq 'clang' ) {
|
|
$swallowArg = 1;
|
|
}
|
|
|
|
if (($arg =~ /--genco/) and $HIP_PLATFORM eq 'clang' ) {
|
|
$arg = "--cuda-device-only";
|
|
}
|
|
|
|
if(($trimarg eq '-stdlib=libstdc++') and ($setStdLib eq 0))
|
|
{
|
|
$HIPCXXFLAGS .= $HCC_WA_FLAGS;
|
|
$setStdLib = 1;
|
|
}
|
|
if($trimarg eq '--version') {
|
|
$printHipVersion = 1;
|
|
}
|
|
if($trimarg eq '--short-version') {
|
|
$printHipVersion = 1;
|
|
$runCmd = 0;
|
|
}
|
|
if($trimarg eq '-M') {
|
|
$compileOnly = 1;
|
|
$buildDeps = 1;
|
|
}
|
|
if($trimarg eq '-use_fast_math') {
|
|
$HIPCXXFLAGS .= " -DHIP_FAST_MATH ";
|
|
}
|
|
if(($trimarg eq '-use-staticlib') and ($setLinkType eq 0))
|
|
{
|
|
$linkType = 0;
|
|
$setLinkType = 1;
|
|
}
|
|
if(($trimarg eq '-use-sharedlib') and ($setLinkType eq 0))
|
|
{
|
|
$linkType = 1;
|
|
$setLinkType = 1;
|
|
}
|
|
if($arg =~ m/^-O/)
|
|
{
|
|
$optArg = $arg;
|
|
}
|
|
|
|
## This is a temporary workaround for CMake detection of OpenMP support.
|
|
## It should be removed when the OpenMP detection c++ test in CMake is updated
|
|
## and corrected CMake version is available.
|
|
if((defined $HIP_COMPILER) and ($HIP_COMPILER eq "clang") and ($arg eq '-fopenmp')) {
|
|
$HIPCXXFLAGS .= " -D_OPENMP "
|
|
}
|
|
|
|
## 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,@/ and $HIP_PLATFORM eq 'clang') {
|
|
my $file = substr $arg, 5;
|
|
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 c $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 -Wl,\@$new_file";
|
|
} elsif (($arg =~ m/\.a$/ || $arg =~ m/\.lo$/) &&
|
|
$HIP_PLATFORM eq 'clang') {
|
|
## 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 c $libBaseName $realObjs");
|
|
$new_arg .= " $tmpdir/$libBaseName";
|
|
}
|
|
$arg = "$new_arg";
|
|
if ($toolArgs =~ m/-Xlinker$/) {
|
|
$toolArgs = substr $toolArgs, 0, -8;
|
|
chomp $toolArgs;
|
|
}
|
|
} elsif ($arg =~ m/^-/) {
|
|
# options start with -
|
|
|
|
# Process HIPCC options here:
|
|
if ($arg =~ m/^--hipcc/) {
|
|
$swallowArg = 1;
|
|
#if $arg eq "--hipcc_profile") { # Example argument here, hipcc
|
|
#
|
|
#}
|
|
} else {
|
|
push (@options, $arg);
|
|
}
|
|
#print "O: <$arg>\n";
|
|
} else {
|
|
# input files and libraries
|
|
if (($arg =~ /\.cpp$/) or ($arg =~ /\.cxx$/) or ($arg =~ /\.c$/) or ($arg =~ /\.cc$/) ) {
|
|
$hasC = 1;
|
|
$needCXXFLAGS = 1;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$toolArgs .= " -x hip"
|
|
}
|
|
}
|
|
if (($arg =~ /\.cu$/) or ($arg =~ /\.cuh$/) or ($arg =~ /\.hip$/)) {
|
|
$hasCU = 1;
|
|
$needCXXFLAGS = 1;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$toolArgs .= " -x hip"
|
|
}
|
|
}
|
|
|
|
push (@inputs, $arg);
|
|
#print "I: <$arg>\n";
|
|
}
|
|
$toolArgs .= " $arg" unless $swallowArg;
|
|
}
|
|
|
|
if($HIP_PLATFORM eq "hcc" or $HIP_PLATFORM eq "clang"){
|
|
# No AMDGPU target specified at commandline. So look for HCC_AMDGPU_TARGET
|
|
if($default_amdgpu_target eq 1 and defined $ENV{HCC_AMDGPU_TARGET})
|
|
{
|
|
foreach my $target (split(/,/, $ENV{HCC_AMDGPU_TARGET}))
|
|
{
|
|
if($target eq 'gfx701')
|
|
{
|
|
$target_gfx701 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx801')
|
|
{
|
|
$target_gfx801 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx802')
|
|
{
|
|
$target_gfx802 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx803')
|
|
{
|
|
$target_gfx803 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx900')
|
|
{
|
|
$target_gfx900 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx906')
|
|
{
|
|
$target_gfx906 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx908')
|
|
{
|
|
$target_gfx908 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx1010')
|
|
{
|
|
$target_gfx1010 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($target eq 'gfx1012')
|
|
{
|
|
$target_gfx1012 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
}
|
|
}
|
|
# Else try using rocm_agent_enumerator
|
|
if($default_amdgpu_target eq 1)
|
|
{
|
|
$ROCM_AGENT_ENUM = "${ROCM_PATH}/bin/rocm_agent_enumerator";
|
|
|
|
my $myAgents = `${ROCM_AGENT_ENUM} -t GPU`;
|
|
my @agentsLine = split('\n', $myAgents);
|
|
|
|
foreach my $val (@agentsLine) {
|
|
if($val eq "gfx701") {
|
|
$target_gfx701 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq "gfx801") {
|
|
$target_gfx801 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq "gfx802") {
|
|
$target_gfx802 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq "gfx803") {
|
|
$target_gfx803 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq "gfx900") {
|
|
$target_gfx900 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq "gfx906") {
|
|
$target_gfx906 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq "gfx908") {
|
|
$target_gfx908 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq 'gfx1010')
|
|
{
|
|
$target_gfx1010 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
if($val eq 'gfx1012')
|
|
{
|
|
$target_gfx1012 = 1;
|
|
$default_amdgpu_target = 0;
|
|
}
|
|
}
|
|
}
|
|
# 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 --amdgpu-target=" and die();
|
|
}
|
|
|
|
$ENV{HCC_EXTRA_LIBRARIES}="\n";
|
|
|
|
if($HIP_PLATFORM eq "hcc") {
|
|
$GPU_ARCH_OPT = " --amdgpu-target=";
|
|
} else {
|
|
$GPU_ARCH_OPT = " --cuda-gpu-arch=";
|
|
}
|
|
# Handle ROCm target platform
|
|
if ($target_gfx701 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx701";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX701__=1 ";
|
|
}
|
|
if ($target_gfx801 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx801";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX801__=1 ";
|
|
}
|
|
if ($target_gfx802 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx802";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX802__=1 ";
|
|
}
|
|
if ($target_gfx803 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx803";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX803__=1 ";
|
|
}
|
|
if ($target_gfx900 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx900";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX900__=1 ";
|
|
}
|
|
if ($target_gfx906 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx906";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX906__=1 ";
|
|
}
|
|
if ($target_gfx908 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx908";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX908__=1 ";
|
|
}
|
|
if ($target_gfx1010 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx1010";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX1010__=1 ";
|
|
}
|
|
if ($target_gfx1012 eq 1) {
|
|
$GPU_ARCH_ARG = $GPU_ARCH_OPT . "gfx1012";
|
|
$HIPLDFLAGS .= $GPU_ARCH_ARG;
|
|
if ($HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= $GPU_ARCH_ARG;;
|
|
}
|
|
$HIPCXXFLAGS .= " -D__HIP_ARCH_GFX1012__=1 ";
|
|
}
|
|
}
|
|
|
|
if ($hasC and $HIP_PLATFORM eq 'nvcc') {
|
|
$HIPCXXFLAGS .= " -x cu";
|
|
}
|
|
if ($hasCU and $HIP_PLATFORM eq 'hcc') {
|
|
$HIPCXXFLAGS .= " -x c++";
|
|
}
|
|
|
|
if ($buildDeps and $HIP_PLATFORM eq 'nvcc') {
|
|
$HIPCXXFLAGS .= " -M -D__CUDACC__";
|
|
}
|
|
|
|
if ($buildDeps and $HIP_PLATFORM eq 'clang') {
|
|
$HIPCXXFLAGS .= " --cuda-host-only";
|
|
}
|
|
|
|
# Add --hip-link only if there are no source files.
|
|
if (!$needCXXFLAGS and $HIP_PLATFORM eq 'clang') {
|
|
$HIPLDFLAGS .= " --hip-link";
|
|
}
|
|
|
|
if ($setStdLib eq 0 and $HIP_PLATFORM eq 'hcc')
|
|
{
|
|
$HIPCXXFLAGS .= $HCC_WA_FLAGS;
|
|
}
|
|
|
|
if ($needHipHcc) {
|
|
if ($linkType eq 0) {
|
|
substr($HIPLDFLAGS,0,0) = " $HIP_LIB_PATH/libhip_hcc_static.a " ;
|
|
} else {
|
|
substr($HIPLDFLAGS,0,0) = " -Wl,--enable-new-dtags -Wl,--rpath=$HIP_LIB_PATH:$ROCM_PATH/lib $HIP_LIB_PATH/libhip_hcc.so ";
|
|
}
|
|
}
|
|
|
|
# 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 "clang") {
|
|
# Set default optimization level to -O3 for hip-clang.
|
|
if ($optArg eq "") {
|
|
$HIPCXXFLAGS .= " -O3";
|
|
$HIPLDFLAGS .= " -O3";
|
|
}
|
|
$HIP_DEVLIB_FLAGS = " --hip-device-lib-path=$DEVICE_LIB_PATH";
|
|
$HIPCXXFLAGS .= " $HIP_DEVLIB_FLAGS";
|
|
if (not $isWindows) {
|
|
$HIPLDFLAGS .= " -lgcc_s -lgcc -lpthread -lm";
|
|
}
|
|
}
|
|
|
|
|
|
if ($HIPCC_COMPILE_FLAGS_APPEND) {
|
|
$HIPCXXFLAGS .= " $HIPCC_COMPILE_FLAGS_APPEND";
|
|
}
|
|
if ($HIPCC_LINK_FLAGS_APPEND) {
|
|
$HIPLDFLAGS .= " $HIPCC_LINK_FLAGS_APPEND";
|
|
}
|
|
|
|
my $CMD="$HIPCC";
|
|
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 ($runCmd) {
|
|
if ($HIP_PLATFORM eq "hcc" and exists($hipConfig{'HCC_VERSION'}) and $HCC_VERSION ne $hipConfig{'HCC_VERSION'}) {
|
|
print ("HIP ($HIP_PATH) was built using hcc $hipConfig{'HCC_VERSION'}, but you are using $HCC_HOME/hcc with version $HCC_VERSION from hipcc. Please rebuild HIP including cmake or update HCC_HOME variable.\n") ;
|
|
die unless $ENV{'HIP_IGNORE_HCC_VERSION'};
|
|
}
|
|
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
|