1329be958a
Change-Id: I8023f4349621fd81c58615737b7e897649e0f7ca
345 строки
11 KiB
Perl
Исполняемый файл
345 строки
11 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"`;
|
|
|
|
$ROCM_PATH=$ENV{'ROCM_PATH'} // "/opt/rocm";
|
|
|
|
$HIP_ATP_MARKER=$ENV{'HIP_ATP_MARKER'};
|
|
$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;
|
|
|
|
$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";
|
|
}
|
|
|
|
# Satisfy HCC dependencies
|
|
$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";
|
|
}
|
|
|
|
# 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 @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)
|
|
{
|
|
my $swallowArg = 0;
|
|
if ($arg eq '-c') {
|
|
$compileOnly = 1;
|
|
$needCXXFLAGS = 1;
|
|
$needLDFLAGS = 0;
|
|
}
|
|
if ($arg eq '-o') {
|
|
$needLDFLAGS = 1;
|
|
}
|
|
|
|
if(($arg eq '-stdlib=libc++') and ($setStdLib eq 0))
|
|
{
|
|
$HIPCXXFLAGS .= " -stdlib=libc++";
|
|
$setStdLib = 1;
|
|
}
|
|
if(($arg eq '-stdlib=libstdc++') and ($setStdLib eq 0))
|
|
{
|
|
$HIPCXXFLAGS .= " -stdlib=libstdc++";
|
|
$setStdLib = 1;
|
|
}
|
|
if($arg eq '--version') {
|
|
$printHipVersion = 1;
|
|
}
|
|
if($arg eq '--short-version') {
|
|
$printHipVersion = 1;
|
|
$runCmd = 0;
|
|
}
|
|
if($arg eq '-M') {
|
|
$compileOnly = 1;
|
|
$buildDeps = 1;
|
|
}
|
|
|
|
if ($arg =~ m/^-/) {
|
|
# options start with -
|
|
|
|
# Process HIPCC options here:
|
|
if ($arg =~ m/^--hipcc/) {
|
|
$swallowArg = 1;
|
|
if ($arg eq "--hipcc_explicit_lib") {
|
|
# Some environments (ie cmake tests) already link their own hip_hcc.o, so don't add here:
|
|
$needHipHcc = 0;
|
|
}
|
|
} 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++";
|
|
}
|
|
|
|
if ($needHipHcc) {
|
|
$HIP_LIB_TYPE = $hipConfig{'HIP_LIB_TYPE'} // 0;
|
|
|
|
if ($HIP_LIB_TYPE eq 0) {
|
|
$HIPLDFLAGS .= " $HIP_PATH/lib/device_util.cpp.o $HIP_PATH/lib/hip_device.cpp.o $HIP_PATH/lib/hip_error.cpp.o $HIP_PATH/lib/hip_event.cpp.o $HIP_PATH/lib/hip_hcc.cpp.o $HIP_PATH/lib/hip_memory.cpp.o $HIP_PATH/lib/hip_peer.cpp.o $HIP_PATH/lib/hip_stream.cpp.o $HIP_PATH/lib/hip_ldg.cpp.o $HIP_PATH/lib/hip_fp16.cpp.o $HIP_PATH/lib/hip_context.cpp.o $HIP_PATH/lib/hip_module.cpp.o";
|
|
} elsif ($HIP_LIB_TYPE eq 1) {
|
|
$HIPLDFLAGS .= " -L$HIP_PATH/lib -lhip_hcc" ;
|
|
} else {
|
|
$HIPLDFLAGS .= " -L$HIP_PATH/lib -Wl,--rpath=$HIP_PATH/lib -lhip_hcc";
|
|
}
|
|
}
|
|
|
|
# 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 $HCC_VERSION. Please rebuild HIP including cmake.\n") && die ();
|
|
}
|
|
system ("$CMD") and die ();
|
|
}
|