Merge branch 'master' into support-malloc

This commit is contained in:
Maneesh Gupta
2018-09-17 10:17:25 +05:30
committed by GitHub
61 changed files with 5094 additions and 2387 deletions
+24 -3
View File
@@ -58,6 +58,21 @@ if(NOT DEFINED HIP_PLATFORM)
endif()
message(STATUS "HIP Platform: " ${HIP_PLATFORM})
# Determine HIP_COMPILER
# Either hcc or clang; default is hcc
if(NOT DEFINED HIP_COMPILER)
if(NOT DEFINED ENV{HIP_COMPILER})
set(HIP_COMPILER "hcc" CACHE STRING "HIP Compiler")
else()
set(HIP_COMPILER $ENV{HIP_COMPILER} CACHE STRING "HIP Compiler")
endif()
endif()
if(NOT (HIP_COMPILER STREQUAL "hcc" OR HIP_COMPILER STREQUAL "clang"))
message(FATAL_ERROR "Must use HIP_COMPILER as hcc or clang")
endif()
message(STATUS "HIP Compiler: " ${HIP_COMPILER})
# If HIP_PLATFORM is hcc, we need HCC_HOME and HSA_PATH to be defined
if(HIP_PLATFORM STREQUAL "hcc")
# Determine HCC_HOME
@@ -202,9 +217,11 @@ if(HIP_PLATFORM STREQUAL "hcc")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/opt/rocm/profiler/CXLActivityLogger/bin/x86_64 -lCXLActivityLogger")
endif()
add_library(hip_hcc SHARED ${SOURCE_FILES_RUNTIME})
target_link_libraries(hip_hcc PRIVATE hc_am)
add_library(hip_hcc_static STATIC ${SOURCE_FILES_RUNTIME})
target_link_libraries(hip_hcc_static PRIVATE hc_am)
if(HIP_COMPILER STREQUAL "hcc")
target_link_libraries(hip_hcc PRIVATE hc_am)
target_link_libraries(hip_hcc_static PRIVATE hc_am)
endif()
add_library(hip_device STATIC ${SOURCE_FILES_DEVICE})
string(REPLACE " " ";" HCC_CXX_FLAGS_LIST ${HCC_CXX_FLAGS})
@@ -214,7 +231,11 @@ if(HIP_PLATFORM STREQUAL "hcc")
add_library(host INTERFACE)
target_link_libraries(host INTERFACE hip_hcc)
add_library(device INTERFACE)
target_link_libraries(device INTERFACE host hip_device hcc::hccrt hcc::hc_am)
if(HIP_COMPILER STREQUAL "hcc")
target_link_libraries(device INTERFACE host hip_device hcc::hccrt hcc::hc_am)
elseif(HIP_COMPILER STREQUAL "clang")
target_link_libraries(device INTERFACE host hip_device)
endif()
# Generate .hipInfo
file(WRITE "${PROJECT_BINARY_DIR}/.hipInfo" ${_buildInfo})
Vendored
+39 -165
View File
@@ -38,6 +38,13 @@ String get_upstream_build_project( )
return upstream_cause.getUpstreamProject()
}
////////////////////////////////////////////////////////////////////////
// Construct the docker build image name
String docker_build_image_name( )
{
return "build-ubuntu-16.04"
}
////////////////////////////////////////////////////////////////////////
// Construct the relative path of the build directory
String build_directory_rel( String build_config )
@@ -114,7 +121,7 @@ String checkout_and_version( String platform )
// The docker images contains all dependencies, including OS platform, to build
def docker_build_image( String platform, String org, String optional_build_parm, String source_hip_rel, String from_image )
{
String build_image_name = "build-ubuntu-16.04"
String build_image_name = docker_build_image_name( )
String dockerfile_name = "dockerfile-build-ubuntu-16.04"
def build_image = null
@@ -170,7 +177,7 @@ def docker_build_inside_image( def build_image, String inside_args, String platf
cd ${build_dir_rel}
make install -j\$(nproc)
make build_tests -i -j\$(nproc)
ctest -E hipPrintfKernel
ctest -E hipVectorTypes
"""
// If unit tests output a junit or xunit file in the future, jenkins can parse that file
// to display test results on the dashboard
@@ -179,7 +186,7 @@ def docker_build_inside_image( def build_image, String inside_args, String platf
}
// Only create packages from hcc based builds
if( platform.toLowerCase( ).startsWith( 'hcc-' ) )
if( platform.toLowerCase( ).startsWith( 'rocm-' ) )
{
stage("${platform} packaging")
{
@@ -191,10 +198,10 @@ def docker_build_inside_image( def build_image, String inside_args, String platf
// No matter the base platform, all packages have the same name
// Only upload 1 set of packages, so we don't have a race condition uploading packages
if( platform.toLowerCase( ).startsWith( 'hcc-ctu' ) )
if( platform.toLowerCase( ).startsWith( 'rocm-head' ) )
{
archiveArtifacts artifacts: "${build_dir_rel}/*.deb", fingerprint: true
// archiveArtifacts artifacts: "${build_dir_rel}/*.rpm", fingerprint: true
archiveArtifacts artifacts: "${build_dir_rel}/*.rpm", fingerprint: true
}
}
}
@@ -282,103 +289,26 @@ def docker_upload_dockerhub( String local_org, String image_name, String remote_
}
}
////////////////////////////////////////////////////////////////////////
// hcc_integration_testing
// This function is sets up compilation and testing of HiP on a compiler downloaded from an upstream build
// Integration testing is centered around docker and constructing clean test environments every time
// NOTES: I have implemeneted integration testing 3 different ways, and I've come to the conclusion nothing is perfect
// 1. I've tried having HCC push the test compiler to artifactory, and having HiP download the test docker image from artifactory
// a. The act of uploading and downloading images from artifactory takes minutes
// b. There is no good way of deleting images from a repository. You have to use an arcane CURL command and I don't know how
// to keep the password secret. These test integration images are meant to be ephemeral.
// 2. I tried 'docker save' to export a docker image into a tarball, and transfering the image through 'copy artifacts plugin'
// a. The HCC docker image uncompressed is over 1GB
// b. Compressing the docker image takes even longer than uploading the image to artifactory
// 3. Download the HCC .deb and dockerfile through 'copy artifacts plugin'. Create a new HCC image on the fly
// a. There is inefficency in building a new ubuntu image and installing HCC twice (once in HCC build, once here)
// b. This solution doesn't scale when we start testing downstream libraries
// I've implemented solution #3 above, probably transitioning to #2 down the line (probably without compression)
String hcc_integration_testing( String inside_args, String job, String build_config )
{
// Attempt to make unique docker image names for each build, to support concurrent builds
// Mangle docker org name with upstream build info
String testing_org_name = 'hcc-test-' + get_upstream_build_project( ).replaceAll('/','-').toLowerCase( ) + '-' + get_upstream_build_num( )
// String testing_org_name = 'hcc-test-artifacts-download'
// Tag image name with this build number
String hcc_test_image_name = "hcc:${env.BUILD_NUMBER}"
def hip_integration_image = null
dir( 'integration-testing' )
{
deleteDir( )
// This invokes 'copy artifact plugin' to copy archived files from upstream build
step([$class: 'CopyArtifact', filter: 'build/**/*.deb, docker/dockerfile-hcc-lc-*',
fingerprintArtifacts: true, projectName: get_upstream_build_project( ), flatten: true,
selector: [$class: 'TriggeredBuildSelector', allowUpstreamDependencies: false, fallbackToLastSuccessful: false, upstreamFilterStrategy: 'UseGlobalSetting'],
target: '.' ])
// step([$class: 'CopyArtifact', filter: 'build/**/*.deb, docker/dockerfile-hcc-lc-*',
// fingerprintArtifacts: true, projectName: 'kknox/hcc/test-artifact-download', flatten: true,
// selector: [$class: 'LastCompletedBuildSelector'],
// target: '.' ])
docker.build( "${testing_org_name}/${hcc_test_image_name}", "-f dockerfile-hcc-lc-ubuntu-16.04 ." )
}
// Checkout source code, dependencies and version files
String source_hip_rel = checkout_and_version( job )
// Conctruct a binary directory path based on build config
String build_hip_rel = build_directory_rel( build_config );
// Build hip inside of the build environment
hip_integration_image = docker_build_image( job, testing_org_name, '', source_hip_rel, "${testing_org_name}/${hcc_test_image_name}" )
docker_build_inside_image( hip_integration_image, inside_args, job, '', build_config, source_hip_rel, build_hip_rel )
docker_clean_images( testing_org_name, '*' )
}
////////////////////////////////////////////////////////////////////////
// -- MAIN
// Following this line is the start of MAIN of this Jenkinsfile
String build_config = 'Release'
String job_name = env.JOB_NAME.toLowerCase( )
// Integration testing is a special path which implies testing of an upsteam build of hcc,
// but does not need testing across older builds of hcc or cuda. This is more of a compiler
// hcc unit test
// params.hcc_integration_test is set in HCC build
if( params.hcc_integration_test )
{
println "HCC integration testing"
node('docker && rocm')
{
hcc_integration_testing( '--device=/dev/kfd --device=/dev/dri --group-add=video', 'hcc-ctu', build_config )
}
return
}
// The following launches 3 builds in parallel: hcc-ctu, hcc-1.6 and cuda
parallel hcc_ctu:
parallel rocm_1_9:
{
node('docker && rocm && dkms')
node('hip-rocm')
{
String hcc_ver = 'hcc-ctu'
String from_image = 'compute-artifactory:5001/radeonopencompute/hcc/clang_tot_upgrade/hcc-lc-ubuntu-16.04:latest'
String hcc_ver = 'rocm-1.9.x'
String from_image = 'ci_test_nodes/rocm-1.9.x/ubuntu-16.04:latest'
String inside_args = '--device=/dev/kfd --device=/dev/dri --group-add=video'
// Checkout source code, dependencies and version files
String source_hip_rel = checkout_and_version( hcc_ver )
// Create/reuse a docker image that represents the hip build environment
def hip_build_image = docker_build_image( hcc_ver, 'hip', ' --pull', source_hip_rel, from_image )
def hip_build_image = docker_build_image( hcc_ver, 'hip', '', source_hip_rel, from_image )
// Print system information for the log
hip_build_image.inside( inside_args )
@@ -396,67 +326,34 @@ parallel hcc_ctu:
// Build hip inside of the build environment
docker_build_inside_image( hip_build_image, inside_args, hcc_ver, '', build_config, source_hip_rel, build_hip_rel )
// After a successful build, upload a docker image of the results
String hip_image_name = docker_upload_artifactory( hcc_ver, job_name, from_image, source_hip_rel, build_hip_rel )
// Clean docker build image
docker_clean_images( 'hip', docker_build_image_name( ) )
// After a successful build, upload a docker image of the results
/*
String hip_image_name = docker_upload_artifactory( hcc_ver, job_name, from_image, source_hip_rel, build_hip_rel )
if( params.push_image_to_docker_hub )
{
docker_upload_dockerhub( job_name, hip_image_name, 'rocm' )
docker_clean_images( 'rocm', hip_image_name )
}
docker_clean_images( job_name, hip_image_name )
*/
}
},
/*
hcc_1_6:
rocm_head:
{
node('docker && rocm')
node('hip-rocm')
{
String hcc_ver = 'hcc-1.6'
String from_image = 'rocm/dev-ubuntu-16.04:1.6.4'
String inside_args = '--device=/dev/kfd --device=/dev/dri'
// Checkout source code, dependencies and version files
String source_hip_rel = checkout_and_version( hcc_ver )
// Create/reuse a docker image that represents the hip build environment
def hip_build_image = docker_build_image( hcc_ver, 'hip', ' --pull', source_hip_rel, from_image )
// Print system information for the log
hip_build_image.inside( inside_args )
{
sh """#!/usr/bin/env bash
set -x
/opt/rocm/bin/rocm_agent_enumerator -t ALL
/opt/rocm/bin/hcc --version
"""
}
// Conctruct a binary directory path based on build config
String build_hip_rel = build_directory_rel( build_config );
// Build hip inside of the build environment
docker_build_inside_image( hip_build_image, inside_args, hcc_ver, '', build_config, source_hip_rel, build_hip_rel )
// Not pushing hip-hcc-1.6 builds at this time; saves a minute and nobody needs?
// String hip_image_name = docker_upload_artifactory( hcc_ver, job_name, from_image, source_hip_rel, build_hip_rel )
// docker_clean_images( job_name, hip_image_name )
}
},
*/
hcc_1_7:
{
node('docker && rocm && dkms')
{
String hcc_ver = 'hcc-1.7'
String from_image = 'rocm/dev-ubuntu-16.04:latest'
String hcc_ver = 'rocm-head'
String from_image = 'ci_test_nodes/rocm-head/ubuntu-16.04:latest'
String inside_args = '--device=/dev/kfd --device=/dev/dri --group-add=video'
// Checkout source code, dependencies and version files
String source_hip_rel = checkout_and_version( hcc_ver )
// Create/reuse a docker image that represents the hip build environment
def hip_build_image = docker_build_image( hcc_ver, 'hip', ' --pull', source_hip_rel, from_image )
def hip_build_image = docker_build_image( hcc_ver, 'hip', '', source_hip_rel, from_image )
// Print system information for the log
hip_build_image.inside( inside_args )
@@ -474,41 +371,18 @@ hcc_1_7:
// Build hip inside of the build environment
docker_build_inside_image( hip_build_image, inside_args, hcc_ver, '', build_config, source_hip_rel, build_hip_rel )
// Not pushing hip-hcc-1.7 builds at this time; saves a minute and nobody needs?
// String hip_image_name = docker_upload_artifactory( hcc_ver, job_name, from_image, source_hip_rel, build_hip_rel )
// docker_clean_images( job_name, hip_image_name )
}
}/*,
nvcc:
{
node('docker && cuda')
{
////////////////////////////////////////////////////////////////////////
// Block of string constants customizing behavior for cuda
String nvcc_ver = 'nvcc-9.0'
String from_image = 'nvidia/cuda:9.0-devel'
String inside_args = '--runtime=nvidia';
// Clean docker image
docker_clean_images( 'hip', docker_build_image_name( ) )
// Checkout source code, dependencies and version files
String source_hip_rel = checkout_and_version( nvcc_ver )
// We pull public nvidia images
def hip_build_image = docker_build_image( nvcc_ver, 'hip', ' --pull', source_hip_rel, from_image )
// Print system information for the log
hip_build_image.inside( inside_args )
// After a successful build, upload a docker image of the results
/*
String hip_image_name = docker_upload_artifactory( hcc_ver, job_name, from_image, source_hip_rel, build_hip_rel )
if( params.push_image_to_docker_hub )
{
sh """#!/usr/bin/env bash
set -x
nvidia-smi
nvcc --version
"""
docker_upload_dockerhub( job_name, hip_image_name, 'rocm' )
docker_clean_images( 'rocm', hip_image_name )
}
// Conctruct a binary directory path based on build config
String build_hip_rel = build_directory_rel( build_config );
// Build hip inside of the build environment
docker_build_inside_image( hip_build_image, inside_args, nvcc_ver, "-DHIP_NVCC_FLAGS=--Wno-deprecated-gpu-targets", build_config, source_hip_rel, build_hip_rel )
docker_clean_images( job_name, hip_image_name )
*/
}
}*/
}
+63 -2
View File
@@ -57,6 +57,7 @@ $HIP_PATH=$ENV{'HIP_PATH'} // dirname (dirname $0); # use parent directory of hi
$HIP_VDI_HOME=$ENV{'HIP_VDI_HOME'};
$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
#---
# Read .hipInfo
@@ -158,6 +159,10 @@ if ($HIP_PLATFORM eq "clang") {
$HIPCXXFLAGS .= " -std=c++11 -isystem $HIP_CLANG_INCLUDE_PATH";
$HIPLDFLAGS .= " --hip-device-lib-path=$DEVICE_LIB_PATH -L$HIP_LIB_PATH -Wl,--rpath=$HIP_LIB_PATH -lhip_hcc";
if ($HIP_CLANG_HCC_COMPAT_MODE) {
## Allow __fp16 as function parameter and return type.
$HIPCXXFLAGS .= " -Xclang -fallow-half-arguments-and-returns -D__HIP_HCC_COMPAT_MODE__=1";
}
} elsif ($HIP_PLATFORM eq "hcc") {
$HIP_INCLUDE_PATH = "$HIP_PATH/include";
$HSA_PATH=$ENV{'HSA_PATH'} // "/opt/rocm/hsa";
@@ -216,7 +221,7 @@ if ($HIP_PLATFORM eq "clang") {
$HIPCXXFLAGS .= " -I$HSA_PATH/include";
$HIPCXXFLAGS .= " -Wno-deprecated-register";
$HIPLDFLAGS .= " -L$HSA_PATH/lib -L$ROCM_PATH/lib -lhsa-runtime64 -lhc_am -lhsakmt ";
$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:
@@ -448,6 +453,15 @@ foreach $arg (@ARGV)
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";
}
@@ -455,6 +469,53 @@ foreach $arg (@ARGV)
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/);
$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 -
@@ -673,7 +734,7 @@ if ($needLDFLAGS and not $compileOnly) {
}
$CMD .= " $toolArgs";
if ($needLDFLAGS and not $compileOnly and $HIP_PLATFORM eq "clang") {
$CMD .= " -lgcc_s -lgcc";
$CMD .= " -lgcc_s -lgcc -lpthread -lm";
}
if ($verbose & 0x1) {
+2 -2
View File
@@ -33,7 +33,7 @@ set(CMAKE_HIP_ARCHIVE_FINISH ${CMAKE_CXX_ARCHIVE_FINISH})
set(CMAKE_SHARED_LIBRARY_SONAME_HIP_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG})
set(CMAKE_SHARED_LIBRARY_CREATE_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS})
set(CMAKE_SHARED_LIBRARY_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS})
set(CMAKE_SHARED_LIBRARY_LINK_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS})
#set(CMAKE_SHARED_LIBRARY_LINK_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS})
set(CMAKE_SHARED_LIBRARY_RUNTIME_HIP_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG})
set(CMAKE_SHARED_LIBRARY_RUNTIME_HIP_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP})
set(CMAKE_SHARED_LIBRARY_LINK_STATIC_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_STATIC_CXX_FLAGS})
@@ -380,7 +380,7 @@ endmacro()
###############################################################################
macro(HIP_PREPARE_TARGET_COMMANDS _target _format _generated_files _source_files)
set(_hip_flags "")
set(_hip_build_configuration "${CMAKE_BUILD_TYPE}")
string(TOUPPER "${CMAKE_BUILD_TYPE}" _hip_build_configuration)
if(HIP_HOST_COMPILATION_CPP)
set(HIP_C_OR_CXX CXX)
else()
+2 -17
View File
@@ -2,28 +2,13 @@
ARG base_image
FROM ${base_image}
MAINTAINER Kent Knox <kent.knox@amd>
MAINTAINER Maneesh Gupta <maneesh.gupta@amd>
ARG user_uid
# Install Packages
# python and libnuma1 are dependencies of rocm_agent_enumerator
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
sudo \
build-essential \
cmake \
git \
libelf-dev \
rpm \
python \
libnuma1 \
&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# docker pipeline runs containers with particular uid
# create a jenkins user with this specific uid so it can use sudo priviledges
# Grant any member of sudo group password-less sudo privileges
RUN useradd --create-home -u ${user_uid} -G sudo --shell /bin/bash jenkins && \
RUN useradd --create-home -u ${user_uid} -G sudo,video --shell /bin/bash jenkins && \
mkdir -p /etc/sudoers.d/ && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' | tee /etc/sudoers.d/sudo-nopasswd
@@ -0,0 +1,516 @@
# CUBLAS API supported by HIP
## **1. CUBLAS Data types**
| **type** | **CUDA** | **HIP** |**HIP value** (if differs) |
|-------------:|---------------------------------------------------------------|------------------------------------------------------------|---------------------------|
| enum |***`cublasStatus`*** |***`hipblasStatus_t`*** |
| enum |***`cublasStatus_t`*** |***`hipblasStatus_t`*** |
| 0 |*`CUBLAS_STATUS_SUCCESS`* |*`HIPBLAS_STATUS_SUCCESS`* |
| 1 |*`CUBLAS_STATUS_NOT_INITIALIZED`* |*`HIPBLAS_STATUS_NOT_INITIALIZED`* |
| 3 |*`CUBLAS_STATUS_ALLOC_FAILED`* |*`HIPBLAS_STATUS_ALLOC_FAILED`* | 2 |
| 7 |*`CUBLAS_STATUS_INVALID_VALUE`* |*`HIPBLAS_STATUS_INVALID_VALUE`* | 3 |
| 8 |*`CUBLAS_STATUS_ARCH_MISMATCH`* |*`HIPBLAS_STATUS_ARCH_MISMATCH`* | |
| 11 |*`CUBLAS_STATUS_MAPPING_ERROR`* |*`HIPBLAS_STATUS_MAPPING_ERROR`* | 4 |
| 13 |*`CUBLAS_STATUS_EXECUTION_FAILED`* |*`HIPBLAS_STATUS_EXECUTION_FAILED`* | 5 |
| 14 |*`CUBLAS_STATUS_INTERNAL_ERROR`* |*`HIPBLAS_STATUS_INTERNAL_ERROR`* | 6 |
| 15 |*`CUBLAS_STATUS_NOT_SUPPORTED`* |*`HIPBLAS_STATUS_NOT_SUPPORTED`* | 7 |
| 16 |*`CUBLAS_STATUS_LICENSE_ERROR`* | |
| enum |***`cublasOperation_t`*** |***`hipblasOperation_t`*** |
| 0 |*`CUBLAS_OP_N`* |*`HIPBLAS_OP_N`* | 111 |
| 1 |*`CUBLAS_OP_T`* |*`HIPBLAS_OP_T`* | 112 |
| 2 |*`CUBLAS_OP_C`* |*`HIPBLAS_OP_C`* | 113 |
| enum |***`cublasFillMode_t`*** |***`hipblasFillMode_t`*** |
| 0 |*`CUBLAS_FILL_MODE_LOWER`* |*`HIPBLAS_FILL_MODE_LOWER`* | 121 |
| 1 |*`CUBLAS_FILL_MODE_UPPER`* |*`HIPBLAS_FILL_MODE_UPPER`* | 122 |
| enum |***`cublasDiagType_t`*** |***`hipblasDiagType_t`*** |
| 0 |*`CUBLAS_DIAG_NON_UNIT`* |*`HIPBLAS_DIAG_NON_UNIT`* | 131 |
| 1 |*`CUBLAS_DIAG_UNIT`* |*`HIPBLAS_DIAG_UNIT`* | 132 |
| enum |***`cublasSideMode_t`*** |***`hipblasSideMode_t`*** |
| 0 |*`CUBLAS_SIDE_LEFT`* |*`HIPBLAS_SIDE_LEFT`* | 141 |
| 1 |*`CUBLAS_SIDE_RIGHT`* |*`HIPBLAS_SIDE_RIGHT`* | 142 |
| enum |***`cublasPointerMode_t`*** |***`hipblasPointerMode_t`*** |
| 0 |*`CUBLAS_POINTER_MODE_HOST`* |*`HIPBLAS_POINTER_MODE_HOST`* |
| 1 |*`CUBLAS_POINTER_MODE_DEVICE`* |*`HIPBLAS_POINTER_MODE_DEVICE`* |
| enum |***`cublasAtomicsMode_t`*** | |
| 0 |*`CUBLAS_ATOMICS_NOT_ALLOWED`* | |
| 1 |*`CUBLAS_ATOMICS_ALLOWED`* | |
| enum |***`cublasAtomicsMode_t`*** | |
| -1 |*`CUBLAS_GEMM_DFALT`* | |
| -1 |*`CUBLAS_GEMM_DEFAULT`* | |
| 0 |*`CUBLAS_GEMM_ALGO0`* | |
| 1 |*`CUBLAS_GEMM_ALGO1`* | |
| 2 |*`CUBLAS_GEMM_ALGO2`* | |
| 3 |*`CUBLAS_GEMM_ALGO3`* | |
| 4 |*`CUBLAS_GEMM_ALGO4`* | |
| 5 |*`CUBLAS_GEMM_ALGO5`* | |
| 6 |*`CUBLAS_GEMM_ALGO6`* | |
| 7 |*`CUBLAS_GEMM_ALGO7`* | |
| 8 |*`CUBLAS_GEMM_ALGO8`* | |
| 9 |*`CUBLAS_GEMM_ALGO9`* | |
| 10 |*`CUBLAS_GEMM_ALGO10`* | |
| 11 |*`CUBLAS_GEMM_ALGO11`* | |
| 12 |*`CUBLAS_GEMM_ALGO12`* | |
| 13 |*`CUBLAS_GEMM_ALGO13`* | |
| 14 |*`CUBLAS_GEMM_ALGO14`* | |
| 15 |*`CUBLAS_GEMM_ALGO15`* | |
| 16 |*`CUBLAS_GEMM_ALGO16`* | |
| 17 |*`CUBLAS_GEMM_ALGO17`* | |
| 18 |*`CUBLAS_GEMM_ALGO18`* | |
| 19 |*`CUBLAS_GEMM_ALGO19`* | |
| 20 |*`CUBLAS_GEMM_ALGO20`* | |
| 21 |*`CUBLAS_GEMM_ALGO21`* | |
| 22 |*`CUBLAS_GEMM_ALGO22`* | |
| 23 |*`CUBLAS_GEMM_ALGO23`* | |
| 99 |*`CUBLAS_GEMM_DEFAULT_TENSOR_OP`* | |
| 99 |*`CUBLAS_GEMM_DFALT_TENSOR_OP`* | |
| 100 |*`CUBLAS_GEMM_ALGO0_TENSOR_OP`* | |
| 101 |*`CUBLAS_GEMM_ALGO1_TENSOR_OP`* | |
| 102 |*`CUBLAS_GEMM_ALGO2_TENSOR_OP`* | |
| 103 |*`CUBLAS_GEMM_ALGO3_TENSOR_OP`* | |
| 104 |*`CUBLAS_GEMM_ALGO4_TENSOR_OP`* | |
| 105 |*`CUBLAS_GEMM_ALGO5_TENSOR_OP`* | |
| 106 |*`CUBLAS_GEMM_ALGO6_TENSOR_OP`* | |
| 107 |*`CUBLAS_GEMM_ALGO7_TENSOR_OP`* | |
| 108 |*`CUBLAS_GEMM_ALGO8_TENSOR_OP`* | |
| 109 |*`CUBLAS_GEMM_ALGO9_TENSOR_OP`* | |
| 110 |*`CUBLAS_GEMM_ALGO10_TENSOR_OP`* | |
| 111 |*`CUBLAS_GEMM_ALGO11_TENSOR_OP`* | |
| 112 |*`CUBLAS_GEMM_ALGO12_TENSOR_OP`* | |
| 113 |*`CUBLAS_GEMM_ALGO13_TENSOR_OP`* | |
| 114 |*`CUBLAS_GEMM_ALGO14_TENSOR_OP`* | |
| 115 |*`CUBLAS_GEMM_ALGO15_TENSOR_OP`* | |
| enum |***`cublasMath_t`*** | |
| 0 |*`CUBLAS_DEFAULT_MATH`* | |
| 1 |*`CUBLAS_TENSOR_OP_MATH`* | |
| enum* |`cublasDataType_t` | |
| struct |`cublasContext` | |
| struct* |`cublasHandle_t` |`hipblasHandle_t` |
## **2. CUBLAS API functions**
| **CUDA** | **HIP** |
|-----------------------------------------------------------|-------------------------------------------------|
|`cublasCreate` |`hipblasCreate` |
|`cublasCreate_v2` |`hipblasCreate` |
|`cublasDestroy` |`hipblasDestroy` |
|`cublasDestroy_v2` |`hipblasDestroy` |
|`cublasGetVersion` | |
|`cublasGetVersion_v2` | |
|`cublasGetProperty` | |
|`cublasGetStream` |`hipblasGetStream` |
|`cublasGetStream_v2` |`hipblasGetStream_v2` |
|`cublasSetStream` |`hipblasSetStream` |
|`cublasSetStream_v2` |`hipblasSetStream_v2` |
|`cublasGetPointerMode` |`hipblasGetPointerMode` |
|`cublasGetPointerMode_v2` |`hipblasGetPointerMode_v2` |
|`cublasSetPointerMode` |`hipblasSetPointerMode` |
|`cublasSetPointerMode_v2` |`hipblasSetPointerMode_v2` |
|`cublasGetAtomicsMode` | |
|`cublasSetAtomicsMode` | |
|`cublasGetMathMode` | |
|`cublasSetMathMode` | |
|`cublasLogCallback` | |
|`cublasLoggerConfigure` | |
|`cublasSetLoggerCallback` | |
|`cublasGetLoggerCallback` | |
|`cublasSetVector` |`hipblasSetVector` |
|`cublasGetVector` |`hipblasGetVector` |
|`cublasSetMatrix` |`hipblasSetMatrix` |
|`cublasGetMatrix` |`hipblasGetMatrix` |
|`cublasSetVectorAsync` | |
|`cublasGetVectorAsync` | |
|`cublasSetMatrixAsync` | |
|`cublasGetMatrixAsync` | |
|`cublasXerbla` | |
|`cublasNrm2Ex` | |
|`cublasSnrm2` |`hipblasSnrm2` |
|`cublasSnrm2_v2` |`hipblasSnrm2` |
|`cublasDnrm2` |`hipblasDnrm2` |
|`cublasDnrm2_v2` |`hipblasDnrm2` |
|`cublasScnrm2` | |
|`cublasScnrm2_v2` | |
|`cublasDznrm2` | |
|`cublasDznrm2_v2` | |
|`cublasDotEx` | |
|`cublasDotcEx` | |
|`cublasSdot` |`hipblasSdot` |
|`cublasSdot_v2` |`hipblasSdot` |
|`cublasDdot` |`hipblasDdot` |
|`cublasDdot_v2` |`hipblasDdot` |
|`cublasCdotu` | |
|`cublasCdotu_v2` | |
|`cublasCdotc` | |
|`cublasCdotc_v2` | |
|`cublasZdotu` | |
|`cublasZdotu_v2` | |
|`cublasZdotc` | |
|`cublasZdotc_v2` | |
|`cublasScalEx` | |
|`cublasSscal` |`hipblasSscal` |
|`cublasSscal_v2` |`hipblasSscal` |
|`cublasDscal` |`hipblasDscal` |
|`cublasDscal_v2` |`hipblasDscal` |
|`cublasCscal` | |
|`cublasCscal_v2` | |
|`cublasCsscal` | |
|`cublasCsscal_v2` | |
|`cublasZscal` | |
|`cublasZscal_v2` | |
|`cublasZdscal` | |
|`cublasZdscal_v2` | |
|`cublasAxpyEx` | |
|`cublasSaxpy` |`hipblasSaxpy` |
|`cublasSaxpy_v2` |`hipblasSaxpy` |
|`cublasDaxpy` |`hipblasDaxpy` |
|`cublasDaxpy_v2` |`hipblasDaxpy` |
|`cublasCaxpy` | |
|`cublasCaxpy_v2` | |
|`cublasZaxpy` | |
|`cublasZaxpy_v2` | |
|`cublasScopy` |`hipblasScopy` |
|`cublasScopy_v2` |`hipblasScopy` |
|`cublasDcopy` |`hipblasDcopy` |
|`cublasDcopy_v2` |`hipblasDcopy` |
|`cublasCcopy` | |
|`cublasCcopy_v2` | |
|`cublasZcopy` | |
|`cublasZcopy_v2` | |
|`cublasSswap` | |
|`cublasSswap_v2` | |
|`cublasDswap` | |
|`cublasDswap_v2` | |
|`cublasCswap` | |
|`cublasCswap_v2` | |
|`cublasZswap` | |
|`cublasZswap_v2` | |
|`cublasIsamax` |`hipblasIsamax` |
|`cublasIsamax_v2` |`hipblasIsamax` |
|`cublasIdamax` |`hipblasIdamax` |
|`cublasIdamax_v2` |`hipblasIdamax` |
|`cublasIcamax` | |
|`cublasIcamax_v2` | |
|`cublasIzamax` | |
|`cublasIzamax_v2` | |
|`cublasIsamin` | |
|`cublasIsamin_v2` | |
|`cublasIdamin` | |
|`cublasIdamin_v2` | |
|`cublasIcamin` | |
|`cublasIcamin_v2` | |
|`cublasIzamin` | |
|`cublasIzamin_v2` | |
|`cublasSasum` |`hipblasSasum` |
|`cublasSasum_v2` |`hipblasSasum` |
|`cublasDasum` |`hipblasDasum` |
|`cublasDasum_v2` |`hipblasDasum` |
|`cublasScasum` | |
|`cublasScasum_v2` | |
|`cublasDzasum` | |
|`cublasDzasum_v2` | |
|`cublasSrot` | |
|`cublasSrot_v2` | |
|`cublasDrot` | |
|`cublasDrot_v2` | |
|`cublasCrot` | |
|`cublasCrot_v2` | |
|`cublasZrot` | |
|`cublasZrot_v2` | |
|`cublasZdrot` | |
|`cublasZdrot_v2` | |
|`cublasSrotg` | |
|`cublasSrotg_v2` | |
|`cublasDrotg` | |
|`cublasDrotg_v2` | |
|`cublasCrotg` | |
|`cublasCrotg_v2` | |
|`cublasZrotg` | |
|`cublasZrotg_v2` | |
|`cublasSrotm` | |
|`cublasSrotm_v2` | |
|`cublasDrotm` | |
|`cublasDrotm_v2` | |
|`cublasSrotmg` | |
|`cublasSrotmg_v2` | |
|`cublasDrotmg` | |
|`cublasDrotmg_v2` | |
|`cublasSgemv` |`hipblasSgemv` |
|`cublasSgemv_v2` |`hipblasSgemv` |
|`cublasDgemv` |`hipblasDgemv` |
|`cublasDgemv_v2` |`hipblasDgemv` |
|`cublasCgemv` | |
|`cublasCgemv_v2` | |
|`cublasZgemv` | |
|`cublasZgemv_v2` | |
|`cublasSgbmv` | |
|`cublasSgbmv_v2` | |
|`cublasDgbmv` | |
|`cublasDgbmv_v2` | |
|`cublasCgbmv` | |
|`cublasCgbmv_v2` | |
|`cublasZgbmv` | |
|`cublasZgbmv_v2` | |
|`cublasStrmv` | |
|`cublasStrmv_v2` | |
|`cublasDtrmv` | |
|`cublasDtrmv_v2` | |
|`cublasCtrmv` | |
|`cublasCtrmv_v2` | |
|`cublasZtrmv` | |
|`cublasZtrmv_v2` | |
|`cublasStbmv` | |
|`cublasStbmv_v2` | |
|`cublasDtbmv` | |
|`cublasDtbmv_v2` | |
|`cublasCtbmv` | |
|`cublasCtbmv_v2` | |
|`cublasZtbmv` | |
|`cublasZtbmv_v2` | |
|`cublasStpmv` | |
|`cublasStpmv_v2` | |
|`cublasDtpmv` | |
|`cublasDtpmv_v2` | |
|`cublasCtpmv` | |
|`cublasCtpmv_v2` | |
|`cublasZtpmv` | |
|`cublasZtpmv_v2` | |
|`cublasStrsv` | |
|`cublasStrsv_v2` | |
|`cublasDtrsv` | |
|`cublasDtrsv_v2` | |
|`cublasCtrsv` | |
|`cublasCtrsv_v2` | |
|`cublasZtrsv` | |
|`cublasZtrsv_v2` | |
|`cublasStpsv` | |
|`cublasStpsv_v2` | |
|`cublasDtpsv` | |
|`cublasDtpsv_v2` | |
|`cublasCtpsv` | |
|`cublasCtpsv_v2` | |
|`cublasZtpsv` | |
|`cublasZtpsv_v2` | |
|`cublasStbsv` | |
|`cublasStbsv_v2` | |
|`cublasDtbsv` | |
|`cublasDtbsv_v2` | |
|`cublasCtbsv` | |
|`cublasCtbsv_v2` | |
|`cublasZtbsv` | |
|`cublasZtbsv_v2` | |
|`cublasSsymv` | |
|`cublasSsymv_v2` | |
|`cublasDsymv` | |
|`cublasDsymv_v2` | |
|`cublasCsymv` | |
|`cublasCsymv_v2` | |
|`cublasZsymv` | |
|`cublasZsymv_v2` | |
|`cublasChemv` | |
|`cublasChemv_v2` | |
|`cublasZhemv` | |
|`cublasZhemv_v2` | |
|`cublasSsbmv` | |
|`cublasSsbmv_v2` | |
|`cublasDsbmv` | |
|`cublasDsbmv_v2` | |
|`cublasChbmv` | |
|`cublasChbmv_v2` | |
|`cublasZhbmv` | |
|`cublasZhbmv_v2` | |
|`cublasSspmv` | |
|`cublasSspmv_v2` | |
|`cublasDspmv` | |
|`cublasDspmv_v2` | |
|`cublasChpmv` | |
|`cublasChpmv_v2` | |
|`cublasZhpmv` | |
|`cublasZhpmv_v2` | |
|`cublasSger` |`hipblasSger` |
|`cublasSger_v2` |`hipblasSger` |
|`cublasDger` |`hipblasDger` |
|`cublasDger_v2` |`hipblasDger` |
|`cublasCgeru` | |
|`cublasCgeru_v2` | |
|`cublasCgerc` | |
|`cublasCgerc_v2` | |
|`cublasZgeru` | |
|`cublasZgeru_v2` | |
|`cublasZgerc` | |
|`cublasZgerc_v2` | |
|`cublasSsyr` | |
|`cublasSsyr_v2` | |
|`cublasDsyr` | |
|`cublasDsyr_v2` | |
|`cublasCsyr` | |
|`cublasCsyr_v2` | |
|`cublasZsyr` | |
|`cublasZsyr_v2` | |
|`cublasCher` | |
|`cublasCher_v2` | |
|`cublasZher` | |
|`cublasZher_v2` | |
|`cublasSspr` | |
|`cublasSspr_v2` | |
|`cublasDspr` | |
|`cublasDspr_v2` | |
|`cublasChpr` | |
|`cublasChpr_v2` | |
|`cublasZhpr` | |
|`cublasZhpr_v2` | |
|`cublasSsyr2` | |
|`cublasSsyr2_v2` | |
|`cublasDsyr2` | |
|`cublasDsyr2_v2` | |
|`cublasCsyr2` | |
|`cublasCsyr2_v2` | |
|`cublasZsyr2` | |
|`cublasZsyr2_v2` | |
|`cublasCher2` | |
|`cublasCher2_v2` | |
|`cublasZher2` | |
|`cublasZher2_v2` | |
|`cublasSspr2` | |
|`cublasSspr2_v2` | |
|`cublasDspr2` | |
|`cublasDspr2_v2` | |
|`cublasChpr2` | |
|`cublasChpr2_v2` | |
|`cublasZhpr2` | |
|`cublasZhpr2_v2` | |
|`cublasSgemm` |`hipblasSgemm` |
|`cublasSgemm_v2` |`hipblasSgemm` |
|`cublasDgemm` |`hipblasDgemm` |
|`cublasDgemm_v2` |`hipblasDgemm` |
|`cublasCgemm` |`hipblasCgemm` |
|`cublasCgemm_v2` |`hipblasCgemm` |
|`cublasCgemm3m` | |
|`cublasCgemm3mEx` | |
|`cublasZgemm` | |
|`cublasZgemm_v2` | |
|`cublasZgemm3m` | |
|`cublasHgemm` |`hipblasHgemm` |
|`cublasSgemmEx` | |
|`cublasGemmEx` | |
|`cublasCgemmEx` | |
|`cublasUint8gemmBias` | |
|`cublasSsyrk` | |
|`cublasSsyrk_v2` | |
|`cublasDsyrk` | |
|`cublasDsyrk_v2` | |
|`cublasCsyrk` | |
|`cublasCsyrk_v2` | |
|`cublasZsyrk` | |
|`cublasZsyrk_v2` | |
|`cublasCsyrkEx` | |
|`cublasCsyrk3mEx` | |
|`cublasCherk` | |
|`cublasCherk_v2` | |
|`cublasZherk` | |
|`cublasZherk_v2` | |
|`cublasCherkEx` | |
|`cublasCherk3mEx` | |
|`cublasSsyr2k` | |
|`cublasSsyr2k_v2` | |
|`cublasDsyr2k` | |
|`cublasDsyr2k_v2` | |
|`cublasCsyr2k` | |
|`cublasCsyr2k_v2` | |
|`cublasZsyr2k` | |
|`cublasZsyr2k_v2` | |
|`cublasCher2k` | |
|`cublasCher2k_v2` | |
|`cublasZher2k` | |
|`cublasZher2k_v2` | |
|`cublasSsyrkx` | |
|`cublasDsyrkx` | |
|`cublasCsyrkx` | |
|`cublasZsyrkx` | |
|`cublasCherkx` | |
|`cublasZherkx` | |
|`cublasSsymm` | |
|`cublasSsymm_v2` | |
|`cublasDsymm` | |
|`cublasDsymm_v2` | |
|`cublasCsymm` | |
|`cublasCsymm_v2` | |
|`cublasZsymm` | |
|`cublasZsymm_v2` | |
|`cublasChemm` | |
|`cublasChemm_v2` | |
|`cublasZhemm` | |
|`cublasZhemm_v2` | |
|`cublasStrsm` |`hipblasStrsm` |
|`cublasStrsm_v2` |`hipblasStrsm` |
|`cublasDtrsm` |`hipblasDtrsm` |
|`cublasDtrsm_v2` |`hipblasDtrsm` |
|`cublasCtrsm` | |
|`cublasCtrsm_v2` | |
|`cublasZtrsm` | |
|`cublasZtrsm_v2` | |
|`cublasStrmm` | |
|`cublasStrmm_v2` | |
|`cublasDtrmm` | |
|`cublasDtrmm_v2` | |
|`cublasCtrmm` | |
|`cublasCtrmm_v2` | |
|`cublasZtrmm` | |
|`cublasZtrmm_v2` | |
|`cublasHgemmBatched` | |
|`cublasSgemmBatched` |`hipblasSgemmBatched` |
|`cublasDgemmBatched` |`hipblasDgemmBatched` |
|`cublasCgemmBatched` | |
|`cublasCgemm3mBatched` | |
|`cublasZgemmBatched` | |
|`cublasGemmBatchedEx` | |
|`cublasGemmStridedBatchedEx` | |
|`cublasSgemmStridedBatched` | |
|`cublasDgemmStridedBatched` | |
|`cublasCgemmStridedBatched` | |
|`cublasCgemm3mStridedBatched` | |
|`cublasZgemmStridedBatched` | |
|`cublasHgemmStridedBatched` | |
|`cublasSgeam` |`hipblasSgeam` |
|`cublasDgeam` |`hipblasDgeam` |
|`cublasCgeam` | |
|`cublasZgeam` | |
|`cublasSgetrfBatched` | |
|`cublasDgetrfBatched` | |
|`cublasCgetrfBatched` | |
|`cublasZgetrfBatched` | |
|`cublasSgetriBatched` | |
|`cublasDgetriBatched` | |
|`cublasCgetriBatched` | |
|`cublasZgetriBatched` | |
|`cublasSgetrsBatched` | |
|`cublasDgetrsBatched` | |
|`cublasCgetrsBatched` | |
|`cublasZgetrsBatched` | |
|`cublasStrsmBatched` | |
|`cublasDtrsmBatched` | |
|`cublasCtrsmBatched` | |
|`cublasZtrsmBatched` | |
|`cublasSmatinvBatched` | |
|`cublasDmatinvBatched` | |
|`cublasCmatinvBatched` | |
|`cublasZmatinvBatched` | |
|`cublasSgeqrfBatched` | |
|`cublasDgeqrfBatched` | |
|`cublasCgeqrfBatched` | |
|`cublasZgeqrfBatched` | |
|`cublasSgelsBatched` | |
|`cublasDgelsBatched` | |
|`cublasCgelsBatched` | |
|`cublasZgelsBatched` | |
|`cublasSdgmm` | |
|`cublasDdgmm` | |
|`cublasCdgmm` | |
|`cublasZdgmm` | |
|`cublasStpttr` | |
|`cublasDtpttr` | |
|`cublasCtpttr` | |
|`cublasZtpttr` | |
|`cublasStrttp` | |
|`cublasDtrttp` | |
|`cublasCtrttp` | |
|`cublasZtrttp` | |
@@ -0,0 +1,81 @@
# CUFFT API supported by HIP
## **1. CUFFT Data types**
| **type** | **CUDA** | **HIP** |**HIP value** (if differs) |
|-------------:|---------------------------------------------------------------|------------------------------------------------------------|---------------------------|
| enum |***`cufftResult_t`*** |***`hipfftResult_t`*** |
| enum |***`cufftResult`*** |***`hipfftResult`*** |
| 0x0 |*`CUFFT_SUCCESS`* |*`HIPFFT_SUCCESS`* | 0 |
| 0x1 |*`CUFFT_INVALID_PLAN`* |*`HIPFFT_INVALID_PLAN`* | 1 |
| 0x2 |*`CUFFT_ALLOC_FAILED`* |*`HIPFFT_ALLOC_FAILED`* | 2 |
| 0x3 |*`CUFFT_INVALID_TYPE`* |*`HIPFFT_INVALID_TYPE`* | 3 |
| 0x4 |*`CUFFT_INVALID_VALUE`* |*`HIPFFT_INVALID_VALUE`* | 4 |
| 0x5 |*`CUFFT_INTERNAL_ERROR`* |*`HIPFFT_INTERNAL_ERROR`* | 5 |
| 0x6 |*`CUFFT_EXEC_FAILED`* |*`HIPFFT_EXEC_FAILED`* | 6 |
| 0x7 |*`CUFFT_SETUP_FAILED`* |*`HIPFFT_SETUP_FAILED`* | 7 |
| 0x8 |*`CUFFT_I;NVALID_SIZE`* |*`HIPFFT_INVALID_SIZE`* | 8 |
| 0x9 |*`CUFFT_UNALIGNED_DATA`* |*`HIPFFT_UNALIGNED_DATA`* | 9 |
| 0xA |*`CUFFT_INCOMPLETE_PARAMETER_LIST`* |*`HIPFFT_INCOMPLETE_PARAMETER_LIST`* | 10 |
| 0xB |*`CUFFT_INVALID_DEVICE`* |*`HIPFFT_INVALID_DEVICE`* | 11 |
| 0xC |*`CUFFT_PARSE_ERROR`* |*`HIPFFT_PARSE_ERROR`* | 12 |
| 0xD |*`CUFFT_NO_WORKSPACE`* |*`HIPFFT_NO_WORKSPACE`* | 13 |
| 0xE |*`CUFFT_NOT_IMPLEMENTED`* |*`HIPFFT_NOT_IMPLEMENTED`* | 14 |
| 0xF |*`CUFFT_LICENSE_ERROR`* | |
| 0x10 |*`CUFFT_NOT_SUPPORTED`* |*`HIPFFT_NOT_SUPPORTED`* | 16 |
| float |***`cufftReal`*** |***`hipfftReal`*** |
| double |***`cufftDoubleReal`*** |***`hipfftDoubleReal`*** |
| float2 |***`cufftComplex`*** |***`hipfftComplex`*** |
| double2 |***`cufftDoubleComplex`*** |***`hipfftDoubleComplex`*** |
| define |`CUFFT_FORWARD` |`HIPFFT_FORWARD` |
| define |`CUFFT_INVERSE` |`HIPFFT_BACKWARD` |
| enum |***`cufftType_t`*** |***`hipfftType_t`*** |
| enum |***`cufftType`*** |***`hipfftType`*** |
| 0x2a |*`CUFFT_R2C`* |*`HIPFFT_R2C`* |
| 0x2c |*`CUFFT_C2R`* |*`HIPFFT_C2R`* |
| 0x29 |*`CUFFT_C2C`* |*`HIPFFT_C2C`* |
| 0x6a |*`CUFFT_D2Z`* |*`HIPFFT_D2Z`* |
| 0x6c |*`CUFFT_Z2D`* |*`HIPFFT_Z2D`* |
| 0x69 |*`CUFFT_Z2Z`* |*`HIPFFT_Z2Z`* |
| enum |***`cufftCompatibility_t`*** | |
| enum |***`cufftCompatibility`*** | |
| 0x01 |*`CUFFT_COMPATIBILITY_FFTW_PADDING`* | |
| define |`CUFFT_COMPATIBILITY_DEFAULT` | |
| int |***`cufftHandle`*** |***`hipfftHandle`*** |
## **2. CUFFT API functions**
| **CUDA** | **HIP** |
|-----------------------------------------------------------|-------------------------------------------------|
|`cufftPlan1d` |`hipfftPlan1d` |
|`cufftPlan2d` |`hipfftPlan2d` |
|`cufftPlan3d` |`hipfftPlan3d` |
|`cufftPlanMany` |`hipfftPlanMany` |
|`cufftMakePlan1d` |`hipfftMakePlan1d` |
|`cufftMakePlan2d` |`hipfftMakePlan2d` |
|`cufftMakePlan3d` |`hipfftMakePlan3d` |
|`cufftMakePlanMany` |`hipfftMakePlanMany` |
|`cufftMakePlanMany64` |`hipfftMakePlanMany64` |
|`cufftGetSizeMany64` |`hipfftGetSizeMany64` |
|`cufftEstimate1d` |`hipfftEstimate1d` |
|`cufftEstimate2d` |`hipfftEstimate2d` |
|`cufftEstimate3d` |`hipfftEstimate3d` |
|`cufftEstimateMany` |`hipfftEstimateMany` |
|`cufftCreate` |`hipfftCreate` |
|`cufftGetSize1d` |`hipfftGetSize1d` |
|`cufftGetSize2d` |`hipfftGetSize2d` |
|`cufftGetSize3d` |`hipfftGetSize3d` |
|`cufftGetSizeMany` |`hipfftGetSizeMany` |
|`cufftGetSize` |`hipfftGetSize` |
|`cufftSetWorkArea` |`hipfftSetWorkArea` |
|`cufftSetAutoAllocation` |`hipfftSetAutoAllocation` |
|`cufftExecC2C` |`hipfftExecC2C` |
|`cufftExecR2C` |`hipfftExecR2C` |
|`cufftExecC2R` |`hipfftExecC2R` |
|`cufftExecZ2Z` |`hipfftExecZ2Z` |
|`cufftExecD2Z` |`hipfftExecD2Z` |
|`cufftExecZ2D` |`hipfftExecZ2D` |
|`cufftSetStream` |`hipfftSetStream` |
|`cufftDestroy` |`hipfftDestroy` |
|`cufftGetVersion` |`hipfftGetVersion` |
|`cufftGetProperty` | |
@@ -0,0 +1,37 @@
# cuComplex API supported by HIP
## **1. cuComplex Data types**
| **type** | **CUDA** | **HIP** |**HIP value** (if differs) |
|-------------:|---------------------------------------------------------------|------------------------------------------------------------|---------------------------|
| float2 |***`cuFloatComplex`*** |***`hipFloatComplex`*** | struct |
| double2 |***`cuDoubleComplex`*** |***`hipDoubleComplex`*** | struct |
| float2 |***`cuComplex`*** |***`hipComplex`*** | struct |
## **2. cuComplex API functions**
| **CUDA** | **HIP** |
|-----------------------------------------------------------|-------------------------------------------------|
|`cuCrealf` |`hipCrealf` |
|`cuCimagf` |`hipCimagf` |
|`make_cuFloatComplex` |`make_hipFloatComplex` |
|`cuConjf` |`hipConjf` |
|`cuCaddf` |`hipCaddf` |
|`cuCsubf` |`hipCsubf` |
|`cuCmulf` |`hipCmulf` |
|`cuCdivf` |`hipCdivf` |
|`cuCabsf` |`hipCabsf` |
|`cuCreal` |`hipCreal` |
|`cuCimag` |`hipCimag` |
|`make_cuDoubleComplex` |`make_hipDoubleComplex` |
|`cuConj` |`hipConj` |
|`cuCadd` |`hipCadd` |
|`cuCsub` |`hipCsub` |
|`cuCmul` |`hipCmul` |
|`cuCdiv` |`hipCdiv` |
|`cuCabs` |`hipCabs` |
|`make_cuComplex` |`make_hipComplex` |
|`cuComplexFloatToDouble` |`hipComplexFloatToDouble` |
|`cuComplexDoubleToFloat` |`hipComplexDoubleToFloat` |
|`cuCfmaf` |`hipCfmaf` |
|`cuCfma` |`hipCfma` |
+9
View File
@@ -102,6 +102,15 @@ hip-clang links device code from different translation units together. For each
hip-clang generates initializatiion and termination functions for each translation unit for host code compilation. The initialization functions call `__hipRegisterFatBinary` to register the fatbinary embeded in the ELF file. They also call `__hipRegisterFunction` and `__hipRegisterVar` to register kernel functions and device side global variables. The termination functions call `__hipUnregisterFatBinary`.
hip-clang emits a global variable `__hip_gpubin_handle` of void** type with linkonce linkage and inital value 0 for each host translation unit. Each initialization function checks `__hip_gpubin_handle` and register the fatbinary only if `__hip_gpubin_handle` is 0 and saves the return value of `__hip_gpubin_handle` to `__hip_gpubin_handle`. This is to guarantee that the fatbinary is only registered once. Similar check is done in the termination functions.
#### Kernel Launching
hip-clang supports kernel launching by CUDA `<<<>>>` syntax, hipLaunchKernel, and hipLaunchKernelGGL. The latter two are macros which expand to CUDA `<<<>>>` syntax.
In host code, hip-clang emits a stub function with the same name and arguments as the kernel. In the body of this function, hipSetupArgument is called for each kernel argument, then hipLaunchByPtr is called with a function pointer to the stub function.
When the executable or shared library is loaded by the dynamic linker, the initilization functions are called. In the initialization functions, when `__hipRegisterFatBinary` is called, the code objects containing all kernels are loaded; when `__hipRegisterFunction` is called, the stub functions are associated with the corresponding kernels in code objects.
In the host code, for the `<<<>>>` statement, hip-clang first emits call of hipConfigureCall to set up the threads and grids, then emits call of the stub function with the given arguments. In the stub function, when the runtime host API function hipLaunchByPtr is called, the real kernel associated with the stub function is launched.
### NVCC Implementation Notes
#### Interoperation between HIP and CUDA Driver
+26 -18
View File
@@ -13,7 +13,7 @@ and provides practical suggestions on how to port CUDA code and work through com
* [Converting a project "in-place"](#converting-a-project-in-place)
- [Distinguishing Compiler Modes](#distinguishing-compiler-modes)
* [Identifying HIP Target Platform](#identifying-hip-target-platform)
* [Identifying the Compiler: hcc or nvcc](#identifying-the-compiler-hcc-or-nvcc)
* [Identifying the Compiler: hcc, hip-clang, or nvcc](#identifying-the-compiler-hcc-hip-clang-or-nvcc)
* [Identifying Current Compilation Pass: Host or Device](#identifying-current-compilation-pass-host-or-device)
* [Compiler Defines: Summary](#compiler-defines-summary)
- [Identifying Architecture Features](#identifying-architecture-features)
@@ -137,13 +137,18 @@ All HIP projects target either the hcc or nvcc platform. The platform affects wh
Many projects use a mixture of an accelerator compiler (hcc or nvcc) and a standard compiler (e.g., g++). These defines are set for both accelerator and standard compilers and thus are often the best option when writing code that uses conditional compilation.
### Identifying the Compiler: hcc or nvcc
Often, it’s useful to know whether the underlying compiler is hcc or nvcc. This knowledge can guard platform-specific code (features that only work on the nvcc or hcc path but not both) or aid in platform-specific performance tuning.
### Identifying the Compiler: hcc, hip-clang or nvcc
Often, it’s useful to know whether the underlying compiler is hcc, hip-clang or nvcc. This knowledge can guard platform-specific code (features that only work on the nvcc, hip-clang or hcc path but not all) or aid in platform-specific performance tuning.
```
#ifdef __HCC__
// Compiled with hcc
```
```
#ifdef __HIP__
// Compiled with hip-clang
```
```
@@ -159,9 +164,9 @@ Often, it’s useful to know whether the underlying compiler is hcc or nvcc. This
// Compiled with nvcc (Cuda language extensions enabled)
```
hcc directly generates the host code (using the Clang x86 target) and passes the code to another host compiler. Thus, it lacks the equivalent of the \__CUDA_ACC define.
hcc and hip-clang directly generates the host code (using the Clang x86 target) and passes the code to another host compiler. Thus, it lacks the equivalent of the \__CUDA_ACC define.
The macro `__HIPCC__` is set if either `__HCC__` or `__CUDACC__` is defined. This configuration is useful in determining when code is being compiled using an accelerator-enabled compiler (hcc or nvcc) as opposed to a standard host compiler (GCC, ICC, Clang, etc.).
The macro `__HIPCC__` is set if either `__HCC__`, `__HIP__` or `__CUDACC__` is defined. This configuration is useful in determining when code is being compiled using an accelerator-enabled compiler (hcc or nvcc) as opposed to a standard host compiler (GCC, ICC, Clang, etc.).
### Identifying Current Compilation Pass: Host or Device
@@ -176,22 +181,25 @@ Unlike `__CUDA_ARCH__`, the `__HIP_DEVICE_COMPILE__` value is 1 or undefined, an
### Compiler Defines: Summary
|Define | hcc | nvcc | Other (GCC, ICC, Clang, etc.)
|--- | --- | --- |---|
|Define | hcc | hip-clang | nvcc | Other (GCC, ICC, Clang, etc.)
|--- | --- | --- | --- |---|
|HIP-related defines:|
|`__HIP_PLATFORM_HCC___`| Defined | Undefined | Defined if targeting hcc platform; undefined otherwise |
|`__HIP_PLATFORM_NVCC___`| Undefined | Defined | Defined if targeting nvcc platform; undefined otherwise |
|`__HIP_DEVICE_COMPILE__` | 1 if compiling for device; undefined if compiling for host |1 if compiling for device; undefined if compiling for host | Undefined
|`__HIPCC__` | Defined | Defined | Undefined
|`__HIP_ARCH_*` | 0 or 1 depending on feature support (see below) | 0 or 1 depending on feature support (see below) | 0
|`__HIP_PLATFORM_HCC___`| Defined | Defined | Undefined | Defined if targeting hcc platform; undefined otherwise |
|`__HIP_PLATFORM_NVCC___`| Undefined | Undefined | Defined | Defined if targeting nvcc platform; undefined otherwise |
|`__HIP_DEVICE_COMPILE__` | 1 if compiling for device; undefined if compiling for host | 1 if compiling for device; undefined if compiling for host |1 if compiling for device; undefined if compiling for host | Undefined
|`__HIPCC__` | Defined | Defined | Defined | Undefined
|`__HIP_ARCH_*` | 0 or 1 depending on feature support (see below) |0 or 1 depending on feature support (see below) | 0 or 1 depending on feature support (see below) | 0
|nvcc-related defines:|
|`__CUDACC__` | Undefined | Defined if source code is compiled by nvcc; undefined otherwise | Undefined
|`__NVCC__` | Undefined | Defined | Undefined
|`__CUDA_ARCH__` | Undefined | Unsigned representing compute capability (e.g., "130") if in device code; 0 if in host code | Undefined
|`__CUDACC__` | Undefined | Undefined | Defined if source code is compiled by nvcc; undefined otherwise | Undefined
|`__NVCC__` | Undefined | Undefined | Defined | Undefined
|`__CUDA_ARCH__` | Undefined | Undefined | Unsigned representing compute capability (e.g., "130") if in device code; 0 if in host code | Undefined
|hcc-related defines:|
|`__HCC__` | Defined | Undefined | Undefined
|`__HCC_ACCELERATOR__` | Nonzero if in device code; otherwise undefined | Undefined | Undefined
|`__clang__` | Defined | Undefined | Defined if using Clang; otherwise undefined
|`__HCC__` | Defined | Undefined | Undefined | Undefined
|`__HCC_ACCELERATOR__` | Nonzero if in device code; otherwise undefined | Undefined | Undefined | Undefined
|hip-clang-related defines:|
|`__HIP__` | Undefined | Defined | Undefined | Undefined
|hcc/hip-clang common defines:|
|`__clang__` | Defined | Defined | Undefined | Defined if using Clang; otherwise undefined
## Identifying Architecture Features
+3 -1
View File
@@ -48,7 +48,9 @@ set_and_check( hip_BIN_INSTALL_DIR "@PACKAGE_BIN_INSTALL_DIR@" )
set_and_check(hip_HIPCC_EXECUTABLE "${hip_BIN_INSTALL_DIR}/hipcc")
set_and_check(hip_HIPCONFIG_EXECUTABLE "${hip_BIN_INSTALL_DIR}/hipconfig")
find_dependency(hcc)
if(HIP_COMPILER STREQUAL "hcc")
find_dependency(hcc)
endif()
include( "${CMAKE_CURRENT_LIST_DIR}/hip-targets.cmake" )
set( hip_LIBRARIES hip::host hip::device)
+38 -25
View File
@@ -6,19 +6,31 @@
<!-- toc -->
- [Using hipify-clang](#using-hipify-clang)
* [Build and install](#build-and-install)
* [Running and using hipify-clang](#running-and-using-hipify-clang)
- [Supported CUDA APIs](#cuda-apis)
- [Dependencies](#dependencies)
- [Build and install](#build-and-install)
* [Building](#building)
* [Testing](#testing)
* [Windows](#windows)
- [Running and using hipify-clang](#running-and-using-hipify-clang)
- [Disclaimer](#disclaimer)
<!-- tocstop -->
## Build and install
## <a name="cuda-apis"></a> Supported CUDA APIs
### Dependencies
- [Runtime API](../docs/markdown/CUDA_Runtime_API_functions_supported_by_HIP.md)
- [Driver API](../docs/markdown/CUDA_Driver_API_functions_supported_by_HIP.md)
- [cuComplex API](../docs/markdown/cuComplex_API_supported_by_HIP.md)
- [cuBLAS](../docs/markdown/CUBLAS_API_supported_by_HIP.md)
- [cuRAND](../docs/markdown/CURAND_API_supported_by_HIP.md)
- [cuDNN](../docs/markdown/CUDNN_API_supported_by_HIP.md)
- [cuFFT](../docs/markdown/CUFFT_API_supported_by_HIP.md)
## <a name="dependencies"></a> Dependencies
`hipify-clang` requires:
1. LLVM+CLANG of at least version 3.8.0, latest stable release is 6.0.0.
1. LLVM+CLANG of at least version 3.8.0, latest stable and recommended release is 6.0.1.
2. CUDA at least version 7.5, latest supported release is 9.0.
| **LLVM release version** | **CUDA latest supported version** |
@@ -38,10 +50,11 @@
In most cases, you can get a suitable version of LLVM+CLANG with your package manager.
Failing that or having multiple versions of LLVM, you can [download a release archive](http://releases.llvm.org/), build or install it, and set
[CMAKE_PREFIX_PATH](https://cmake.org/cmake/help/v3.0/variable/CMAKE_PREFIX_PATH.html) so `cmake` can find it; for instance: `-DCMAKE_PREFIX_PATH=f:\LLVM\6.0.0\dist`
[CMAKE_PREFIX_PATH](https://cmake.org/cmake/help/v3.10/variable/CMAKE_PREFIX_PATH.html) so `cmake` can find it; for instance: `-DCMAKE_PREFIX_PATH=f:\LLVM\6.0.1\dist`
### Build
## <a name="build-and-install"></a> Build and install
### <a name="building"></a> Build
Assuming this repository is at `./HIP`:
@@ -64,14 +77,14 @@ Debug build type `-DCMAKE_BUILD_TYPE=Debug` is also supported and tested, `LLVM+
The binary can then be found at `./dist/bin/hipify-clang`.
### Test
### <a name="testing"></a> Test
`hipify-clang` has unit tests using LLVM [`lit`](https://llvm.org/docs/CommandGuide/lit.html)/[`FileCheck`](https://llvm.org/docs/CommandGuide/FileCheck.html).
**LLVM+CLANG should be built from sources, Pre-Built Binaries are not exhaustive for testing.**
To run it:
1. Download [`LLVM`](http://releases.llvm.org/6.0.0/llvm-6.0.0.src.tar.xz)+[`CLANG`](http://releases.llvm.org/6.0.0/cfe-6.0.0.src.tar.xz) sources.
1. Download [`LLVM`](http://releases.llvm.org/6.0.1/llvm-6.0.1.src.tar.xz)+[`CLANG`](http://releases.llvm.org/6.0.1/cfe-6.0.1.src.tar.xz) sources.
2. Build [`LLVM+CLANG`](http://llvm.org/docs/CMake.html).
For instance:
```shell
@@ -110,21 +123,21 @@ To run it:
6. Ensure `lit` and `FileCheck` are installed - these are distributed with LLVM.
* installing `lit` into `python` might be required:
`python f:/LLVM/6.0.0/llvm/utils/lit/setup.py install`,
`python f:/LLVM/6.0.1/llvm/utils/lit/setup.py install`,
where `f:/LLVM/6.0.0/llvm` is LLVM sources root directory.
where `f:/LLVM/6.0.1/llvm` is LLVM sources root directory.
* Starting with LLVM 6.0.0 path to llvm-lit.py script should be specified by the `LLVM_EXTERNAL_LIT` option:
* Starting with LLVM 6.0.1 path to llvm-lit.py script should be specified by the `LLVM_EXTERNAL_LIT` option:
`-DLLVM_EXTERNAL_LIT=f:/LLVM/6.0.0/build/Release/bin/llvm-lit.py`,
`-DLLVM_EXTERNAL_LIT=f:/LLVM/6.0.1/build/Release/bin/llvm-lit.py`,
where `f:/LLVM/6.0.0/build/Release` is LLVM build directory.
where `f:/LLVM/6.0.1/build/Release` is LLVM build directory.
7. Build with the `HIPIFY_CLANG_TESTS` option turned on: -DHIPIFY_CLANG_TESTS=1.
8. `make test-hipify`
On Windows after `cmake` the project `test-hipify` in the generated `hipify-clang.sln` should be built by `Visual Studio 15 2017` instead of `make test-hipify`.
### Windows
### <a name="windows"></a >Windows
On Windows the following configurations are tested:
@@ -144,30 +157,30 @@ cmake
-DHIPIFY_CLANG_TESTS=1 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=../dist \
-DCMAKE_PREFIX_PATH=f:/LLVM/6.0.0/dist \
-DCMAKE_PREFIX_PATH=f:/LLVM/6.0.1/dist \
-DCUDA_TOOLKIT_ROOT_DIR="c:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0" \
-DCUDA_SDK_ROOT_DIR="c:/ProgramData/NVIDIA Corporation/CUDA Samples/v9.0" \
-DCUDA_DNN_ROOT_DIR=f:/CUDNN/cudnn-9.0-windows10-x64-v7.1 \
-DLLVM_EXTERNAL_LIT=f:/LLVM/6.0.0/build/Release/bin/llvm-lit.py \
-DLLVM_EXTERNAL_LIT=f:/LLVM/6.0.1/build/Release/bin/llvm-lit.py \
-Thost=x64
..
```
A corresponding successful output:
```shell
-- Found LLVM 6.0.0:
-- - CMake module path: F:/LLVM/6.0.0/dist/lib/cmake/llvm
-- - Include path : F:/LLVM/6.0.0/dist/include
-- - Binary path : F:/LLVM/6.0.0/dist/bin
-- Found LLVM 6.0.1:
-- - CMake module path: F:/LLVM/6.0.1/dist/lib/cmake/llvm
-- - Include path : F:/LLVM/6.0.1/dist/include
-- - Binary path : F:/LLVM/6.0.1/dist/bin
-- Found PythonInterp: C:/Program Files/Python36/python.exe (found suitable version "3.6.4", minimum required is "2.7")
-- Found lit: C:/Program Files/Python36/Scripts/lit.exe
-- Found FileCheck: F:/LLVM/6.0.0/dist/bin/FileCheck.exe
-- Found FileCheck: F:/LLVM/6.0.1/dist/bin/FileCheck.exe
-- Found CUDA: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0 (found version "9.0")
-- Configuring done
-- Generating done
-- Build files have been written to: f:/HIP/hipify-clang/build
```
## Running and using hipify-clang
## <a name="running-and-using-hipify-clang"></a> Running and using hipify-clang
To process a file, `hipify-clang` needs access to the same headers that would be needed to compile it with clang.
@@ -188,7 +201,7 @@ may be useful.
For a list of `hipify-clang` options, run `hipify-clang --help`.
## Disclaimer
## <a name="disclaimer"></a> Disclaimer
The information contained herein is for informational purposes only, and is subject to change without notice. While every precaution has been taken in the preparation of this document, it may contain technical inaccuracies, omissions and typographical errors, and AMD is under no obligation to update or otherwise correct this information. Advanced Micro Devices, Inc. makes no representations or warranties with respect to the accuracy or completeness of the contents of this document, and assumes no liability of any kind, including the implied warranties of noninfringement, merchantability or fitness for particular purposes, with respect to the operation or use of AMD hardware, software or other products described herein. No license, including implied or arising by estoppel, to any intellectual property rights is granted by this document. Terms and limitations applicable to the purchase or use of AMD's products are as set forth in a signed agreement between the parties or in AMD's Standard Terms and Conditions of Sale.
File diff suppressed because it is too large Load Diff
+8
View File
@@ -164,6 +164,14 @@ bool HipifyAction::Exclude(const hipCounter & hipToken) {
if (insertedDNNHeader) { return true; }
insertedDNNHeader = true;
return false;
case API_FFT:
if (insertedFFTHeader) { return true; }
insertedFFTHeader = true;
return false;
case API_COMPLEX:
if (insertedComplexHeader) { return true; }
insertedComplexHeader = true;
return false;
default:
return false;
}
+2
View File
@@ -28,6 +28,8 @@ private:
bool insertedRANDHeader = false;
bool insertedRAND_kernelHeader = false;
bool insertedDNNHeader = false;
bool insertedFFTHeader = false;
bool insertedComplexHeader = false;
bool firstHeader = false;
bool pragmaOnce = false;
clang::SourceLocation firstHeaderLoc;
+2 -2
View File
@@ -8,13 +8,13 @@ const char *counterNames[NUM_CONV_TYPES] = {
"version", "init", "device", "mem", "kern", "coord_func", "math_func", "device_func",
"special_func", "stream", "event", "occupancy", "ctx", "peer", "module",
"cache", "exec", "err", "def", "tex", "gl", "graphics",
"surface", "jit", "d3d9", "d3d10", "d3d11", "vdpau", "egl",
"surface", "jit", "d3d9", "d3d10", "d3d11", "vdpau", "egl", "complex",
"thread", "other", "include", "include_cuda_main_header", "type", "literal",
"numeric_literal"
};
const char *apiNames[NUM_API_TYPES] = {
"CUDA Driver API", "CUDA RT API", "CUBLAS API", "CURAND API", "CUDNN API"
"CUDA Driver API", "CUDA RT API", "CUBLAS API", "CURAND API", "CUDNN API", "CUFFT API", "cuComplex API"
};
namespace {
+3
View File
@@ -40,6 +40,7 @@ enum ConvTypes {
CONV_D3D11,
CONV_VDPAU,
CONV_EGL,
CONV_COMPLEX,
CONV_THREAD,
CONV_OTHER,
CONV_INCLUDE,
@@ -57,6 +58,8 @@ enum ApiTypes {
API_BLAS,
API_RAND,
API_DNN,
API_FFT,
API_COMPLEX,
API_LAST
};
constexpr int NUM_API_TYPES = (int) ApiTypes::API_LAST;
+70 -63
View File
@@ -32,9 +32,6 @@ THE SOFTWARE.
#include <hip/hcc_detail/llvm_intrinsics.h>
#include <stddef.h>
typedef unsigned long ulong;
typedef unsigned int uint;
/*
Integer Intrinsics
*/
@@ -47,78 +44,68 @@ __device__ static inline unsigned int __popcll(unsigned long long int input) {
return __builtin_popcountl(input);
}
__device__ static inline unsigned int __clz(unsigned int input) {
#ifdef NVCC_COMPAT
return input == 0 ? 32 : __builtin_clz(input);
#else
return input == 0 ? -1 : __builtin_clz(input);
#endif
__device__ static inline int __clz(int input) {
return __ockl_clz_u32((uint)input);
}
__device__ static inline unsigned int __clzll(unsigned long long int input) {
#ifdef NVCC_COMPAT
return input == 0 ? 64 : ( input == 0 ? -1 : __builtin_clzl(input) );
#else
return input == 0 ? -1 : __builtin_clzl(input);
#endif
}
__device__ static inline unsigned int __clz(int input) {
#ifdef NVCC_COMPAT
return input == 0 ? 32 : ( input > 0 ? __builtin_clz(input) : __builtin_clz(~input) );
#else
if (input == 0) return -1;
return input > 0 ? __builtin_clz(input) : __builtin_clz(~input);
#endif
}
__device__ static inline unsigned int __clzll(long long int input) {
#ifdef NVCC_COMPAT
return input == 0 ? 64 : input > 0 ? __builtin_clzl(input) : __builtin_clzl(~input);
#else
if (input == 0) return -1;
return input > 0 ? __builtin_clzl(input) : __builtin_clzl(~input);
#endif
__device__ static inline int __clzll(long long int input) {
return __ockl_clz_u64((ulong)input);
}
__device__ static inline unsigned int __ffs(unsigned int input) {
#ifdef NVCC_COMPAT
return ( input == 0 ? -1 : __builtin_ctz(input) ) + 1;
#else
return input == 0 ? -1 : __builtin_ctz(input);
#endif
}
__device__ static inline unsigned int __ffsll(unsigned long long int input) {
#ifdef NVCC_COMPAT
return ( input == 0 ? -1 : __builtin_ctzl(input) ) + 1;
#else
return input == 0 ? -1 : __builtin_ctzl(input);
#endif
}
__device__ static inline unsigned int __ffs(int input) {
#ifdef NVCC_COMPAT
return ( input == 0 ? -1 : __builtin_ctz(input) ) + 1;
#else
return input == 0 ? -1 : __builtin_ctz(input);
#endif
}
__device__ static inline unsigned int __ffsll(long long int input) {
#ifdef NVCC_COMPAT
return ( input == 0 ? -1 : __builtin_ctzl(input) ) + 1;
#else
return input == 0 ? -1 : __builtin_ctzl(input);
#endif
}
__device__ static inline unsigned int __brev(unsigned int input) { return __llvm_bitrev_b32(input); }
__device__ static inline unsigned int __brev(unsigned int input) {
return __llvm_bitrev_b32(input);
}
__device__ static inline unsigned long long int __brevll(unsigned long long int input) {
return __llvm_bitrev_b64(input);
}
__device__ static inline unsigned int __lastbit_u32_u64(uint64_t input) {
return input == 0 ? -1 : __builtin_ctzl(input);
}
__device__ static inline unsigned int __bitextract_u32(unsigned int src0, unsigned int src1, unsigned int src2) {
uint32_t offset = src1 & 31;
uint32_t width = src2 & 31;
return width == 0 ? 0 : (src0 << (32 - offset - width)) >> (32 - width);
}
__device__ static inline uint64_t __bitextract_u64(uint64_t src0, unsigned int src1, unsigned int src2) {
uint64_t offset = src1 & 63;
uint64_t width = src2 & 63;
return width == 0 ? 0 : (src0 << (64 - offset - width)) >> (64 - width);
}
__device__ static inline unsigned int __bitinsert_u32(unsigned int src0, unsigned int src1, unsigned int src2, unsigned int src3) {
uint32_t offset = src2 & 31;
uint32_t width = src3 & 31;
uint32_t mask = (1 << width) - 1;
return ((src0 & ~(mask << offset)) | ((src1 & mask) << offset));
}
__device__ static inline uint64_t __bitinsert_u64(uint64_t src0, uint64_t src1, unsigned int src2, unsigned int src3) {
uint64_t offset = src2 & 63;
uint64_t width = src3 & 63;
uint64_t mask = (1 << width) - 1;
return ((src0 & ~(mask << offset)) | ((src1 & mask) << offset));
}
__device__ static unsigned int __byte_perm(unsigned int x, unsigned int y, unsigned int s);
__device__ static unsigned int __hadd(int x, int y);
__device__ static int __mul24(int x, int y);
@@ -606,7 +593,7 @@ __device__ static inline double __longlong_as_double(long long int x) {
double tmp;
__builtin_memcpy(&tmp, &x, sizeof(tmp));
return x;
return tmp;
}
__device__ static inline double __uint2double_rn(int x) { return (double)x; }
@@ -645,16 +632,43 @@ __device__ static inline float __ull2float_rz(unsigned long long int x) { return
#ifdef __HCC_OR_HIP_CLANG__
// Clock functions
__device__ long long int __clock64();
__device__ long long int __clock();
__device__ long long int clock64();
__device__ long long int clock();
// hip.amdgcn.bc - named sync
__device__ void __named_sync(int a, int b);
#ifdef __HIP_DEVICE_COMPILE__
// Clock functions
__device__
inline
long long int __clock64() { return (long long int) __builtin_amdgcn_s_memrealtime(); }
#if __HCC__
extern "C" uint64_t __clock_u64() __HC__;
#endif
__device__
inline
long long int __clock() { return (long long int) __builtin_amdgcn_s_memrealtime(); }
inline __attribute((always_inline))
long long int __clock64() {
// ToDo: Unify HCC and HIP implementation.
#if __HCC__
return (long long int) __clock_u64();
#else
return (long long int) __builtin_amdgcn_s_memrealtime();
#endif
}
__device__
inline __attribute((always_inline))
long long int __clock() { return __clock64(); }
__device__
inline __attribute__((always_inline))
long long int clock64() { return __clock64(); }
__device__
inline __attribute__((always_inline))
long long int clock() { return __clock(); }
// hip.amdgcn.bc - named sync
__device__
@@ -673,14 +687,7 @@ int __all(int predicate) {
__device__
inline
int __any(int predicate) {
#ifdef NVCC_COMPAT
if (__ockl_wfany_i32(predicate) != 0)
return 1;
else
return 0;
#else
return __ockl_wfany_i32(predicate);
#endif
}
// XXX from llvm/include/llvm/IR/InstrTypes.h
@@ -30,6 +30,11 @@ THE SOFTWARE.
#include "hip/hcc_detail/host_defines.h"
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
extern "C" __device__ __attribute__((const)) bool __ockl_wfany_i32(int);
extern "C" __device__ __attribute__((const)) bool __ockl_wfall_i32(int);
extern "C" __device__ uint __ockl_activelane_u32(void);
@@ -40,6 +45,11 @@ extern "C" __device__ __attribute__((const)) uint __ockl_mul_hi_u32(uint, uint);
extern "C" __device__ __attribute__((const)) int __ockl_mul_hi_i32(int, int);
extern "C" __device__ __attribute__((const)) uint __ockl_sad_u32(uint, uint, uint);
extern "C" __device__ __attribute__((const)) uchar __ockl_clz_u8(uchar);
extern "C" __device__ __attribute__((const)) ushort __ockl_clz_u16(ushort);
extern "C" __device__ __attribute__((const)) uint __ockl_clz_u32(uint);
extern "C" __device__ __attribute__((const)) ulong __ockl_clz_u64(ulong);
extern "C" __device__ __attribute__((const)) float __ocml_floor_f32(float);
extern "C" __device__ __attribute__((const)) float __ocml_rint_f32(float);
extern "C" __device__ __attribute__((const)) float __ocml_ceil_f32(float);
@@ -51,30 +51,53 @@ inline T round_up_to_next_multiple_nonnegative(T x, T y) {
return tmp - tmp % y;
}
inline std::vector<std::uint8_t> make_kernarg() { return {}; }
inline std::vector<std::uint8_t> make_kernarg(std::vector<std::uint8_t> kernarg) { return kernarg; }
template <typename T>
inline std::vector<std::uint8_t> make_kernarg(std::vector<uint8_t> kernarg, T x) {
kernarg.resize(round_up_to_next_multiple_nonnegative(kernarg.size(), alignof(T)) + sizeof(T));
new (kernarg.data() + kernarg.size() - sizeof(T)) T{std::move(x)};
template <
std::size_t n,
typename... Ts,
typename std::enable_if<n == sizeof...(Ts)>::type* = nullptr>
inline std::vector<std::uint8_t> make_kernarg(
std::vector<std::uint8_t> kernarg, const std::tuple<Ts...>&) {
return kernarg;
}
template <typename T, typename... Ts>
inline std::vector<std::uint8_t> make_kernarg(std::vector<std::uint8_t> kernarg, T x, Ts... xs) {
return make_kernarg(make_kernarg(std::move(kernarg), std::move(x)), std::move(xs)...);
template <
std::size_t n,
typename... Ts,
typename std::enable_if<n != sizeof...(Ts)>::type* = nullptr>
inline std::vector<std::uint8_t> make_kernarg(
std::vector<std::uint8_t> kernarg, const std::tuple<Ts...>& formals) {
using T = typename std::tuple_element<n, std::tuple<Ts...>>::type;
static_assert(
!std::is_reference<T>{},
"A __global__ function cannot have a reference as one of its "
"arguments.");
#if defined(HIP_STRICT)
static_assert(
std::is_trivially_copyable<T>{},
"Only TriviallyCopyable types can be arguments to a __global__ "
"function");
#endif
kernarg.resize(round_up_to_next_multiple_nonnegative(
kernarg.size(), alignof(T)) + sizeof(T));
new (kernarg.data() + kernarg.size() - sizeof(T)) T{std::get<n>(formals)};
return make_kernarg<n + 1>(std::move(kernarg), formals);
}
template <typename... Ts>
inline std::vector<std::uint8_t> make_kernarg(Ts... xs) {
std::vector<std::uint8_t> kernarg;
kernarg.reserve(sizeof(std::tuple<Ts...>));
template <typename... Formals, typename... Actuals>
inline std::vector<std::uint8_t> make_kernarg(
void (*)(Formals...), std::tuple<Actuals...> actuals) {
static_assert(sizeof...(Formals) == sizeof...(Actuals),
"The count of formal arguments must match the count of actuals.");
return make_kernarg(std::move(kernarg), std::move(xs)...);
std::tuple<Formals...> to_formals{std::move(actuals)};
std::vector<std::uint8_t> kernarg;
kernarg.reserve(sizeof(to_formals));
return make_kernarg<0>(std::move(kernarg), to_formals);
}
void hipLaunchKernelGGLImpl(std::uintptr_t function_address, const dim3& numBlocks,
@@ -85,7 +108,8 @@ void hipLaunchKernelGGLImpl(std::uintptr_t function_address, const dim3& numBloc
template <typename... Args, typename F = void (*)(Args...)>
inline void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args) {
auto kernarg = hip_impl::make_kernarg(std::move(args)...);
auto kernarg = hip_impl::make_kernarg(
kernel, std::tuple<Args...>{std::move(args)...});
std::size_t kernarg_size = kernarg.size();
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, kernarg.data(), HIP_LAUNCH_PARAM_BUFFER_SIZE,
@@ -100,4 +124,4 @@ inline void hipLaunchKernel(F kernel, const dim3& numBlocks, const dim3& dimBloc
std::uint32_t groupMemBytes, hipStream_t stream, Args... args) {
hipLaunchKernelGGL(kernel, numBlocks, dimBlocks, groupMemBytes, stream, hipLaunchParm{},
std::move(args)...);
}
}
+3 -3
View File
@@ -121,7 +121,7 @@ THE SOFTWARE.
return ret; \
}
#define MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(ComplexT, T) \
__device__ __host__ ComplexT(T val) : x(val), y(val) {} \
explicit __device__ __host__ ComplexT(T val) : x(val), y(val) {} \
__device__ __host__ ComplexT(T val1, T val2) : x(val1), y(val2) {}
#endif
@@ -131,7 +131,7 @@ struct hipFloatComplex {
public:
typedef float value_type;
__device__ __host__ hipFloatComplex() : x(0.0f), y(0.0f) {}
__device__ __host__ hipFloatComplex(float x) : x(x), y(0.0f) {}
explicit __device__ __host__ hipFloatComplex(float x) : x(x), y(0.0f) {}
__device__ __host__ hipFloatComplex(float x, float y) : x(x), y(y) {}
MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, unsigned short)
MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipFloatComplex, signed short)
@@ -151,7 +151,7 @@ struct hipDoubleComplex {
public:
typedef double value_type;
__device__ __host__ hipDoubleComplex() : x(0.0f), y(0.0f) {}
__device__ __host__ hipDoubleComplex(double x) : x(x), y(0.0f) {}
explicit __device__ __host__ hipDoubleComplex(double x) : x(x), y(0.0f) {}
__device__ __host__ hipDoubleComplex(double x, double y) : x(x), y(y) {}
MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, unsigned short)
MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(hipDoubleComplex, signed short)
+13 -13
View File
@@ -635,37 +635,37 @@ THE SOFTWARE.
// TODO: rounding behaviour is not correct.
// float -> half | half2
inline
__device__
__device__ __host__
__half __float2half(float x)
{
return __half_raw{static_cast<_Float16>(x)};
}
inline
__device__
__device__ __host__
__half __float2half_rn(float x)
{
return __half_raw{static_cast<_Float16>(x)};
}
inline
__device__
__device__ __host__
__half __float2half_rz(float x)
{
return __half_raw{static_cast<_Float16>(x)};
}
inline
__device__
__device__ __host__
__half __float2half_rd(float x)
{
return __half_raw{static_cast<_Float16>(x)};
}
inline
__device__
__device__ __host__
__half __float2half_ru(float x)
{
return __half_raw{static_cast<_Float16>(x)};
}
inline
__device__
__device__ __host__
__half2 __float2half2_rn(float x)
{
return __half2_raw{
@@ -673,14 +673,14 @@ THE SOFTWARE.
static_cast<_Float16>(x), static_cast<_Float16>(x)}};
}
inline
__device__
__device__ __host__
__half2 __floats2half2_rn(float x, float y)
{
return __half2_raw{_Float16_2{
static_cast<_Float16>(x), static_cast<_Float16>(y)}};
}
inline
__device__
__device__ __host__
__half2 __float22half2_rn(float2 x)
{
return __floats2half2_rn(x.x, x.y);
@@ -688,25 +688,25 @@ THE SOFTWARE.
// half | half2 -> float
inline
__device__
__device__ __host__
float __half2float(__half x)
{
return static_cast<__half_raw>(x).data;
}
inline
__device__
__device__ __host__
float __low2float(__half2 x)
{
return static_cast<__half2_raw>(x).data.x;
}
inline
__device__
__device__ __host__
float __high2float(__half2 x)
{
return static_cast<__half2_raw>(x).data.y;
}
inline
__device__
__device__ __host__
float2 __half22float2(__half2 x)
{
return make_float2(
@@ -1633,4 +1633,4 @@ THE SOFTWARE.
#endif // defined(__cplusplus)
#elif defined(__GNUC__)
#include "hip_fp16_gcc.h"
#endif // !defined(__clang__) && defined(__GNUC__)
#endif // !defined(__clang__) && defined(__GNUC__)
+52 -27
View File
@@ -57,8 +57,6 @@ THE SOFTWARE.
#if __HCC_OR_HIP_CLANG__
// Define NVCC_COMPAT for CUDA compatibility
#define NVCC_COMPAT
#define CUDA_SUCCESS hipSuccess
#include <hip/hip_runtime_api.h>
@@ -110,9 +108,9 @@ extern int HIP_TRACE_API;
#include <hip/hcc_detail/host_defines.h>
#include <hip/hcc_detail/device_functions.h>
#include <hip/hcc_detail/surface_functions.h>
#include <hip/hcc_detail/texture_functions.h>
#if __HCC__
#include <hip/hcc_detail/math_functions.h>
#include <hip/hcc_detail/texture_functions.h>
#endif // __HCC__
// TODO-HCC remove old definitions ; ~1602 hcc supports __HCC_ACCELERATOR__ define.
@@ -201,16 +199,6 @@ __device__ int __hip_move_dpp(int src, int dpp_ctrl, int row_mask, int bank_mask
#endif //__HIP_ARCH_GFX803__ == 1
__device__ inline static int min(int arg1, int arg2) {
return (arg1 < arg2) ? arg1 : arg2;
}
__device__ inline static int max(int arg1, int arg2) {
return (arg1 > arg2) ? arg1 : arg2;
}
__host__ inline static int min(int arg1, int arg2) { return std::min(arg1, arg2); }
__host__ inline static int max(int arg1, int arg2) { return std::max(arg1, arg2); }
#endif // __HCC_OR_HIP_CLANG__
#if defined __HCC__
@@ -266,19 +254,16 @@ extern "C" __device__ void* __hip_free(void* ptr);
static inline __device__ void* malloc(size_t size) { return __hip_malloc(size); }
static inline __device__ void* free(void* ptr) { return __hip_free(ptr); }
#ifdef __HCC_ACCELERATOR__
#ifdef HC_FEATURE_PRINTF
#if defined(__HCC_ACCELERATOR__) && defined(HC_FEATURE_PRINTF)
template <typename... All>
static inline __device__ void printf(const char* format, All... all) {
hc::printf(format, all...);
}
#else
#elif defined(__HCC_ACCELERATOR__) || __HIP__
template <typename... All>
static inline __device__ void printf(const char* format, All... all) {}
#endif
#endif
#endif //__HCC_OR_HIP_CLANG__
#ifdef __HCC__
@@ -348,15 +333,18 @@ extern void ihipPostLaunchKernel(const char* kernelName, hipStream_t stream, gri
typedef int hipLaunchParm;
#define hipLaunchKernel(kernelName, numblocks, numthreads, memperblock, streamId, ...) \
do { \
kernelName<<<numblocks, numthreads, memperblock, streamId>>>(0, ##__VA_ARGS__); \
} while (0)
template <typename... Args, typename F = void (*)(Args...)>
inline void hipLaunchKernelGGL(F kernelName, const dim3& numblocks, const dim3& numthreads,
unsigned memperblock, hipStream_t streamId, Args... args) {
kernelName<<<numblocks, numthreads, memperblock, streamId>>>(args...);
}
#define hipLaunchKernelGGL(kernelName, numblocks, numthreads, memperblock, streamId, ...) \
do { \
kernelName<<<numblocks, numthreads, memperblock, streamId>>>(__VA_ARGS__); \
} while (0)
template <typename... Args, typename F = void (*)(hipLaunchParm, Args...)>
inline void hipLaunchKernel(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
std::uint32_t groupMemBytes, hipStream_t stream, Args... args) {
hipLaunchKernelGGL(kernel, numBlocks, dimBlocks, groupMemBytes, stream, hipLaunchParm{},
std::move(args)...);
}
#include <hip/hip_runtime_api.h>
@@ -440,6 +428,34 @@ extern const __device__ __attribute__((weak)) __hip_builtin_gridDim_t gridDim;
#include <hip/hcc_detail/math_functions.h>
#if __HIP_HCC_COMPAT_MODE__
// Define HCC work item functions in terms of HIP builtin variables.
#pragma push_macro("__DEFINE_HCC_FUNC")
#define __DEFINE_HCC_FUNC(hc_fun,hip_var) \
inline __device__ __attribute__((always_inline)) uint hc_get_##hc_fun(uint i) { \
if (i==0) \
return hip_var.x; \
else if(i==1) \
return hip_var.y; \
else \
return hip_var.z; \
}
__DEFINE_HCC_FUNC(workitem_id, threadIdx)
__DEFINE_HCC_FUNC(group_id, blockIdx)
__DEFINE_HCC_FUNC(group_size, blockDim)
__DEFINE_HCC_FUNC(num_groups, gridDim)
#pragma pop_macro("__DEFINE_HCC_FUNC")
extern "C" __device__ __attribute__((const)) size_t __ockl_get_global_id(uint);
inline __device__ __attribute__((always_inline)) uint
hc_get_workitem_absolute_id(int dim)
{
return (uint)__ockl_get_global_id(dim);
}
#endif
// Support std::complex.
#pragma push_macro("__CUDA__")
#define __CUDA__
@@ -447,11 +463,20 @@ extern const __device__ __attribute__((weak)) __hip_builtin_gridDim_t gridDim;
#include <__clang_cuda_complex_builtins.h>
#include <cuda_wrappers/algorithm>
#include <cuda_wrappers/complex>
#include <cuda_wrappers/new>
#undef __CUDA__
#pragma pop_macro("__CUDA__")
#endif
hipError_t hipHccModuleLaunchKernel(hipFunction_t f, uint32_t globalWorkSizeX,
uint32_t globalWorkSizeY, uint32_t globalWorkSizeZ,
uint32_t localWorkSizeX, uint32_t localWorkSizeY,
uint32_t localWorkSizeZ, size_t sharedMemBytes,
hipStream_t hStream, void** kernelParams, void** extra,
hipEvent_t startEvent = nullptr,
hipEvent_t stopEvent = nullptr);
#endif // defined(__clang__) && defined(__HIP__)
#include <hip/hcc_detail/hip_memory.h>
+2 -2
View File
@@ -52,7 +52,7 @@ THE SOFTWARE.
#endif // GENERIC_GRID_LAUNCH
#define __noinline__ __attribute__((noinline))
#define __forceinline__ __attribute__((always_inline))
#define __forceinline__ inline __attribute__((always_inline))
/*
@@ -71,7 +71,7 @@ THE SOFTWARE.
#define __constant__ __attribute__((constant))
#define __noinline__ __attribute__((noinline))
#define __forceinline__ __attribute__((always_inline))
#define __forceinline__ inline __attribute__((always_inline))
#else
+82
View File
@@ -31,6 +31,12 @@ THE SOFTWARE.
#include <limits>
#include <stdint.h>
// HCC's own math functions should be included first, otherwise there will
// be conflicts when hip/math_functions.h is included before hip/hip_runtime.h.
#ifdef __HCC__
#include "kalmar_math.h"
#endif
#pragma push_macro("__DEVICE__")
#pragma push_macro("__RETURN_TYPE")
@@ -1298,6 +1304,66 @@ float func(float x, int y) \
}
__DEF_FLOAT_FUN2I(scalbn)
#if __HCC__
template<class T>
__DEVICE__ inline static T min(T arg1, T arg2) {
return (arg1 < arg2) ? arg1 : arg2;
}
__DEVICE__ inline static uint32_t min(uint32_t arg1, int32_t arg2) {
return min(arg1, (uint32_t) arg2);
}
/*__DEVICE__ inline static uint32_t min(int32_t arg1, uint32_t arg2) {
return min((uint32_t) arg1, arg2);
}
__DEVICE__ inline static uint64_t min(uint64_t arg1, int64_t arg2) {
return min(arg1, (uint64_t) arg2);
}
__DEVICE__ inline static uint64_t min(int64_t arg1, uint64_t arg2) {
return min((uint64_t) arg1, arg2);
}
__DEVICE__ inline static unsigned long long min(unsigned long long arg1, long long arg2) {
return min(arg1, (unsigned long long) arg2);
}
__DEVICE__ inline static unsigned long long min(long long arg1, unsigned long long arg2) {
return min((unsigned long long) arg1, arg2);
}*/
template<class T>
__DEVICE__ inline static T max(T arg1, T arg2) {
return (arg1 > arg2) ? arg1 : arg2;
}
__DEVICE__ inline static uint32_t max(uint32_t arg1, int32_t arg2) {
return max(arg1, (uint32_t) arg2);
}
__DEVICE__ inline static uint32_t max(int32_t arg1, uint32_t arg2) {
return max((uint32_t) arg1, arg2);
}
/*__DEVICE__ inline static uint64_t max(uint64_t arg1, int64_t arg2) {
return max(arg1, (uint64_t) arg2);
}
__DEVICE__ inline static uint64_t max(int64_t arg1, uint64_t arg2) {
return max((uint64_t) arg1, arg2);
}
__DEVICE__ inline static unsigned long long max(unsigned long long arg1, long long arg2) {
return max(arg1, (unsigned long long) arg2);
}
__DEVICE__ inline static unsigned long long max(long long arg1, unsigned long long arg2) {
return max((unsigned long long) arg1, arg2);
}*/
#else
__DEVICE__ inline static int min(int arg1, int arg2) {
return (arg1 < arg2) ? arg1 : arg2;
}
__DEVICE__ inline static int max(int arg1, int arg2) {
return (arg1 > arg2) ? arg1 : arg2;
}
__DEVICE__
inline
float max(float x, float y) {
@@ -1325,6 +1391,17 @@ double min(double x, double y) {
__HIP_OVERLOAD2(double, max)
__HIP_OVERLOAD2(double, min)
#endif
__host__ inline static int min(int arg1, int arg2) {
return std::min(arg1, arg2);
}
__host__ inline static int max(int arg1, int arg2) {
return std::max(arg1, arg2);
}
#pragma pop_macro("__DEF_FLOAT_FUN")
#pragma pop_macro("__DEF_FLOAT_FUN2")
#pragma pop_macro("__DEF_FLOAT_FUN2I")
@@ -1332,3 +1409,8 @@ __HIP_OVERLOAD2(double, min)
#pragma pop_macro("__HIP_OVERLOAD2")
#pragma pop_macro("__DEVICE__")
#pragma pop_macro("__RETURN_TYPE")
// For backward compatibility.
// There are HIP applications e.g. TensorFlow, expecting __HIP_ARCH_* macros
// defined after including math_functions.h.
#include <hip/hcc_detail/hip_runtime.h>
+4 -5
View File
@@ -93,12 +93,11 @@ public:
}
};
const std::unordered_map<hsa_agent_t, std::vector<hsa_executable_t>>& executables(
bool rebuild = false);
const std::unordered_map<hsa_agent_t, std::vector<hsa_executable_t>>& executables();
const std::unordered_map<std::uintptr_t, std::vector<std::pair<hsa_agent_t, Kernel_descriptor>>>&
functions(bool rebuild = false);
const std::unordered_map<std::uintptr_t, std::string>& function_names(bool rebuild = false);
std::unordered_map<std::string, void*>& globals(bool rebuild = false);
functions();
const std::unordered_map<std::uintptr_t, std::string>& function_names();
std::unordered_map<std::string, void*>& globals();
hsa_executable_t load_executable(const std::string& file, hsa_executable_t executable,
hsa_agent_t agent);
File diff suppressed because it is too large Load Diff
+1
View File
@@ -27,6 +27,7 @@ THE SOFTWARE.
// paths to provide a consistent include env and avoid "missing symbol" errors that only appears
// on NVCC path:
#include <hip/hip_common.h>
#if defined(__HIP_PLATFORM_HCC__) && !defined(__HIP_PLATFORM_NVCC__)
#include <hip/hcc_detail/math_functions.h>
+3 -3
View File
@@ -80,7 +80,7 @@ inline void copy_kernel_section_to_fat_binary(const std::string& tmp, const std:
std::find_if(reader.sections.begin(), reader.sections.end(),
[](const ELFIO::section* x) { return x->get_name() == kernel_section(); });
std::ofstream out{output + fat_binary_extension()};
std::ofstream out{output};
if (it == reader.sections.end()) {
std::cerr << "Warning: no kernels were generated; fat binary shall "
@@ -95,8 +95,8 @@ inline void generate_fat_binary(const std::vector<std::string>& sources,
const std::vector<std::string>& targets, const std::string& flags,
const std::string& output) {
static const auto d = [](const std::string* f) { remove(f->c_str()); };
std::unique_ptr<const std::string, decltype(d)> tmp{&output, d};
std::string temp_str = output + ".tmp";
std::unique_ptr<const std::string, decltype(d)> tmp{&temp_str, d};
redi::ipstream hipcc{make_hipcc_call(sources, targets, flags, *tmp), redi::pstream::pstderr};
+14
View File
@@ -7,22 +7,36 @@ set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "hip::hip_hcc_static" for configuration "Release"
set_property(TARGET hip::hip_hcc_static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
if(HIP_COMPILER STREQUAL "clang")
set_target_properties(hip::hip_hcc_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "/opt/rocm/hip/lib/libhip_hcc_static.a"
)
else()
set_target_properties(hip::hip_hcc_static PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "hc_am"
IMPORTED_LOCATION_RELEASE "/opt/rocm/hip/lib/libhip_hcc_static.a"
)
endif()
list(APPEND _IMPORT_CHECK_TARGETS hip::hip_hcc_static )
list(APPEND _IMPORT_CHECK_FILES_FOR_hip::hip_hcc_static "/opt/rocm/hip/lib/libhip_hcc_static.a" )
# Import target "hip::hip_hcc" for configuration "Release"
set_property(TARGET hip::hip_hcc APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
if(HIP_COMPILER STREQUAL "clang")
set_target_properties(hip::hip_hcc PROPERTIES
IMPORTED_LOCATION_RELEASE "/opt/rocm/hip/lib/libhip_hcc.so"
IMPORTED_SONAME_RELEASE "libhip_hcc.so"
)
else()
set_target_properties(hip::hip_hcc PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "hcc::hccrt;hcc::hc_am"
IMPORTED_LOCATION_RELEASE "/opt/rocm/hip/lib/libhip_hcc.so"
IMPORTED_SONAME_RELEASE "libhip_hcc.so"
)
endif()
list(APPEND _IMPORT_CHECK_TARGETS hip::hip_hcc )
list(APPEND _IMPORT_CHECK_FILES_FOR_hip::hip_hcc "/opt/rocm/hip/lib/libhip_hcc.so" )
+6
View File
@@ -75,9 +75,15 @@ set_target_properties(hip::host PROPERTIES
# Create imported target hip::device
add_library(hip::device INTERFACE IMPORTED)
if(HIP_COMPILER STREQUAL "clang")
set_target_properties(hip::device PROPERTIES
INTERFACE_LINK_LIBRARIES "hip::host;hip::hip_device"
)
else()
set_target_properties(hip::device PROPERTIES
INTERFACE_LINK_LIBRARIES "hip::host;hip::hip_device;hcc::hccrt;hcc::hc_am"
)
endif()
if(CMAKE_VERSION VERSION_LESS 3.0.0)
message(FATAL_ERROR "This file relies on consumers using CMake 3.0.0 or greater.")
@@ -34,7 +34,7 @@ THE SOFTWARE.
#define LEN 64
#define SIZE LEN << 2
#define fileName "vcpy_kernel.code.adipose"
#define fileName "vcpy_kernel.code"
#define kernel_name "hello_world"
#define HIP_CHECK(status) \
+3 -22
View File
@@ -30,7 +30,7 @@ THE SOFTWARE.
#define LEN 64
#define SIZE LEN << 2
#define fileName "vcpy_kernel.code.adipose"
#define fileName "vcpy_kernel.code"
#define kernel_name "hello_world"
#define HIP_CHECK(status) \
@@ -66,32 +66,13 @@ int main() {
HIP_CHECK(hipModuleLoad(&Module, fileName));
HIP_CHECK(hipModuleGetFunction(&Function, Module, kernel_name));
#ifdef __HIP_PLATFORM_HCC__
uint32_t len = LEN;
uint32_t one = 1;
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = Ad;
args._Bd = Bd;
#endif
#ifdef __HIP_PLATFORM_NVCC__
struct {
uint32_t _hidden[1];
void* _Ad;
void* _Bd;
} args;
args._hidden[0] = 0;
args._Ad = Ad;
args._Bd = Bd;
#endif
args._Ad = (void*) Ad;
args._Bd = (void*) Bd;
size_t size = sizeof(args);
@@ -30,7 +30,7 @@ THE SOFTWARE.
#define LEN 64
#define SIZE LEN * sizeof(float)
#define fileName "vcpy_kernel.code.adipose"
#define fileName "vcpy_kernel.code"
float myDeviceGlobal;
float myDeviceGlobalArray[16];
#define HIP_CHECK(cmd) \
@@ -79,32 +79,13 @@ int main() {
myDeviceGlobalArray[i] = i * 1000.0f;
}
#ifdef __HIP_PLATFORM_HCC__
uint32_t len = LEN;
uint32_t one = 1;
struct {
void* _Ad;
void* _Bd;
} args;
args._Ad = Ad;
args._Bd = Bd;
#endif
#ifdef __HIP_PLATFORM_NVCC__
struct {
uint32_t _hidden[1];
void* _Ad;
void* _Bd;
} args;
args._hidden[0] = 0;
args._Ad = Ad;
args._Bd = Bd;
#endif
args._Ad = (void*) Ad;
args._Bd = (void*) Bd;
size_t size = sizeof(args);
@@ -21,13 +21,13 @@ THE SOFTWARE.
*/
#include "hip/hip_runtime.h"
#include "hip/hip_runtime_api.h"
//#include "hip/hip_runtime_api.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <hip/hip_hcc.h>
//#include <hip/hip_hcc.h>
#define fileName "tex2dKernel.code.adipose"
#define fileName "tex2dKernel.code"
texture<float, 2, hipReadModeElementType> tex;
bool testResult = false;
@@ -87,34 +87,15 @@ bool runTest(int argc, char** argv) {
float* dData = NULL;
hipMalloc((void**)&dData, size);
#ifdef __HIP_PLATFORM_HCC__
struct {
void* _Ad;
unsigned int _Bd;
unsigned int _Cd;
} args;
args._Ad = dData;
args._Ad = (void*) dData;
args._Bd = width;
args._Cd = height;
#endif
#ifdef __HIP_PLATFORM_NVCC__
struct {
uint32_t _hidden[1];
void* _Ad;
unsigned int _Bd;
unsigned int _Cd;
} args;
args._hidden[0] = 0;
args._Ad = dData;
args._Bd = width;
args._Cd = height;
#endif
size_t sizeTemp = sizeof(args);
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE,
+5 -11
View File
@@ -92,19 +92,13 @@ namespace hip_impl
hipStream_t stream,
void** kernarg)
{
auto it0 = functions().find(function_address);
const auto it0 = functions().find(function_address);
if (it0 == functions().cend()) {
// Re-init device code maps once again to help locate kernels
// loaded after HIP runtime initialization via means such as
// dlopen().
it0 = functions(true).find(function_address);
if (it0 == functions().cend()) {
throw runtime_error{
"No device code available for function: " +
name(function_address)
};
}
throw runtime_error{
"No device code available for function: " +
name(function_address)
};
}
auto agent = target_agent(stream);
+2
View File
@@ -58,6 +58,7 @@ __hipRegisterFatBinary(const void* data)
{
HIP_INIT();
tprintf(DB_FB, "Enter __hipRegisterFatBinary(%p)\n", data);
const __CudaFatBinaryWrapper* fbwrapper = reinterpret_cast<const __CudaFatBinaryWrapper*>(data);
if (fbwrapper->magic != __hipFatMAGIC2 || fbwrapper->version != 1) {
return nullptr;
@@ -113,6 +114,7 @@ __hipRegisterFatBinary(const void* data)
}
}
tprintf(DB_FB, "__hipRegisterFatBinary succeeds and returns %p\n", modules);
return modules;
}
+3 -3
View File
@@ -1228,7 +1228,7 @@ void HipReadEnv() {
READ_ENV_C(release, HIP_DB, 0,
"Print debug info. Bitmask (HIP_DB=0xff) or flags separated by '+' "
"(HIP_DB=api+sync+mem+copy)",
"(HIP_DB=api+sync+mem+copy+fatbin)",
HIP_DB_callback);
if ((HIP_DB & (1 << DB_API)) && (HIP_TRACE_API == 0)) {
// Set HIP_TRACE_API default before we read it, so it is printed correctly.
@@ -1808,7 +1808,7 @@ bool ihipStream_t::canSeeMemory(const ihipCtx_t* copyEngineCtx, const hc::AmPoin
// TODO - pointer-info stores a deviceID not a context,may have some unusual side-effects here:
if (dstPtrInfo->_sizeBytes == 0) {
return false;
} else {
} else if (dstPtrInfo->_appId != -1) {
#if USE_APP_PTR_FOR_CTX
ihipCtx_t* dstCtx = static_cast<ihipCtx_t*>(dstPtrInfo->_appPtr);
#else
@@ -1831,7 +1831,7 @@ bool ihipStream_t::canSeeMemory(const ihipCtx_t* copyEngineCtx, const hc::AmPoin
// TODO - pointer-info stores a deviceID not a context,may have some unusual side-effects here:
if (srcPtrInfo->_sizeBytes == 0) {
return false;
} else {
} else if (srcPtrInfo->_appId != -1) {
#if USE_APP_PTR_FOR_CTX
ihipCtx_t* srcCtx = static_cast<ihipCtx_t*>(srcPtrInfo->_appPtr);
#else
+3 -1
View File
@@ -223,7 +223,8 @@ extern const char* API_COLOR_END;
#define DB_MEM 2 /* 0x04 - trace memory allocation / deallocation */
#define DB_COPY 3 /* 0x08 - trace memory copy and peer commands. . */
#define DB_WARN 4 /* 0x10 - warn about sub-optimal or shady behavior */
#define DB_MAX_FLAG 5
#define DB_FB 5 /* 0x20 - trace loading fat binary */
#define DB_MAX_FLAG 6
// When adding a new debug flag, also add to the char name table below.
//
//
@@ -237,6 +238,7 @@ struct DbName {
static const DbName dbName[] = {
{KGRN, "api"}, // not used,
{KYEL, "sync"}, {KCYN, "mem"}, {KMAG, "copy"}, {KRED, "warn"},
{KBLU, "fatbin"},
};
+7 -6
View File
@@ -61,19 +61,20 @@ int sharePtr(void* ptr, ihipCtx_t* ctx, bool shareWithAll, unsigned hipFlags) {
auto device = ctx->getWriteableDevice();
#if USE_APP_PTR_FOR_CTX
hc::am_memtracker_update(ptr, device->_deviceId, hipFlags, ctx);
#else
hc::am_memtracker_update(ptr, device->_deviceId, hipFlags);
#endif
if (shareWithAll) {
// shareWithAll memory is not mapped to any device
hc::am_memtracker_update(ptr, -1, hipFlags);
hsa_status_t s = hsa_amd_agents_allow_access(g_deviceCnt + 1, g_allAgents, NULL, ptr);
tprintf(DB_MEM, " allow access to CPU + all %d GPUs (shareWithAll)\n", g_deviceCnt);
if (s != HSA_STATUS_SUCCESS) {
ret = -1;
}
} else {
#if USE_APP_PTR_FOR_CTX
hc::am_memtracker_update(ptr, device->_deviceId, hipFlags, ctx);
#else
hc::am_memtracker_update(ptr, device->_deviceId, hipFlags);
#endif
int peerCnt = 0;
{
LockedAccessor_CtxCrit_t crit(ctx->criticalData());
+37 -131
View File
@@ -74,15 +74,11 @@ vector<string> copy_names_of_undefined_symbols(const symbol_section_accessor& se
}
const std::unordered_map<std::string, std::pair<ELFIO::Elf64_Addr, ELFIO::Elf_Xword>>&
symbol_addresses(bool rebuild = false) {
symbol_addresses() {
static unordered_map<string, pair<Elf64_Addr, Elf_Xword>> r;
static once_flag f;
auto cons = [rebuild]() {
if (rebuild) {
r.clear();
}
call_once(f, []() {
dl_iterate_phdr(
[](dl_phdr_info* info, size_t, void*) {
static constexpr const char self[] = "/proc/self/exe";
@@ -112,12 +108,7 @@ symbol_addresses(bool rebuild = false) {
return 0;
},
nullptr);
};
call_once(f, cons);
if (rebuild) {
cons();
}
});
return r;
}
@@ -175,34 +166,21 @@ vector<char> code_object_blob_for_process() {
return r;
}
const unordered_map<hsa_isa_t, vector<vector<char>>>& code_object_blobs(bool rebuild = false) {
const unordered_map<hsa_isa_t, vector<vector<char>>>& code_object_blobs() {
static unordered_map<hsa_isa_t, vector<vector<char>>> r;
static once_flag f;
auto cons = [rebuild]() {
// names of shared libraries who .kernel sections already loaded
static unordered_set<string> lib_names;
call_once(f, []() {
static vector<vector<char>> blobs{code_object_blob_for_process()};
if (rebuild) {
r.clear();
blobs.clear();
}
dl_iterate_phdr(
[](dl_phdr_info* info, std::size_t, void*) {
elfio tmp;
if ((lib_names.find(info->dlpi_name) == lib_names.end()) &&
(tmp.load(info->dlpi_name))) {
if (tmp.load(info->dlpi_name)) {
const auto it = find_section_if(
tmp, [](const section* x) { return x->get_name() == ".kernel"; });
if (it) {
blobs.emplace_back(
it->get_data(), it->get_data() + it->get_size());
// register the shared library as already loaded
lib_names.emplace(info->dlpi_name);
}
if (it) blobs.emplace_back(it->get_data(), it->get_data() + it->get_size());
}
return 0;
},
@@ -216,13 +194,7 @@ const unordered_map<hsa_isa_t, vector<vector<char>>>& code_object_blobs(bool reb
}
}
}
};
call_once(f, cons);
if (rebuild) {
cons();
}
});
return r;
}
@@ -244,13 +216,13 @@ vector<pair<uintptr_t, string>> function_names_for(const elfio& reader, section*
return r;
}
const vector<pair<uintptr_t, string>>& function_names_for_process(bool rebuild = false) {
const vector<pair<uintptr_t, string>>& function_names_for_process() {
static constexpr const char self[] = "/proc/self/exe";
static vector<pair<uintptr_t, string>> r;
static once_flag f;
auto cons = [rebuild]() {
call_once(f, []() {
elfio reader;
if (!reader.load(self)) {
@@ -261,26 +233,16 @@ const vector<pair<uintptr_t, string>>& function_names_for_process(bool rebuild =
find_section_if(reader, [](const section* x) { return x->get_type() == SHT_SYMTAB; });
if (symtab) r = function_names_for(reader, symtab);
};
call_once(f, cons);
if (rebuild) {
cons();
}
});
return r;
}
const unordered_map<string, vector<hsa_executable_symbol_t>>& kernels(bool rebuild = false) {
const unordered_map<string, vector<hsa_executable_symbol_t>>& kernels() {
static unordered_map<string, vector<hsa_executable_symbol_t>> r;
static once_flag f;
auto cons = [rebuild]() {
if (rebuild) {
r.clear();
executables(rebuild);
}
call_once(f, []() {
static const auto copy_kernels = [](hsa_executable_t, hsa_agent_t,
hsa_executable_symbol_t s, void*) {
if (type(s) == HSA_SYMBOL_KIND_KERNEL) r[name(s)].push_back(s);
@@ -294,12 +256,7 @@ const unordered_map<string, vector<hsa_executable_symbol_t>>& kernels(bool rebui
copy_kernels, nullptr);
}
}
};
call_once(f, cons);
if (rebuild) {
cons();
}
});
return r;
}
@@ -338,19 +295,13 @@ void load_code_object_and_freeze_executable(
namespace hip_impl {
const unordered_map<hsa_agent_t, vector<hsa_executable_t>>&
executables(bool rebuild) { // TODO: This leaks the hsa_executable_ts, it should use RAII.
executables() { // TODO: This leaks the hsa_executable_ts, it should use RAII.
static unordered_map<hsa_agent_t, vector<hsa_executable_t>> r;
static once_flag f;
auto cons = [rebuild]() {
call_once(f, []() {
static const auto accelerators = hc::accelerator::get_all();
if (rebuild) {
// do NOT clear r so we reuse instances of hsa_executable_t
// created previously
code_object_blobs(rebuild);
}
for (auto&& acc : accelerators) {
auto agent = static_cast<hsa_agent_t*>(acc.get_hsa_agent());
@@ -384,29 +335,17 @@ executables(bool rebuild) { // TODO: This leaks the hsa_executable_ts, it shoul
},
agent);
}
};
call_once(f, cons);
if (rebuild) {
cons();
}
});
return r;
}
const unordered_map<uintptr_t, string>& function_names(bool rebuild) {
const unordered_map<uintptr_t, string>& function_names() {
static unordered_map<uintptr_t, string> r{function_names_for_process().cbegin(),
function_names_for_process().cend()};
static once_flag f;
auto cons = [rebuild]() {
if (rebuild) {
r.clear();
function_names_for_process(rebuild);
r.insert(function_names_for_process().cbegin(),
function_names_for_process().cend());
}
call_once(f, []() {
dl_iterate_phdr(
[](dl_phdr_info* info, size_t, void*) {
elfio tmp;
@@ -426,32 +365,16 @@ const unordered_map<uintptr_t, string>& function_names(bool rebuild) {
return 0;
},
nullptr);
};
call_once(f, cons);
if (rebuild) {
static mutex mtx;
lock_guard<mutex> lck{mtx};
cons();
}
});
return r;
}
const unordered_map<uintptr_t, vector<pair<hsa_agent_t, Kernel_descriptor>>>& functions(bool rebuild) {
const unordered_map<uintptr_t, vector<pair<hsa_agent_t, Kernel_descriptor>>>& functions() {
static unordered_map<uintptr_t, vector<pair<hsa_agent_t, Kernel_descriptor>>> r;
static once_flag f;
auto cons = [rebuild]() {
if (rebuild) {
// do NOT clear r so we reuse instances of pair<hsa_agent_t, Kernel_descriptor>
// created previously
function_names(rebuild);
kernels(rebuild);
globals(rebuild);
}
call_once(f, []() {
for (auto&& function : function_names()) {
const auto it = kernels().find(function.second);
@@ -463,34 +386,15 @@ const unordered_map<uintptr_t, vector<pair<hsa_agent_t, Kernel_descriptor>>>& fu
}
}
}
};
call_once(f, cons);
if (rebuild) {
static mutex mtx;
lock_guard<mutex> lck{mtx};
cons();
}
});
return r;
}
unordered_map<string, void*>& globals(bool rebuild) {
unordered_map<string, void*>& globals() {
static unordered_map<string, void*> r;
static once_flag f;
auto cons =[rebuild]() {
if (rebuild) {
r.clear();
symbol_addresses(rebuild);
}
r.reserve(symbol_addresses().size());
};
call_once(f, cons);
if (rebuild) {
cons();
}
call_once(f, []() { r.reserve(symbol_addresses().size()); });
return r;
}
@@ -513,15 +417,17 @@ hsa_executable_t load_executable(const string& file, hsa_executable_t executable
return executable;
}
// To force HIP to load the kernels and to setup the function
// symbol map on program startup
class startup_kernel_loader {
private:
startup_kernel_loader() { functions(); }
startup_kernel_loader(const startup_kernel_loader&) = delete;
startup_kernel_loader& operator=(const startup_kernel_loader&) = delete;
static startup_kernel_loader skl;
};
startup_kernel_loader startup_kernel_loader::skl;
// HIP startup kernel loader logic
// When enabled HIP_STARTUP_LOADER, HIP will load the kernels and setup
// the function symbol map on program startup
extern "C" void __attribute__((constructor)) __startup_kernel_loader_init() {
int hip_startup_loader=0;
if (std::getenv("HIP_STARTUP_LOADER"))
hip_startup_loader = atoi(std::getenv("HIP_STARTUP_LOADER"));
if (hip_startup_loader) functions();
}
extern "C" void __attribute__((destructor)) __startup_kernel_loader_fini() {
}
} // Namespace hip_impl.
@@ -0,0 +1,79 @@
// RUN: %run_test hipify "%s" "%t" %cuda_args
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// CHECK: #include "hipblas.h"
#include "cublas.h"
#define M 6
#define N 5
#define IDX2C(i,j,ld) (((j)*(ld))+(i))
static __inline__ void modify(float *m, int ldm, int n, int p, int q, float
alpha, float beta) {
// CHECK: hipblasSscal(n - p, alpha, &m[IDX2C(p, q, ldm)], ldm);
// CHECK: hipblasSscal(ldm - p, beta, &m[IDX2C(p, q, ldm)], 1);
cublasSscal(n - p, alpha, &m[IDX2C(p, q, ldm)], ldm);
cublasSscal(ldm - p, beta, &m[IDX2C(p, q, ldm)], 1);
}
int main(void) {
int i, j;
// CHECK: hipblasStatus_t stat;
cublasStatus stat;
float* devPtrA;
float* a = 0;
a = (float *)malloc(M * N * sizeof(*a));
if (!a) {
printf("host memory allocation failed");
return EXIT_FAILURE;
}
for (j = 0; j < N; j++) {
for (i = 0; i < M; i++) {
a[IDX2C(i, j, M)] = (float)(i * M + j + 1);
}
}
// cublasInit is not supported yet
cublasInit();
stat = cublasAlloc(M*N, sizeof(*a), (void**)&devPtrA);
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
if (stat != CUBLAS_STATUS_SUCCESS) {
printf("device memory allocation failed");
// cublasShutdown is not supported yet
cublasShutdown();
return EXIT_FAILURE;
}
// CHECK: stat = hipblasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
stat = cublasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
if (stat != CUBLAS_STATUS_SUCCESS) {
printf("data download failed");
// cublasFree is not supported yet
cublasFree(devPtrA);
// cublasShutdown is not supported yet
cublasShutdown();
return EXIT_FAILURE;
}
modify(devPtrA, M, N, 1, 2, 16.0f, 12.0f);
// CHECK: stat = hipblasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
stat = cublasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
if (stat != CUBLAS_STATUS_SUCCESS) {
printf("data upload failed");
// cublasFree is not supported yet
cublasFree(devPtrA);
// cublasShutdown is not supported yet
cublasShutdown();
return EXIT_FAILURE;
}
// cublasFree is not supported yet
cublasFree(devPtrA);
// cublasShutdown is not supported yet
cublasShutdown();
for (j = 0; j < N; j++) {
for (i = 0; i < M; i++) {
printf("%7.0f", a[IDX2C(i, j, M)]);
}
printf("\n");
}
free(a);
return EXIT_SUCCESS;
}
@@ -0,0 +1,90 @@
// RUN: %run_test hipify "%s" "%t" %cuda_args
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// CHECK: #include <hip/hip_runtime.h>
#include <cuda_runtime.h>
// CHECK: #include "hipblas.h"
#include "cublas_v2.h"
#define M 6
#define N 5
#define IDX2F(i,j,ld) ((((j)-1)*(ld))+((i)-1))
// CHECK: static __inline__ void modify(hipblasHandle_t handle, float *m, int ldm, int
static __inline__ void modify(cublasHandle_t handle, float *m, int ldm, int
n, int p, int q, float alpha, float beta) {
// CHECK: hipblasSscal(handle, n - p + 1, &alpha, &m[IDX2F(p, q, ldm)], ldm);
// CHECK: hipblasSscal(handle, ldm - p + 1, &beta, &m[IDX2F(p, q, ldm)], 1);
cublasSscal(handle, n - p + 1, &alpha, &m[IDX2F(p, q, ldm)], ldm);
cublasSscal(handle, ldm - p + 1, &beta, &m[IDX2F(p, q, ldm)], 1);
}
int main(void) {
// CHECK: hipError_t cudaStat;
// CHECK: hipblasStatus_t stat;
// CHECK: hipblasHandle_t handle;
cudaError_t cudaStat;
cublasStatus_t stat;
cublasHandle_t handle;
int i, j;
float* devPtrA;
float* a = 0;
a = (float *)malloc(M * N * sizeof(*a));
if (!a) {
printf("host memory allocation failed");
return EXIT_FAILURE;
}
for (j = 1; j <= N; j++) {
for (i = 1; i <= M; i++) {
a[IDX2F(i, j, M)] = (float)((i - 1) * M + j);
}
}
// CHECK: cudaStat = hipMalloc((void**)&devPtrA, M*N * sizeof(*a));
cudaStat = cudaMalloc((void**)&devPtrA, M*N * sizeof(*a));
// CHECK: if (cudaStat != hipSuccess) {
if (cudaStat != cudaSuccess) {
printf("device memory allocation failed");
return EXIT_FAILURE;
}
// CHECK: stat = hipblasCreate(&handle);
stat = cublasCreate(&handle);
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
if (stat != CUBLAS_STATUS_SUCCESS) {
printf("CUBLAS initialization failed\n");
return EXIT_FAILURE;
}
// CHECK: stat = hipblasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
stat = cublasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
if (stat != CUBLAS_STATUS_SUCCESS) {
printf("data download failed");
// CHECK: hipFree(devPtrA);
// CHECK: hipblasDestroy(handle);
cudaFree(devPtrA);
cublasDestroy(handle);
return EXIT_FAILURE;
}
modify(handle, devPtrA, M, N, 2, 3, 16.0f, 12.0f);
// CHECK: stat = hipblasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
stat = cublasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
if (stat != CUBLAS_STATUS_SUCCESS) {
printf("data upload failed");
// CHECK: hipFree(devPtrA);
// CHECK: hipblasDestroy(handle);
cudaFree(devPtrA);
cublasDestroy(handle);
return EXIT_FAILURE;
}
// CHECK: hipFree(devPtrA);
// CHECK: hipblasDestroy(handle);
cudaFree(devPtrA);
cublasDestroy(handle);
for (j = 1; j <= N; j++) {
for (i = 1; i <= M; i++) {
printf("%7.0f", a[IDX2F(i, j, M)]);
}
printf("\n");
}
free(a);
return EXIT_SUCCESS;
}
@@ -0,0 +1,108 @@
// RUN: %run_test hipify "%s" "%t" %cuda_args
#include <stdio.h>
#include <stdlib.h>
// CHECK: #include <hip/hip_runtime.h>
#include <cuda_runtime.h>
// CHECK: #include "hipblas.h"
#include "cublas_v2.h"
#define IDX2C(i,j,ld) (((j)*(ld))+(i))
#define m 6
#define n 4
#define k 5
int main(void) {
// CHECK: hipError_t cudaStat;
// CHECK: hipblasStatus_t stat;
// CHECK: hipblasHandle_t handle;
cudaError_t cudaStat;
cublasStatus_t stat;
cublasHandle_t handle;
int i, j;
float * a;
float * b;
float * c;
a = (float *)malloc(m*k * sizeof(float));
b = (float *)malloc(k*n * sizeof(float));
c = (float *)malloc(m*n * sizeof(float));
int ind = 11;
for (j = 0; j<k; j++) {
for (i = 0; i<m; i++) {
a[IDX2C(i, j, m)] = (float)ind++;
}
}
printf("a:\n");
for (i = 0; i<m; i++) {
for (j = 0; j<k; j++) {
printf(" %5.0f", a[IDX2C(i, j, m)]);
}
printf("\n");
}
ind = 11;
for (j = 0; j<n; j++) {
for (i = 0; i<k; i++) {
b[IDX2C(i, j, k)] = (float)ind++;
}
}
printf("b:\n");
for (i = 0; i<k; i++) {
for (j = 0; j<n; j++) {
printf(" %5.0f", b[IDX2C(i, j, k)]);
}
printf("\n");
}
ind = 11;
for (j = 0; j<n; j++) {
for (i = 0; i<m; i++) {
c[IDX2C(i, j, m)] = (float)ind++;
}
}
printf("c:\n");
for (i = 0; i<m; i++) {
for (j = 0; j<n; j++) {
printf(" %5.0f", c[IDX2C(i, j, m)]);
}
printf("\n");
}
float * d_a;
float * d_b;
float * d_c;
// CHECK: cudaStat = hipMalloc((void **)& d_a, m*k * sizeof(*a));
// CHECK: cudaStat = hipMalloc((void **)& d_b, k*n * sizeof(*b));
// CHECK: cudaStat = hipMalloc((void **)& d_c, m*n * sizeof(*c));
cudaStat = cudaMalloc((void **)& d_a, m*k * sizeof(*a));
cudaStat = cudaMalloc((void **)& d_b, k*n * sizeof(*b));
cudaStat = cudaMalloc((void **)& d_c, m*n * sizeof(*c));
// CHECK: stat = hipblasCreate(&handle);
stat = cublasCreate(&handle);
// CHECK: stat = hipblasSetMatrix(m, k, sizeof(*a), a, m, d_a, m);
// CHECK: stat = hipblasSetMatrix(k, n, sizeof(*b), b, k, d_b, k);
// CHECK: stat = hipblasSetMatrix(m, n, sizeof(*c), c, m, d_c, m);
stat = cublasSetMatrix(m, k, sizeof(*a), a, m, d_a, m);
stat = cublasSetMatrix(k, n, sizeof(*b), b, k, d_b, k);
stat = cublasSetMatrix(m, n, sizeof(*c), c, m, d_c, m);
float al = 1.0f;
float bet = 1.0f;
// CHECK: stat = hipblasSgemm(handle, HIPBLAS_OP_N, HIPBLAS_OP_N, m, n, k, &al, d_a, m, d_b, k, &bet, d_c, m);
stat = cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k, &al, d_a, m, d_b, k, &bet, d_c, m);
// CHECK: stat = hipblasGetMatrix(m, n, sizeof(*c), d_c, m, c, m);
stat = cublasGetMatrix(m, n, sizeof(*c), d_c, m, c, m);
printf("c after Sgemm :\n");
for (i = 0; i<m; i++) {
for (j = 0; j<n; j++) {
printf(" %7.0f", c[IDX2C(i, j, m)]);
}
printf("\n");
}
// CHECK: hipFree(d_a);
// CHECK: hipFree(d_b);
// CHECK: hipFree(d_c);
// CHECK: hipblasDestroy(handle);
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
cublasDestroy(handle);
free(a);
free(b);
free(c);
return EXIT_SUCCESS;
}
@@ -0,0 +1,58 @@
// RUN: %run_test hipify "%s" "%t" %cuda_args
// CHECK: #include <hip/hip_runtime.h>
// CHECK: #include "hip/hip_complex.h"
#include "cuComplex.h"
#define TYPEFLOAT
#define DIMX 100
#define DIMY 40
#define moveX 2
#define moveY 1
#define MAXITERATIONS 10
#ifdef TYPEFLOAT
#define TYPE float
// CHECK: #define cTYPE hipFloatComplex
#define cTYPE cuFloatComplex
// CHECK: #define cMakecuComplex(re,i) make_hipFloatComplex(re,i)
#define cMakecuComplex(re,i) make_cuFloatComplex(re,i)
#endif
#ifdef TYPEDOUBLE
// CHECK: #define TYPE hipDoubleComplex
#define TYPE cuDoubleComplex
// CHECK: #define cMakecuComplex(re,i) make_hipDoubleComplex(re,i)
#define cMakecuComplex(re,i) make_cuDoubleComplex(re,i)
#endif
__device__ cTYPE juliaFunctor(cTYPE p, cTYPE c) {
// CHECK: return hipCaddf(hipCmulf(p, p), c);
return cuCaddf(cuCmulf(p, p), c);
}
__device__ cTYPE convertToComplex(int x, int y, float zoom) {
TYPE jx = 1.5 * (x - DIMX / 2) / (0.5 * zoom * DIMX) + moveX;
TYPE jy = (y - DIMY / 2) / (0.5 * zoom * DIMY) + moveY;
return cMakecuComplex(jx, jy);
}
__device__ int evolveComplexPoint(cTYPE p, cTYPE c) {
int it = 1;
// CHECK: while (it <= MAXITERATIONS && hipCabsf(p) <= 4) {
while (it <= MAXITERATIONS && cuCabsf(p) <= 4) {
p = juliaFunctor(p, c);
it++;
}
return it;
}
__global__ void computeJulia(int* data, cTYPE c, float zoom) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i<DIMX && j<DIMY) {
cTYPE p = convertToComplex(i, j, zoom);
data[i*DIMY + j] = evolveComplexPoint(p, c);
}
}
+78
View File
@@ -0,0 +1,78 @@
// RUN: %run_test hipify "%s" "%t" %cuda_args
// CHECK: #include <hip/hip_runtime.h>
#include <cuda.h>
// CHECK: #include <hipfft.h>
#include <cufft.h>
#include <stdio.h>
#include <math.h>
#define DATASIZE 8
#define BATCH 2
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
// CHECK: inline void gpuAssert(hipError_t code, const char *file, int line, bool abort = true)
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort = true)
{
// CHECK: if (code != hipSuccess)
if (code != cudaSuccess)
{
// CHECK: fprintf(stderr, "GPUassert: %s %s %dn", hipGetErrorString(code), file, line);
fprintf(stderr, "GPUassert: %s %s %dn", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
int main()
{
// --- Host side input data allocation and initialization
// CHECK: hipfftReal *hostInputData = (hipfftReal*)malloc(DATASIZE*BATCH * sizeof(hipfftReal));
cufftReal *hostInputData = (cufftReal*)malloc(DATASIZE*BATCH * sizeof(cufftReal));
for (int i = 0; i<BATCH; i++)
for (int j = 0; j<DATASIZE; j++) hostInputData[i*DATASIZE + j] = (cufftReal)(i + 1);
// --- Device side input data allocation and initialization
cufftReal *deviceInputData; gpuErrchk(cudaMalloc((void**)&deviceInputData, DATASIZE * BATCH * sizeof(cufftReal)));
// CHECK: hipMemcpy(deviceInputData, hostInputData, DATASIZE * BATCH * sizeof(hipfftReal), hipMemcpyHostToDevice);
cudaMemcpy(deviceInputData, hostInputData, DATASIZE * BATCH * sizeof(cufftReal), cudaMemcpyHostToDevice);
// --- Host side output data allocation
cufftComplex *hostOutputData = (cufftComplex*)malloc((DATASIZE / 2 + 1) * BATCH * sizeof(cufftComplex));
// --- Device side output data allocation
cufftComplex *deviceOutputData; gpuErrchk(cudaMalloc((void**)&deviceOutputData, (DATASIZE / 2 + 1) * BATCH * sizeof(cufftComplex)));
// --- Batched 1D FFTs
// CHECK: hipfftHandle handle;
cufftHandle handle;
int rank = 1; // --- 1D FFTs
int n[] = { DATASIZE }; // --- Size of the Fourier transform
int istride = 1, ostride = 1; // --- Distance between two successive input/output elements
int idist = DATASIZE, odist = (DATASIZE / 2 + 1); // --- Distance between batches
int inembed[] = { 0 }; // --- Input size with pitch (ignored for 1D transforms)
int onembed[] = { 0 }; // --- Output size with pitch (ignored for 1D transforms)
int batch = BATCH; // --- Number of batched executions
// CHECK: hipfftPlanMany(&handle, rank, n,
cufftPlanMany(&handle, rank, n,
inembed, istride, idist,
// CHECK: onembed, ostride, odist, HIPFFT_R2C, batch);
onembed, ostride, odist, CUFFT_R2C, batch);
// CHECK: hipfftExecR2C(handle, deviceInputData, deviceOutputData);
cufftExecR2C(handle, deviceInputData, deviceOutputData);
// --- Device->Host copy of the results
// CHECK: gpuErrchk(hipMemcpy(hostOutputData, deviceOutputData, (DATASIZE / 2 + 1) * BATCH * sizeof(hipfftComplex), hipMemcpyDeviceToHost));
gpuErrchk(cudaMemcpy(hostOutputData, deviceOutputData, (DATASIZE / 2 + 1) * BATCH * sizeof(cufftComplex), cudaMemcpyDeviceToHost));
for (int i = 0; i<BATCH; i++)
for (int j = 0; j<(DATASIZE / 2 + 1); j++)
printf("%i %i %f %fn", i, j, hostOutputData[i*(DATASIZE / 2 + 1) + j].x, hostOutputData[i*(DATASIZE / 2 + 1) + j].y);
// CHECK: hipfftDestroy(handle);
cufftDestroy(handle);
// CHECK: gpuErrchk(hipFree(deviceOutputData));
// CHECK: gpuErrchk(hipFree(deviceInputData));
gpuErrchk(cudaFree(deviceOutputData));
gpuErrchk(cudaFree(deviceInputData));
}
+4
View File
@@ -47,6 +47,8 @@
// CHECK: #include <string>
// CHECK: #include "hipfft.h"
#include <cuda.h>
#include <memory>
@@ -91,3 +93,5 @@
#include "curand_uniform.h"
#include <string>
#include "cufft.h"
+355
View File
@@ -0,0 +1,355 @@
/*
Copyright (c) 2015-Present 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp
* RUN: %t
* HIT_END
*/
#include "hipClassKernel.h"
#ifdef ENABLE_OVERLOAD_OVERRIDE_TESTS
__global__ void
ovrdClassKernel(bool* result_ecd){
int tid = threadIdx.x + blockIdx.x * blockDim.x;
testOvrD tobj1;
result_ecd[tid] = (tobj1.ovrdFunc1() == 30);
}
void HipClassTests::TestForOverride(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(ovrdClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
__global__ void
ovldClassKernel(bool* result_ecd){
int tid = threadIdx.x + blockIdx.x * blockDim.x;
testFuncOvld tfo1;
result_ecd[tid] = (tfo1.func1(10) == 20)
&& (tfo1.func1(10,10) == 30);
}
void HipClassTests::TestForOverload(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(ovldClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
#endif
#ifdef ENABLE_FRIEND_TEST
// check for friend
__global__ void
friendClassKernel(bool* result_ecd){
int tid = threadIdx.x + blockIdx.x * blockDim.x;
testFrndB tfb1;
result_ecd[tid] = (tfb1.showA() == 10);
}
#endif
// check sizeof empty class is 1
__global__ void
emptyClassKernel(bool* result_ecd) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
testClassEmpty ob1,ob2;
result_ecd[tid] = (sizeof(testClassEmpty) == 1)
&& (&ob1 != &ob2);
}
void HipClassTests::TestForEmptyClass(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(emptyClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
// tests for classes >8 bytes
__global__ void
sizeClassBKernel(bool* result_ecd) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
result_ecd[tid] = (sizeof(testSizeB) == 12)
&& (sizeof(testSizeC) == 16)
&& (sizeof(testSizeP1) == 6)
&& (sizeof(testSizeP2) == 13)
&& (sizeof(testSizeP3) == 8);
}
void HipClassTests::TestForClassBSize(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(sizeClassBKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
__global__ void
sizeClassKernel(bool* result_ecd) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
result_ecd[tid] = (sizeof(testSizeA) == 16)
&& (sizeof(testSizeDerived) == 24)
&& (sizeof(testSizeDerived2) == 20);
}
void HipClassTests::TestForClassSize(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(sizeClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
#ifdef ENABLE_VIRTUAL_TESTS
__global__ void
sizeVirtualClassKernel(bool* result_ecd) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
result_ecd[tid] = (sizeof(testSizeDV) == 16)
&& (sizeof(testSizeDerivedDV) == 16)
&& (sizeof(testSizeVirtDerPack) == 24)
&& (sizeof(testSizeVirtDer) == 24)
&& (sizeof(testSizeDerMulti) == 48) ;
}
void HipClassTests::TestForVirtualClassSize(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(sizeVirtualClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
#endif
// check pass by value
__global__ void
passByValueKernel(testPassByValue obj, bool* result_ecd) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
result_ecd[tid] = (obj.exI == 10)
&& (obj.exC == 'C');
}
void HipClassTests::TestForPassByValue(void){
bool *result_ecd,*result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
testPassByValue exObj;
exObj.exI = 10;
exObj.exC = 'C';
hipLaunchKernelGGL(passByValueKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
exObj,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
// check obj created with hipMalloc
__global__ void
mallocObjKernel(testPassByValue *obj, bool* result_ecd) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
result_ecd[tid] = (obj->exI == 100)
&& (obj->exC == 'C');
}
void HipClassTests::TestForMallocPassByValue(void){
bool *result_ecd,*result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
testPassByValue *exObjM;
HIPCHECK(hipMalloc(&exObjM, sizeof(testPassByValue)));
exObjM->exI = 100;
exObjM->exC = 'C';
hipLaunchKernelGGL(mallocObjKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
exObjM,
result_ecd);
HipClassTests::VerifyResult(result_ech,result_ecd);
HipClassTests::FreeMem(result_ech,result_ecd);
}
// check if constr and destr are accessible from kernel
#ifdef ENABLE_DESTRUCTOR_TEST
__global__ void
testDeviceClassKernel() {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
testDeviceClass ob1;
testDeviceClass ob2;
ob2.iVar = 10;
}
void HipClassTests::TestForConsrtDesrt(){
testDeviceClass tDC;
hipLaunchKernelGGL(testDeviceClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0);
}
#endif
#ifdef ENABLE_FRIEND_TEST
void HipClassTests::TestForFriend(void){
bool *result_ecd, *result_ech;
result_ech = HipClassTests::AllocateHostMemory();
result_ecd = HipClassTests::AllocateDeviceMemory();
hipLaunchKernelGGL(friendClassKernel,
dim3(BLOCKS),
dim3(THREADS_PER_BLOCK),
0,
0,
result_ecd);
}
#endif
bool* HipClassTests::AllocateHostMemory(void){
bool *result_ech;
HIPCHECK(hipHostMalloc(&result_ech,
NBOOL,
hipHostMallocDefault));
return result_ech;
}
bool* HipClassTests::AllocateDeviceMemory(void){
bool* result_ecd;
HIPCHECK(hipMalloc(&result_ecd,
NBOOL));
HIPCHECK(hipMemset(result_ecd,
false,
NBOOL));
return result_ecd;
}
void HipClassTests::VerifyResult(bool* result_ech, bool* result_ecd){
HIPCHECK(hipMemcpy(result_ech,
result_ecd,
BLOCKS*sizeof(bool),
hipMemcpyDeviceToHost));
// validation on host side
for (int i = 0; i < BLOCKS; i++) {
HIPASSERT(result_ech[i] == true);
}
}
void HipClassTests::FreeMem(bool* result_ech, bool* result_ecd){
HIPCHECK(hipHostFree(result_ech));
HIPCHECK(hipFree(result_ecd));
}
int main(){
HipClassTests classTests;
classTests.TestForEmptyClass();
test_passed(TestForEmptyClass);
classTests.TestForClassBSize();
test_passed(TestForClassBSize);
classTests.TestForClassSize();
test_passed(TestForClassSize);
classTests.TestForPassByValue();
test_passed(TestForPassByValue);
#ifdef ENABLE_OVERLOAD_OVERRIDE_TESTS
classTests.TestForOverload();
test_passed(TestForOverload);
classTests.TestForOverride();
test_passed(TestForOverride);
#endif
#ifdef ENABLE_FRIEND_TEST
classTests.TestForFriend();
test_passed(TestForFriend);
#endif
// classTests.TestForMallocPassByValue();
// test_passed(TestForMallocPassByValue); #this test is crashing
#ifdef ENABLE_VIRTUAL_TESTS
classTests.TestForVirtualClassSize();
test_passed(TestForVirtualClassSize);
#endif
#ifdef ENABLE_DESTRUCTOR_TEST
classTests.TestForConsrtDesrt();
test_passed(TestForConsrtDesrt);
#endif
}
+239
View File
@@ -0,0 +1,239 @@
/*
Copyright (c) 2015-Present 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.
*/
#ifndef _COMPILER_HIPCLASSKERNEL_H_
#define _COMPILER_HIPCLASSKERNEL_H_
#include <iostream>
#include <string>
#include "hip/hip_runtime.h"
#include "test_common.h"
static const int BLOCKS = 512;
static const int THREADS_PER_BLOCK = 1;
static const int ENABLE_DESTRUCTOR_TEST = 0;
static const int ENABLE_VIRTUAL_TESTS = 0;
static const int ENABLE_FRIEND_TEST = 0;
static const int ENABLE_OVERLAD_OVERRIDE_TESTS = 0;
size_t NBOOL = BLOCKS * sizeof(bool);
#define test_passed(test_name) printf("%s %s PASSED!%s\n", KGRN, #test_name, KNRM);
#ifdef ENABLE_OVERLOAD_OVERRIDE_TESTS
class testFuncOvld{
public:
int __host__ __device__ func1(int a){
return a + 10;
}
int __host__ __device__ func1(int a , int b){
return a + b + 10;
}
};
class testOvrB{
public:
int __host__ __device__ ovrdFunc1(){
return 10;
}
};
class testOvrD: public testOvrB{
public:
int __host__ __device__ ovrdFunc1(){
int x = testOvrB::ovrdFunc1();
return x + 20;
}
};
#endif
#ifdef ENABLE_FRIEND_TEST
class testFrndA{
private:
int fa = 10;
public:
friend class testFrndB;
};
class testFrndB{
public:
__host__ __device__ int showA(){
testFrndA x;
return x.fa;
}
};
#endif
class testClassEmpty {};
class testPassByValue{
public:
int exI;
char exC;
};
class testSizeA {
public:
float xa;
int ia;
double da;
static char ca;
};
class testSizeDerived : testSizeA {
public:
float fd;
};
#pragma pack(push,4)
class testSizeDerived2 : testSizeA {
public:
float fd;
};
#pragma pack(pop)
class testSizeB {
public:
char ab;
int ib;
char cb;
};
#ifdef ENBABLE_VIRTUAL_TESTS
class testSizeVirtDer : public virtual testSizeB {
public:
int ivd;
};
class testSizeVirtDer1 : public virtual testSizeB {
public:
int ivd1;
};
class testSizeDerMulti : public testSizeVirtDer, public testSizeVirtDer1 {
public:
int ivd2;
};
#pragma pack(push,4)
class testSizeVirtDerPack : public virtual testSizeB {
public:
int ivd;
};
#pragma pack(pop)
#endif
class testSizeC {
public:
char ac;
int ic;
int bc[2];
};
#ifdef ENABLE_VIRTUAL_TESTS
class testSizeDV {
public:
virtual void __host__ __device__ func1();
private:
int iDV;
};
class testSizeDerivedDV : testSizeDV {
public:
virtual void __host__ __device__ funcD1();
private:
int iDDV;
};
#endif
#pragma pack(push, 1)
class testSizeP1 {
public:
char ap;
int ip;
char cp;
};
#pragma pack(pop)
#pragma pack(push, 1)
class testSizeP2 {
public:
char ap1;
int ip1;
int bp1[2];
};
#pragma pack(pop)
#pragma pack(push, 2)
class testSizeP3 {
public:
char ap2;
int ip2;
char cp2;
};
#pragma pack(pop)
#ifdef ENABLE_DESTRUCTOR_TEST
class testDeviceClass {
public:
int iVar;
__host__ __device__ testDeviceClass();
__host__ __device__ testDeviceClass(int a);
__host__ __device__ ~testDeviceClass();
};
__host__ __device__
testDeviceClass::testDeviceClass() {
iVar = 5;
}
__host__ __device__
testDeviceClass::testDeviceClass(int a) {
iVar = a;
}
#endif
#endif // _HIPCLASSKERNEL_H_
class HipClassTests{
public:
void TestForEmptyClass(void);
void TestForClassBSize(void);
void TestForClassSize(void);
void TestForVirtualClassSize(void);
void TestForPassByValue(void);
void TestForMallocPassByValue(void);
void TestForConsrtDesrt(void);
void TestForOverload(void);
void TestForOverride(void);
bool* AllocateHostMemory(void);
bool* AllocateDeviceMemory(void);
void VerifyResult(bool* result_ech, bool* result_ecd);
void FreeMem(bool* result_ech, bool* result_ecd);
};
+69
View File
@@ -0,0 +1,69 @@
/*
Copyright (c) 2015-2016 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp
* RUN: %t
* HIT_END
*/
#include <hip/hip_runtime.h>
#include <hip/hip_runtime_api.h>
#include <iostream>
#include "test_common.h"
#define HIP_ASSERT(status) assert(status == hipSuccess)
#define LEN 512
#define SIZE 2048
struct TestClock {
static __global__ void kernel1(int* Ad) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
Ad[tid] = clock() + clock64() + __clock() + __clock64();
}
static __global__ void kernel2(int* Ad) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
Ad[tid] = clock() + clock64() + __clock() + __clock64() - Ad[tid];
}
void run() {
int *A, *Ad;
A = new int[LEN];
for (unsigned i = 0; i < LEN; i++) {
A[i] = 0;
}
HIP_ASSERT(hipMalloc((void**)&Ad, SIZE));
hipLaunchKernelGGL(kernel1, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad);
hipLaunchKernelGGL(kernel2, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad);
HIP_ASSERT(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost));
for (unsigned i = 0; i < LEN; i++) {
assert(0 != A[i]);
}
}
};
int main() {
TestClock().run();
passed();
}
+158
View File
@@ -0,0 +1,158 @@
/*
Copyright (c) 2015-2016 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp
* RUN: %t
* HIT_END
*/
// Test include math_functions.h then hip_runtime.h.
// Incorrect implementation causes compilation failure due to conflict
// declartions.
#include <hip/math_functions.h>
// Test __HIP_DEVICE_COMPILE__ is defined after math_functions.h
// is included.
//
__device__ __host__ inline void throw_std_bad_alloc()
{
#ifndef __HIP_DEVICE_COMPILE__
throw std::bad_alloc();
#else
std::size_t huge = static_cast<std::size_t>(-1);
new int[huge];
#endif
}
// Test __HIP_ARCH_HAS_WARP_FUNNEL_SHIFT__ and __HIP_ARCH_HAS_DYNAMIC_PARALLEL__
// is defined. Eigen HIP/hcc/Half.h __ldg depends on this.
#if !defined(__HIP_ARCH_HAS_WARP_FUNNEL_SHIFT__) || \
!defined(__HIP_ARCH_HAS_DYNAMIC_PARALLEL__)
#error \
"__HIP_ARCH_HAS_WARP_FUNNEL_SHIFT__ or __HIP_ARCH_HAS_DYNAMIC_PARALLEL__ not defined"
#endif
#include <hip/hip_runtime.h>
#include "test_common.h"
__global__ void FloatMathPrecise() {
int iX;
float fX, fY;
acosf(1.0f);
acoshf(1.0f);
asinf(0.0f);
asinhf(0.0f);
atan2f(0.0f, 1.0f);
atanf(0.0f);
atanhf(0.0f);
cbrtf(0.0f);
fX = ceilf(0.0f);
fX = copysignf(1.0f, -2.0f);
cosf(0.0f);
coshf(0.0f);
cospif(0.0f);
cyl_bessel_i0f(0.0f);
cyl_bessel_i1f(0.0f);
erfcf(0.0f);
erfcinvf(2.0f);
erfcxf(0.0f);
erff(0.0f);
erfinvf(1.0f);
exp10f(0.0f);
exp2f(0.0f);
expf(0.0f);
expm1f(0.0f);
fX = fabsf(1.0f);
fdimf(1.0f, 0.0f);
fdividef(0.0f, 1.0f);
fX = floorf(0.0f);
fmaf(1.0f, 2.0f, 3.0f);
fX = fmaxf(0.0f, 0.0f);
fX = fminf(0.0f, 0.0f);
fmodf(0.0f, 1.0f);
frexpf(0.0f, &iX);
hypotf(1.0f, 0.0f);
ilogbf(1.0f);
isfinite(0.0f);
fX = isinf(0.0f);
fX = isnan(0.0f);
j0f(0.0f);
j1f(0.0f);
jnf(-1.0f, 1.0f);
ldexpf(0.0f, 0);
lgammaf(1.0f);
llrintf(0.0f);
llroundf(0.0f);
log10f(1.0f);
log1pf(-1.0f);
log2f(1.0f);
logbf(1.0f);
logf(1.0f);
lrintf(0.0f);
lroundf(0.0f);
modff(0.0f, &fX);
fX = nanf("1");
fX = nearbyintf(0.0f);
nextafterf(0.0f, 0.0f);
norm3df(1.0f, 0.0f, 0.0f);
norm4df(1.0f, 0.0f, 0.0f, 0.0f);
normcdff(0.0f);
normcdfinvf(1.0f);
fX = 1.0f;
normf(1, &fX);
powf(1.0f, 0.0f);
rcbrtf(1.0f);
remainderf(2.0f, 1.0f);
remquof(1.0f, 2.0f, &iX);
rhypotf(0.0f, 1.0f);
fY = rintf(1.0f);
rnorm3df(0.0f, 0.0f, 1.0f);
rnorm4df(0.0f, 0.0f, 0.0f, 1.0f);
fX = 1.0f;
rnormf(1, &fX);
fY = roundf(0.0f);
rsqrtf(1.0f);
scalblnf(0.0f, 1);
scalbnf(0.0f, 1);
signbit(1.0f);
sincosf(0.0f, &fX, &fY);
sincospif(0.0f, &fX, &fY);
sinf(0.0f);
sinhf(0.0f);
sinpif(0.0f);
sqrtf(0.0f);
tanf(0.0f);
tanhf(0.0f);
tgammaf(2.0f);
fY = truncf(0.0f);
y0f(1.0f);
y1f(1.0f);
ynf(1, 1.0f);
}
int main() {
hipLaunchKernelGGL(FloatMathPrecise, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0);
passed();
}
+71
View File
@@ -0,0 +1,71 @@
/*
Copyright (c) 2015-2016 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp
* RUN: %t
* HIT_END
*/
#include <hip/hip_runtime.h>
#include <hip/hip_runtime_api.h>
#include <iostream>
#include "test_common.h"
#define HIP_ASSERT(status) assert(status == hipSuccess)
#define LEN 512
#define SIZE 2048
struct TestPlacementNew {
class A {
public:
__device__ A() {
a = threadIdx.x + blockIdx.x * blockDim.x;
}
private:
int a;
};
static __global__ void kernel(int* Ad) {
int tid = threadIdx.x + blockIdx.x * blockDim.x;
new(Ad+tid) A();
}
void run() {
int *A, *Ad;
A = new int[LEN];
for (unsigned i = 0; i < LEN; i++) {
A[i] = 0;
}
HIP_ASSERT(hipMalloc((void**)&Ad, SIZE));
hipLaunchKernelGGL(kernel, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad);
HIP_ASSERT(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost));
for (unsigned i = 0; i < LEN; i++) {
assert(i == A[i]);
}
}
};
int main() {
TestPlacementNew().run();
passed();
}
-13
View File
@@ -86,28 +86,15 @@ int main(int argc, char* argv[]) {
printf("warp no. %d __all = %d \n", i, host_all[i]);
if (host_all[i] != 1) ++allcount;
#if defined(__HIP_PLATFORM_HCC__) && !defined(NVCC_COMPAT)
if (host_any[i] != 64) ++anycount;
#else
if (host_any[i] != 1) ++anycount;
#endif
}
#if defined(__HIP_PLATFORM_HCC__) && !defined(NVCC_COMPAT)
if (anycount == 1 && allcount == 1)
printf("PASSED\n");
else {
printf("FAILED\n");
return EXIT_FAILURE;
}
#else
if (anycount == 0 && allcount == 1)
printf("PASSED\n");
else {
printf("FAILED\n");
return EXIT_FAILURE;
}
#endif
return EXIT_SUCCESS;
}
+220
View File
@@ -0,0 +1,220 @@
/*
Copyright (c) 2015-2016 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp EXCLUDE_HIP_PLATFORM nvcc
* RUN: %t
* HIT_END
*/
#include <assert.h>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <random>
#include "hip/hip_runtime.h"
#include <hip/device_functions.h>
#define HIP_ASSERT(x) (assert((x) == hipSuccess))
#define TEST_DEBUG (0)
// CPU implementation of bitextract
template <typename T>
T bit_extract(T src0, unsigned int src1, unsigned int src2) {
unsigned int bits = sizeof(T) * 8;
T offset = src1 & (bits - 1);
T width = src2 & (bits - 1);
if (width == 0) {
return 0;
} else {
return (src0 << (bits - width - offset)) >> (bits - width);
}
}
__global__ void HIP_kernel(hipLaunchParm lp,
unsigned int* out32, unsigned int* in32_0,
unsigned int* in32_1, unsigned int* in32_2,
unsigned long long int* out64, unsigned long long int* in64_0,
unsigned int* in64_1, unsigned int* in64_2) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
out32[x] = __bitextract_u32(in32_0[x], in32_1[x], in32_2[x]);
out64[x] = __bitextract_u64(in64_0[x], in64_1[x], in64_2[x]);
}
using namespace std;
int main() {
unsigned int* hostOut32;
unsigned int* hostSrc032;
unsigned int* hostSrc132;
unsigned int* hostSrc232;
unsigned long long int* hostOut64;
unsigned long long int* hostSrc064;
unsigned int* hostSrc164;
unsigned int* hostSrc264;
unsigned int* deviceOut32;
unsigned int* deviceSrc032;
unsigned int* deviceSrc132;
unsigned int* deviceSrc232;
unsigned long long int* deviceOut64;
unsigned long long int* deviceSrc064;
unsigned int* deviceSrc164;
unsigned int* deviceSrc264;
hipDeviceProp_t devProp;
hipGetDeviceProperties(&devProp, 0);
cout << " System minor " << devProp.minor << endl;
cout << " System major " << devProp.major << endl;
cout << " agent prop name " << devProp.name << endl;
cout << "hip Device prop succeeded " << endl;
unsigned int wave_size = devProp.warpSize;
unsigned int num_waves_per_block = 2;
unsigned int num_threads_per_block = wave_size * num_waves_per_block;
unsigned int num_blocks = 2;
unsigned int NUM = num_threads_per_block * num_blocks;
int i;
int errors;
hostOut32 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc032 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc132 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc232 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostOut64 = (unsigned long long int*)malloc(NUM * sizeof(unsigned long long int));
hostSrc064 = (unsigned long long int*)malloc(NUM * sizeof(unsigned long long int));
hostSrc164 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc264 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
// initialize the input data
std::random_device rd;
std::uniform_int_distribution<uint32_t> uint32_src0_dist;
std::uniform_int_distribution<uint32_t> uint32_src12_dist(0,31);
std::uniform_int_distribution<uint64_t> uint64_src0_dist;
std::uniform_int_distribution<uint32_t> uint64_src12_dist(0,63);
for (i = 0; i < NUM; i++) {
hostOut32[i] = 0;
hostSrc032[i] = uint32_src0_dist(rd);
hostSrc132[i] = uint32_src12_dist(rd);
hostSrc232[i] = uint32_src12_dist(rd);
hostOut64[i] = 0;
hostSrc064[i] = uint64_src0_dist(rd);
hostSrc164[i] = uint64_src12_dist(rd);
hostSrc264[i] = uint64_src12_dist(rd);
}
HIP_ASSERT(hipMalloc((void**)&deviceOut32, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc032, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc132, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc232, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceOut64, NUM * sizeof(unsigned long long int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc064, NUM * sizeof(unsigned long long int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc164, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc264, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMemcpy(deviceSrc032, hostSrc032, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc132, hostSrc132, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc232, hostSrc232, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc064, hostSrc064, NUM * sizeof(unsigned long long int),
hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc164, hostSrc164, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc264, hostSrc264, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
hipLaunchKernel(HIP_kernel, dim3(num_blocks), dim3(num_threads_per_block),
0, 0,
deviceOut32, deviceSrc032, deviceSrc132, deviceSrc232,
deviceOut64, deviceSrc064, deviceSrc164, deviceSrc264);
HIP_ASSERT(hipMemcpy(hostOut32, deviceOut32, NUM * sizeof(unsigned int), hipMemcpyDeviceToHost));
HIP_ASSERT(hipMemcpy(hostOut64, deviceOut64,
NUM * sizeof(unsigned long long int), hipMemcpyDeviceToHost));
// verify the results
errors = 0;
for (i = 0; i < NUM; i++) {
if (hostOut32[i] != bit_extract<uint32_t>(hostSrc032[i], hostSrc132[i], hostSrc232[i])) {
errors++;
#if TEST_DEBUG
cout << "device: " << hostOut32[i] << " host: "
<< bit_extract<uint32_t>(hostSrc032[i], hostSrc132[i], hostSrc232[i])
<< " " << hostSrc032[i] << " " << hostSrc132[i] << " " << hostSrc232[i] << "\n";
#endif
}
}
if (errors != 0) {
cout << "__bitextract_u32() FAILED\n" << endl;
return -1;
} else {
cout << "__bitextract_u32() checked!" << endl;
}
errors = 0;
for (i = 0; i < NUM; i++) {
if (hostOut64[i] != bit_extract<uint64_t>(hostSrc064[i], hostSrc164[i], hostSrc264[i])) {
errors++;
#if TEST_DEBUG
cout << "device: " << hostOut64[i] << " host: "
<< bit_extract<uint64_t>(hostSrc064[i], hostSrc164[i], hostSrc264[i])
<< " " << hostSrc064[i] << " " << hostSrc164[i] << " " << hostSrc264[i] << "\n";
#endif
}
}
if (errors != 0) {
cout << "__bitextract_u64() FAILED" << endl;
return -1;
} else {
cout << "__bitextract_u64() checked!" << endl;
}
cout << "__bitextract_u32() and __bitextract_u64() PASSED!" << endl;
HIP_ASSERT(hipFree(deviceOut32));
HIP_ASSERT(hipFree(deviceSrc032));
HIP_ASSERT(hipFree(deviceSrc132));
HIP_ASSERT(hipFree(deviceSrc232));
HIP_ASSERT(hipFree(deviceOut64));
HIP_ASSERT(hipFree(deviceSrc064));
HIP_ASSERT(hipFree(deviceSrc164));
HIP_ASSERT(hipFree(deviceSrc264));
free(hostOut32);
free(hostSrc032);
free(hostSrc132);
free(hostSrc232);
free(hostOut64);
free(hostSrc064);
free(hostSrc164);
free(hostSrc264);
return errors;
}
+239
View File
@@ -0,0 +1,239 @@
/*
Copyright (c) 2015-2016 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp EXCLUDE_HIP_PLATFORM nvcc
* RUN: %t
* HIT_END
*/
#include <assert.h>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <random>
#include "hip/hip_runtime.h"
#include <hip/device_functions.h>
#define HIP_ASSERT(x) (assert((x) == hipSuccess))
#define TEST_DEBUG (0)
// CPU implementation of bitinsert
template <typename T>
T bit_insert(T src0, T src1, unsigned int src2, unsigned int src3) {
unsigned int bits = sizeof(T) * 8;
T offset = src2 & (bits - 1);
T width = src3 & (bits - 1);
T mask = (1 << width) - 1;
return ((src0 & ~(mask << offset)) | ((src1 & mask) << offset));
}
__global__ void HIP_kernel(hipLaunchParm lp, unsigned int* out32,
unsigned int* in32_0, unsigned int* in32_1,
unsigned int* in32_2, unsigned int* in32_3,
unsigned long long int* out64, unsigned long long int* in64_0,
unsigned long long int* in64_1, unsigned int* in64_2,
unsigned int* in64_3) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
out32[x] = __bitinsert_u32(in32_0[x], in32_1[x], in32_2[x], in32_3[x]);
out64[x] = __bitinsert_u64(in64_0[x], in64_1[x], in64_2[x], in64_3[x]);
}
using namespace std;
int main() {
unsigned int* hostOut32;
unsigned int* hostSrc032;
unsigned int* hostSrc132;
unsigned int* hostSrc232;
unsigned int* hostSrc332;
unsigned long long int* hostOut64;
unsigned long long int* hostSrc064;
unsigned long long int* hostSrc164;
unsigned int* hostSrc264;
unsigned int* hostSrc364;
unsigned int* deviceOut32;
unsigned int* deviceSrc032;
unsigned int* deviceSrc132;
unsigned int* deviceSrc232;
unsigned int* deviceSrc332;
unsigned long long int* deviceOut64;
unsigned long long int* deviceSrc064;
unsigned long long int* deviceSrc164;
unsigned int* deviceSrc264;
unsigned int* deviceSrc364;
hipDeviceProp_t devProp;
hipGetDeviceProperties(&devProp, 0);
cout << " System minor " << devProp.minor << endl;
cout << " System major " << devProp.major << endl;
cout << " agent prop name " << devProp.name << endl;
cout << "hip Device prop succeeded " << endl;
unsigned int wave_size = devProp.warpSize;
unsigned int num_waves_per_block = 2;
unsigned int num_threads_per_block = wave_size * num_waves_per_block;
unsigned int num_blocks = 2;
unsigned int NUM = num_threads_per_block * num_blocks;
int i;
int errors;
hostOut32 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc032 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc132 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc232 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc332 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostOut64 = (unsigned long long int*)malloc(NUM * sizeof(unsigned long long int));
hostSrc064 = (unsigned long long int*)malloc(NUM * sizeof(unsigned long long int));
hostSrc164 = (unsigned long long int*)malloc(NUM * sizeof(unsigned long long int));
hostSrc264 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
hostSrc364 = (unsigned int*)malloc(NUM * sizeof(unsigned int));
// initialize the input data
std::random_device rd;
std::uniform_int_distribution<uint32_t> uint32_src01_dist;
std::uniform_int_distribution<uint32_t> uint32_src23_dist(0,31);
std::uniform_int_distribution<uint64_t> uint64_src01_dist;
std::uniform_int_distribution<uint32_t> uint64_src23_dist(0,63);
for (i = 0; i < NUM; i++) {
hostOut32[i] = 0;
hostSrc032[i] = uint32_src01_dist(rd);
hostSrc132[i] = uint32_src01_dist(rd);
hostSrc232[i] = uint32_src23_dist(rd);
hostSrc232[i] = uint32_src23_dist(rd);
hostOut64[i] = 0;
hostSrc064[i] = uint64_src01_dist(rd);
hostSrc164[i] = uint64_src01_dist(rd);
hostSrc264[i] = uint64_src23_dist(rd);
hostSrc264[i] = uint64_src23_dist(rd);
}
HIP_ASSERT(hipMalloc((void**)&deviceOut32, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc032, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc132, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc232, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc332, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceOut64, NUM * sizeof(unsigned long long int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc064, NUM * sizeof(unsigned long long int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc164, NUM * sizeof(unsigned long long int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc264, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMalloc((void**)&deviceSrc364, NUM * sizeof(unsigned int)));
HIP_ASSERT(hipMemcpy(deviceSrc032, hostSrc032, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc132, hostSrc132, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc232, hostSrc232, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc332, hostSrc332, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc064, hostSrc064, NUM * sizeof(unsigned long long int),
hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc164, hostSrc164, NUM * sizeof(unsigned long long int),
hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc264, hostSrc264, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
HIP_ASSERT(hipMemcpy(deviceSrc364, hostSrc364, NUM * sizeof(unsigned int), hipMemcpyHostToDevice));
hipLaunchKernel(HIP_kernel, dim3(num_blocks), dim3(num_threads_per_block),
0, 0,
deviceOut32, deviceSrc032, deviceSrc132, deviceSrc232, deviceSrc332,
deviceOut64, deviceSrc064, deviceSrc164, deviceSrc264, deviceSrc364);
HIP_ASSERT(hipMemcpy(hostOut32, deviceOut32, NUM * sizeof(unsigned int), hipMemcpyDeviceToHost));
HIP_ASSERT(hipMemcpy(hostOut64, deviceOut64,
NUM * sizeof(unsigned long long int), hipMemcpyDeviceToHost));
// verify the results
errors = 0;
for (i = 0; i < NUM; i++) {
if (hostOut32[i] != bit_insert<uint32_t>(hostSrc032[i], hostSrc132[i],
hostSrc232[i], hostSrc332[i])) {
errors++;
#if TEST_DEBUG
cout << "device: " << hostOut32[i] << " host: "
<< bit_insert<uint32_t>(hostSrc032[i], hostSrc132[i], hostSrc232[i], hostSrc332[i])
<< " " << hostSrc032[i] << " " << hostSrc132[i] << " " << hostSrc232[i]
<< " " << hostSrc332[i] << "\n";
#endif
}
}
if (errors != 0) {
cout << "__bitinsert_u32() FAILED\n" << endl;
return -1;
} else {
cout << "__bitinsert_u32() checked!" << endl;
}
errors = 0;
for (i = 0; i < NUM; i++) {
if (hostOut64[i] != bit_insert<uint64_t>(hostSrc064[i], hostSrc164[i],
hostSrc264[i], hostSrc364[i])) {
errors++;
#if TEST_DEBUG
cout << "device: " << hostOut64[i] << " host: "
<< bit_insert<uint64_t>(hostSrc064[i], hostSrc164[i], hostSrc264[i], hostSrc364[i])
<< " " << hostSrc064[i] << " " << hostSrc164[i] << " " << hostSrc264[i]
<< " " << hostSrc364[i] << "\n";
#endif
}
}
if (errors != 0) {
cout << "__bitinsert_u64() FAILED" << endl;
return -1;
} else {
cout << "__bitinsert_u64() checked!" << endl;
}
cout << "__bitinsert_u32() and __bitinsert_u64() PASSED!" << endl;
HIP_ASSERT(hipFree(deviceOut32));
HIP_ASSERT(hipFree(deviceSrc032));
HIP_ASSERT(hipFree(deviceSrc132));
HIP_ASSERT(hipFree(deviceSrc232));
HIP_ASSERT(hipFree(deviceSrc332));
HIP_ASSERT(hipFree(deviceOut64));
HIP_ASSERT(hipFree(deviceSrc064));
HIP_ASSERT(hipFree(deviceSrc164));
HIP_ASSERT(hipFree(deviceSrc264));
HIP_ASSERT(hipFree(deviceSrc364));
free(hostOut32);
free(hostSrc032);
free(hostSrc132);
free(hostSrc232);
free(hostSrc332);
free(hostOut64);
free(hostSrc064);
free(hostSrc164);
free(hostSrc264);
free(hostSrc364);
return errors;
}
+15 -9
View File
@@ -45,12 +45,7 @@ THE SOFTWARE.
unsigned int firstbit_u32(unsigned int a) {
if (a == 0) {
#if defined(__HIP_PLATFORM_HCC__) && !defined(NVCC_COMPAT)
return -1;
#else
return 32;
#endif
}
unsigned int pos = 0;
while ((int)a > 0) {
@@ -62,11 +57,7 @@ unsigned int firstbit_u32(unsigned int a) {
unsigned int firstbit_u64(unsigned long long int a) {
if (a == 0) {
#if defined(__HIP_PLATFORM_HCC__) && !defined(NVCC_COMPAT)
return -1;
#else
return 64;
#endif
}
unsigned int pos = 0;
while ((long long int)a > 0) {
@@ -76,6 +67,21 @@ unsigned int firstbit_u64(unsigned long long int a) {
return pos;
}
// Check implicit conversion will not cause ambiguity.
__device__ void test_ambiguity() {
short s;
unsigned short us;
float f;
int i;
unsigned int ui;
__clz(f);
__clz(s);
__clz(us);
__clzll(f);
__clzll(i);
__clzll(ui);
}
__global__ void HIP_kernel(hipLaunchParm lp, unsigned int* a, unsigned int* b, unsigned int* c,
unsigned long long int* d, int width, int height) {
int x = blockDim.x * blockIdx.x + threadIdx.x;
-8
View File
@@ -49,21 +49,13 @@ THE SOFTWARE.
template <typename T>
int lastbit(T a) {
if (a == 0)
#if defined(__HIP_PLATFORM_HCC__) && !defined(NVCC_COMPAT)
return -1;
#else
return 0;
#endif
int pos = 1;
while ((a & 1) != 1) {
a >>= 1;
pos++;
}
#if defined(__HIP_PLATFORM_HCC__) && !defined(NVCC_COMPAT)
return pos - 1;
#else
return pos;
#endif
}
+9 -2
View File
@@ -38,7 +38,10 @@ int getDeviceNumber() {
string str;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if (!(in = popen("./directed_tests/hipEnvVar -c", "r"))) {
return 1;
// Check at same level
if (!(in = popen("./hipEnvVar -c", "r"))) {
return 1;
}
}
while (fgets(buff, 512, in) != NULL) {
cout << buff;
@@ -54,7 +57,11 @@ void getDevicePCIBusNumRemote(int deviceID, char* pciBusID) {
str += std::to_string(deviceID);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if (!(in = popen(str.c_str(), "r"))) {
exit(1);
// Check at same level
if (!(in = popen("./hipEnvVar -d ", "r"))) {
exit(1);
}
}
while (fgets(pciBusID, 100, in) != NULL) {
cout << pciBusID;
+2 -2
View File
@@ -170,8 +170,8 @@ void runTests(int64_t numElements) {
// for (int waitStart=0; waitStart<2; waitStart++) {
for (int waitStart = 1; waitStart >= 0; waitStart--) {
unsigned W = waitStart ? 0x1000 : 0;
test(W | 0x01, C_d, C_h, numElements, 0, waitStart, syncNone);
test(W | 0x02, C_d, C_h, numElements, stream, waitStart, syncNone);
test(W | 0x01, C_d, C_h, numElements, 0, 0, syncNone);
test(W | 0x02, C_d, C_h, numElements, stream, 0, syncNone);
test(W | 0x04, C_d, C_h, numElements, 0, waitStart, syncStream);
test(W | 0x08, C_d, C_h, numElements, stream, waitStart, syncStream);
test(W | 0x10, C_d, C_h, numElements, 0, waitStart, syncStopEvent);
+78
View File
@@ -0,0 +1,78 @@
/*
Copyright (c) 2015-Present 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp
* RUN: %t
* HIT_END
*/
#include <hip/hip_runtime.h>
#include "test_common.h"
using namespace std;
#define R 8 //rows, height
#define C 8 //columns, width
texture<int, hipTextureType2D,hipReadModeElementType> tex;
bool runTest(void);
int main(int argc, char** argv) {
bool testResult=runTest();
if (testResult) {
passed();
} else {
exit(EXIT_FAILURE);
}
}
bool runTest()
{
int val[R][C],i,j;
size_t offset;
for(i=0;i<R;i++)
for(j=0;j<C;j++)
{
val[i][j]=(i+1)*(j+1);
}
hipChannelFormatDesc chan_desc=hipCreateChannelDesc(32,0,0,0,hipChannelFormatKindSigned);
hipArray *hipArray;
HIPCHECK(hipMallocArray(&hipArray, &chan_desc,C,R,0));
HIPCHECK(hipMemcpyToArray(hipArray,0,0, val, R*C*sizeof(int), hipMemcpyHostToDevice));
tex.addressMode[0]=hipAddressModeWrap;
tex.addressMode[1]=hipAddressModeWrap;
tex.filterMode=hipFilterModePoint;
tex.normalized=0;
HIPCHECK(hipBindTextureToArray(&tex, hipArray, &chan_desc));
HIPCHECK(hipGetTextureAlignmentOffset(&offset,&tex));
HIPCHECK(hipUnbindTexture(&tex));
HIPCHECK(hipFreeArray(hipArray));
if(offset != 0)
return false;
else
return true;
}
+63
View File
@@ -0,0 +1,63 @@
/*
Copyright (c) 2015-Present 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.
*/
/* HIT_START
* BUILD: %t %s ../test_common.cpp
* RUN: %t
* HIT_END
*/
#include <hip/hip_runtime.h>
#include "test_common.h"
using namespace std;
#define R 8 //rows, height
#define C 8 //columns, width
bool runTest(void);
int main(int argc, char** argv) {
bool testResult=runTest();
if (testResult) {
passed();
} else {
exit(EXIT_FAILURE);
}
}
bool runTest()
{
bool testResult=true;
hipChannelFormatDesc chan_test,chan_desc=hipCreateChannelDesc(32,0,0,0,hipChannelFormatKindSigned);
hipArray *hipArray;
HIPCHECK(hipMallocArray(&hipArray, &chan_desc,C,R,0));
HIPCHECK(hipGetChannelDesc(&chan_test,hipArray));
if((chan_test.x == 32)&&(chan_test.y == 0)&&(chan_test.z == 0)&&(chan_test.f == 0))
testResult=true;
else
testResult=false;
HIPCHECK(hipFreeArray(hipArray));
return testResult;
}