138cf36547
Ignores strict checking of HCC and HIP version. Can be useful when developing new HCC code.
382 строки
12 KiB
Perl
Исполняемый файл
382 строки
12 KiB
Perl
Исполняемый файл
#!/usr/bin/perl -w
|
|
|
|
|
|
# Need perl > 5.10 to use logic-defined or
|
|
use 5.006; use v5.10.1;
|
|
use File::Basename;
|
|
|
|
# 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 (default /opt/rocm/hcc). Used on AMD platforms only.
|
|
# HSA_PATH : Path to HSA dir (default /opt/rocm/hsa). 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=hippc args
|
|
|
|
$HIP_PATH=$ENV{'HIP_PATH'} // dirname (dirname $0); # use parent directory of hipcc
|
|
|
|
#---
|
|
# Read .hipInfo
|
|
my %hipConfig = ();
|
|
parse_config_file("$HIP_PATH/lib/.hipInfo", \%hipConfig);
|
|
|
|
#---
|
|
#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_VERSION_MAJOR, $HIP_VERSION_MINOR, $HIP_VERSION_PATCH) = split(/\./, $HIP_VERSION);
|
|
|
|
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
|
|
|
|
if ($HIP_PLATFORM eq "hcc") {
|
|
$HSA_PATH=$ENV{'HSA_PATH'} // "/opt/rocm/hsa";
|
|
|
|
$HCC_HOME=$ENV{'HCC_HOME'} // $hipConfig{'HCC_HOME'} // "/opt/rocm/hcc";
|
|
|
|
$HCC_VERSION=`${HCC_HOME}/bin/hcc --version | cut -d" " -f9 | tr -d "\n"`;
|
|
$HCC_VERSION_MAJOR=`${HCC_HOME}/bin/hcc --version | cut -d" " -f9 | cut -d"." -f1 | tr -d "\n"`;
|
|
|
|
$ROCM_PATH=$ENV{'ROCM_PATH'} // "/opt/rocm";
|
|
|
|
$HIP_ATP_MARKER=$ENV{'HIP_ATP_MARKER'} // 1;
|
|
$marker_path = "$ROCM_PATH/profiler/CXLActivityLogger";
|
|
|
|
$ROCM_TARGET=$ENV{'ROCM_TARGET'} // "fiji";
|
|
|
|
# HCC* may be used to compile src/hip_hcc.o (and also feed the HIPCXXFLAGS below)
|
|
$HCC = "$HCC_HOME/bin/hcc";
|
|
$HCCFLAGS = "-hc -I$HCC_HOME/include ";
|
|
|
|
$HIPCC=$HCC;
|
|
$HIPCXXFLAGS = $HCCFLAGS;
|
|
|
|
#### GCC system includes workaround ####
|
|
$HCC_WA_FLAGS = " ";
|
|
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;
|
|
if (${GCC_CUR_VER} eq ${GPP_CUR_VER}) {
|
|
$HCC_WA_FLAGS .= " -I/usr/include/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu/c++/${GCC_CUR_VER} -I/usr/include/c++/${GCC_CUR_VER} ";
|
|
}
|
|
}
|
|
|
|
$HIPCXXFLAGS .= " -I$HIP_PATH/include/hip/hcc_detail/cuda";
|
|
$HIPCXXFLAGS .= " -I$HSA_PATH/include";
|
|
$HIPCXXFLAGS .= " -Wno-deprecated-register";
|
|
$HIPLDFLAGS = "-hc -L$HCC_HOME/lib -Wl,--rpath=$HCC_HOME/lib -lc++ -ldl -lpthread -Wl,--whole-archive -lmcwamp -Wl,--no-whole-archive";
|
|
|
|
# Suppress linker warnings in case HCC distribution contains OpenCL/SPIR symbols
|
|
$HOST_OSNAME= `cat /etc/os-release | grep "^ID\=" | cut -d= -f2 | tr -d '\n'`;
|
|
$HOST_OSVER= `cat /etc/os-release | grep "^VERSION_ID\=" | cut -d= -f2 | tr -d '\n'`;
|
|
if ($HOST_OSNAME eq "ubuntu" and $HOST_OSVER eq "\"16.04\"") {
|
|
# No additional flags required
|
|
} else {
|
|
$HIPLDFLAGS .= " -Wl,--defsym=_binary_kernel_spir_end=1 -Wl,--defsym=_binary_kernel_spir_start=1 -Wl,--defsym=_binary_kernel_cl_start=1 -Wl,--defsym=_binary_kernel_cl_end=1";
|
|
}
|
|
if ($HOST_OSNAME eq "fedora") {
|
|
$HIPCXXFLAGS .= " -I/usr/local/include/c++/v1";
|
|
}
|
|
|
|
# Satisfy HCC dependencies
|
|
if ($HOST_OSNAME eq "fedora") {
|
|
$HIPLDFLAGS .= " -lc++abi";
|
|
} else {
|
|
$HIPLDFLAGS .= " -lc++abi -lsupc++";
|
|
}
|
|
$HIPLDFLAGS .= " -L$HSA_PATH/lib -L$ROCM_PATH/lib -lhsa-runtime64 -lhc_am -lhsakmt";
|
|
|
|
# Handle ROCm target platform
|
|
if ($ROCM_TARGET eq "fiji") {
|
|
$HIPLDFLAGS .= " -amdgpu-target=AMD:AMDGPU:8:0:3";
|
|
}
|
|
if ($ROCM_TARGET eq "carrizo") {
|
|
$HIPLDFLAGS .= " -amdgpu-target=AMD:AMDGPU:8:0:1";
|
|
}
|
|
if ($ROCM_TARGET eq "hawaii") {
|
|
$HIPLDFLAGS .= " -amdgpu-target=AMD:AMDGPU:7:0:1";
|
|
}
|
|
if ($ROCM_TARGET eq "polaris") {
|
|
$HIPLDFLAGS .= " -amdgpu-target=AMD:AMDGPU:8:0:3";
|
|
}
|
|
|
|
# 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 .= " -I$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";
|
|
}
|
|
|
|
# Add C++ libs for GCC.
|
|
$HIPLDFLAGS .= " -lstdc++";
|
|
$HIPLDFLAGS .= " -lm";
|
|
|
|
if ($verbose & 0x2) {
|
|
print ("HSA_PATH=$HSA_PATH\n");
|
|
print ("HCC_HOME=$HCC_HOME\n");
|
|
}
|
|
|
|
} elsif ($HIP_PLATFORM eq "nvcc") {
|
|
if ($verbose & 0x2) {
|
|
print ("CUDA_PATH=$CUDA_PATH\n");
|
|
}
|
|
$CUDA_PATH=$ENV{'CUDA_PATH'} // '/usr/local/cuda';
|
|
|
|
$HIPCC="$CUDA_PATH/bin/nvcc";
|
|
$HIPCXXFLAGS .= " -I$CUDA_PATH/include";
|
|
|
|
$HIPLDFLAGS = "-lcuda -lcudart -L$CUDA_PATH/lib64";
|
|
} else {
|
|
printf ("error: unknown HIP_PLATFORM = '$HIP_PLATFORM'");
|
|
exit (-1);
|
|
}
|
|
|
|
# Add paths to common HIP includes:
|
|
$HIPCXXFLAGS .= " -I$HIP_PATH/include -DHIP_VERSION_MAJOR=$HIP_VERSION_MAJOR -DHIP_VERSION_MINOR=$HIP_VERSION_MINOR -DHIP_VERSION_PATCH=$HIP_VERSION_PATCH" ;
|
|
|
|
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 .= "set ROCM_PATH=$ROCM_PATH && set ROCM_TARGET=$ROCM_TARGET && $HIP_PATH/bin/hccgenco.sh ";
|
|
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")){
|
|
$EXPORT_LL=" ";
|
|
$ENV{HCC_EXTRA_LIBRARIES}="$HIP_PATH/lib/hip_ir.ll\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
|
|
|
|
foreach $arg (@ARGV)
|
|
{
|
|
$trimarg = $arg;
|
|
$trimarg =~ s/^\s+|\s+$//g; # Remive whitespace
|
|
my $swallowArg = 0;
|
|
if ($arg eq '-c') {
|
|
$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;
|
|
}
|
|
if(($trimarg eq '-stdlib=libstdc++') and ($setStdLib eq 0))
|
|
{
|
|
$HIPCXXFLAGS .= " -stdlib=libstdc++";
|
|
$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/^-/) {
|
|
# 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 =~ /\.c$/) or ($arg =~ /\.cc$/) ) {
|
|
$hasC = 1;
|
|
$needCXXFLAGS = 1;
|
|
}
|
|
if (($arg =~ /\.cu$/) or ($arg =~ /\.cuh$/)) {
|
|
$hasCU = 1;
|
|
$needCXXFLAGS = 1;
|
|
}
|
|
|
|
push (@inputs, $arg);
|
|
#print "I: <$arg>\n";
|
|
}
|
|
$toolArgs .= " $arg" unless $swallowArg;
|
|
}
|
|
|
|
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 ($setStdLib eq 0 and $HIP_PLATFORM eq 'hcc')
|
|
{
|
|
$HIPCXXFLAGS .= " -stdlib=libstdc++";
|
|
$HIPCXXFLAGS .= $HCC_WA_FLAGS;
|
|
}
|
|
|
|
if ($needHipHcc) {
|
|
if ($linkType eq 0) {
|
|
substr($HIPLDFLAGS,0,0) = " $HIP_PATH/lib/libhip_hcc_static.a $HIP_PATH/lib/libhip_device.a " ;
|
|
} else {
|
|
substr($HIPLDFLAGS,0,0) = " -Wl,--rpath=$HIP_PATH/lib $HIP_PATH/lib/libhip_hcc.so $HIP_PATH/lib/libhip_device.a ";
|
|
}
|
|
}
|
|
|
|
# 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.
|
|
|
|
|
|
|
|
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") and die ();
|
|
}
|