Merge 'master' into 'amd-master'

Change-Id: I70b2b1a6fc8998d1a0ea0e7532a0a99050784ae1
This commit is contained in:
Jenkins
2018-06-29 04:09:59 -05:00
14 zmienionych plików z 580 dodań i 420 usunięć
+6 -1
Wyświetl plik
@@ -115,8 +115,13 @@ if ($HIP_PLATFORM eq "clang") {
$ROCM_PATH=$ENV{'ROCM_PATH'} // "/opt/rocm";
$HIPCC="$HIP_CLANG_PATH/clang++";
$HIPCXXFLAGS .= "-std=c++11 -I$HIP_PATH/include";
$HIPLDFLAGS = "--hip-link --hip-device-lib-path=$DEVICE_LIB_PATH -L$HIP_PATH/lib -lhip_hcc";
# If $HIPCC clang++ is not compiled, use clang instead
if ( ! -e $HIPCC ) {
$HIPCC="$HIP_CLANG_PATH/clang";
$HIPLDFLAGS = "--driver-mode=g++ " . $HIPLDFLAGS;
}
} elsif ($HIP_PLATFORM eq "hcc") {
$HSA_PATH=$ENV{'HSA_PATH'} // "/opt/rocm/hsa";
+8 -1
Wyświetl plik
@@ -20,6 +20,7 @@ foreach(config ${_hip_configuration_types})
mark_as_advanced(HIP_HIPCC_FLAGS_${config_upper} HIP_HCC_FLAGS_${config_upper} HIP_NVCC_FLAGS_${config_upper})
endforeach()
option(HIP_HOST_COMPILATION_CPP "Host code compilation mode" ON)
option(HIP_VERBOSE_BUILD "Print out the commands run while compiling the HIP source file. With the Makefile generator this defaults to VERBOSE variable specified on the command line, but can be forced on with this option." OFF)
mark_as_advanced(HIP_HOST_COMPILATION_CPP)
###############################################################################
@@ -471,7 +472,13 @@ macro(HIP_PREPARE_TARGET_COMMANDS _target _format _generated_files _source_files
INPUT "${custom_target_script_pregen}"
)
set(main_dep DEPENDS ${source_file})
set(verbose_output "$(VERBOSE)")
if(CMAKE_GENERATOR MATCHES "Makefiles")
set(verbose_output "$(VERBOSE)")
elseif(HIP_VERBOSE_BUILD)
set(verbose_output ON)
else()
set(verbose_output OFF)
endif()
# Create up the comment string
file(RELATIVE_PATH generated_file_relative_path "${CMAKE_BINARY_DIR}" "${generated_file}")
@@ -92,6 +92,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<char2>() {
return hipCreateChannelDesc(e, e, 0, 0, hipChannelFormatKindSigned);
}
#ifndef __GNUC__ // vector3 is the same as vector4
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<uchar3>() {
int e = (int)sizeof(unsigned char) * 8;
@@ -103,6 +104,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<char3>() {
int e = (int)sizeof(signed char) * 8;
return hipCreateChannelDesc(e, e, e, 0, hipChannelFormatKindSigned);
}
#endif
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<uchar4>() {
@@ -152,6 +154,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<short2>() {
return hipCreateChannelDesc(e, e, 0, 0, hipChannelFormatKindSigned);
}
#ifndef __GNUC__
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<ushort3>() {
int e = (int)sizeof(unsigned short) * 8;
@@ -163,6 +166,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<short3>() {
int e = (int)sizeof(signed short) * 8;
return hipCreateChannelDesc(e, e, e, 0, hipChannelFormatKindSigned);
}
#endif
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<ushort4>() {
@@ -212,6 +216,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<int2>() {
return hipCreateChannelDesc(e, e, 0, 0, hipChannelFormatKindSigned);
}
#ifndef __GNUC__
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<uint3>() {
int e = (int)sizeof(unsigned int) * 8;
@@ -223,6 +228,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<int3>() {
int e = (int)sizeof(signed int) * 8;
return hipCreateChannelDesc(e, e, e, 0, hipChannelFormatKindSigned);
}
#endif
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<uint4>() {
@@ -254,11 +260,13 @@ inline hipChannelFormatDesc hipCreateChannelDesc<float2>() {
return hipCreateChannelDesc(e, e, 0, 0, hipChannelFormatKindFloat);
}
#ifndef __GNUC__
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<float3>() {
int e = (int)sizeof(float) * 8;
return hipCreateChannelDesc(e, e, e, 0, hipChannelFormatKindFloat);
}
#endif
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<float4>() {
@@ -302,6 +310,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<long2>() {
return hipCreateChannelDesc(e, e, 0, 0, hipChannelFormatKindSigned);
}
#ifndef __GNUC__
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<ulong3>() {
int e = (int)sizeof(unsigned long) * 8;
@@ -313,6 +322,7 @@ inline hipChannelFormatDesc hipCreateChannelDesc<long3>() {
int e = (int)sizeof(signed long) * 8;
return hipCreateChannelDesc(e, e, e, 0, hipChannelFormatKindSigned);
}
#endif
template <>
inline hipChannelFormatDesc hipCreateChannelDesc<ulong4>() {
@@ -23,7 +23,8 @@ THE SOFTWARE.
#ifndef HIP_INCLUDE_HIP_HCC_DETAIL_DEVICE_FUNCTIONS_H
#define HIP_INCLUDE_HIP_HCC_DETAIL_DEVICE_FUNCTIONS_H
#include <hip/hip_runtime.h>
#include "host_defines.h"
#include <hip/hip_vector_types.h>
extern "C" __device__ unsigned int __hip_hc_ir_umul24_int(unsigned int, unsigned int);
+269
Wyświetl plik
@@ -0,0 +1,269 @@
#pragma once
#include "device_functions.h"
__device__
inline
int atomicCAS(int* address, int compare, int val)
{
__atomic_compare_exchange_n(
address, &compare, val, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
return compare;
}
__device__
inline
unsigned int atomicCAS(
unsigned int* address, unsigned int compare, unsigned int val)
{
__atomic_compare_exchange_n(
address, &compare, val, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
return compare;
}
__device__
inline
unsigned long long atomicCAS(
unsigned long long* address,
unsigned long long compare,
unsigned long long val)
{
__atomic_compare_exchange_n(
address, &compare, val, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
return compare;
}
__device__
inline
int atomicAdd(int* address, int val)
{
return __atomic_fetch_add(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicAdd(unsigned int* address, unsigned int val)
{
return __atomic_fetch_add(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned long long atomicAdd(
unsigned long long* address, unsigned long long val)
{
return __atomic_fetch_add(address, val, __ATOMIC_RELAXED);
}
__device__
inline
float atomicAdd(float* address, float val)
{
unsigned int* uaddr{reinterpret_cast<unsigned int*>(address)};
unsigned int old{__atomic_load_n(uaddr, __ATOMIC_RELAXED)};
unsigned int r;
do {
r = old;
old = atomicCAS(uaddr, r, __float_as_uint(val + __uint_as_float(r)));
} while (r != old);
return __uint_as_float(r);
}
__device__
inline
double atomicAdd(double* address, double val)
{
unsigned long long* uaddr{reinterpret_cast<unsigned long long*>(address)};
unsigned long long old{__atomic_load_n(uaddr, __ATOMIC_RELAXED)};
unsigned long long r;
do {
r = old;
old = atomicCAS(
uaddr, r, __double_as_longlong(val + __longlong_as_double(r)));
} while (r != old);
return __longlong_as_double(r);
}
__device__
inline
int atomicSub(int* address, int val)
{
return __atomic_fetch_sub(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicSub(unsigned int* address, unsigned int val)
{
return __atomic_fetch_sub(address, val, __ATOMIC_RELAXED);
}
__device__
inline
int atomicExch(int* address, int val)
{
return __atomic_exchange_n(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicExch(unsigned int* address, unsigned int val)
{
return __atomic_exchange_n(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicExch(unsigned long long* address, unsigned long long val)
{
return __atomic_exchange_n(address, val, __ATOMIC_RELAXED);
}
__device__
inline
float atomicExch(float* address, float val)
{
return __uint_as_float(__atomic_exchange_n(
reinterpret_cast<unsigned int*>(address),
__float_as_uint(val),
__ATOMIC_RELAXED));
}
__device__
inline
int atomicMin(int* address, int val)
{
return __sync_fetch_and_min(address, val);
}
__device__
inline
unsigned int atomicMin(unsigned int* address, unsigned int val)
{
return __sync_fetch_and_umin(address, val);
}
__device__
inline
unsigned long long atomicMin(
unsigned long long* address, unsigned long long val)
{
unsigned long long tmp{__atomic_load_n(address, __ATOMIC_RELAXED)};
while (val < tmp) { tmp = atomicCAS(address, tmp, val); }
return tmp;
}
__device__
inline
int atomicMax(int* address, int val)
{
return __sync_fetch_and_max(address, val);
}
__device__
inline
unsigned int atomicMax(unsigned int* address, unsigned int val)
{
return __sync_fetch_and_umax(address, val);
}
__device__
inline
unsigned long long atomicMax(
unsigned long long* address, unsigned long long val)
{
unsigned long long tmp{__atomic_load_n(address, __ATOMIC_RELAXED)};
while (tmp < val) { tmp = atomicCAS(address, tmp, val); }
return tmp;
}
__device__
inline
unsigned int atomicInc(unsigned int* address, unsigned int val)
{
__device__
extern
unsigned int __builtin_amdgcn_atomic_inc(
unsigned int*,
unsigned int,
unsigned int,
unsigned int,
bool) __asm("llvm.amdgcn.atomic.inc.i32.p0i32");
return __builtin_amdgcn_atomic_inc(
address, val, __ATOMIC_RELAXED, 1 /* Device scope */, false);
}
__device__
inline
unsigned int atomicDec(unsigned int* address, unsigned int val)
{
__device__
extern
unsigned int __builtin_amdgcn_atomic_dec(
unsigned int*,
unsigned int,
unsigned int,
unsigned int,
bool) __asm("llvm.amdgcn.atomic.dec.i32.p0i32");
return __builtin_amdgcn_atomic_dec(
address, val, __ATOMIC_RELAXED, 1 /* Device scope */, false);
}
__device__
inline
int atomicAnd(int* address, int val)
{
return __atomic_fetch_and(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicAnd(unsigned int* address, unsigned int val)
{
return __atomic_fetch_and(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned long long atomicAnd(
unsigned long long* address, unsigned long long val)
{
return __atomic_fetch_and(address, val, __ATOMIC_RELAXED);
}
__device__
inline
int atomicOr(int* address, int val)
{
return __atomic_fetch_or(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicOr(unsigned int* address, unsigned int val)
{
return __atomic_fetch_or(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned long long atomicOr(
unsigned long long* address, unsigned long long val)
{
return __atomic_fetch_or(address, val, __ATOMIC_RELAXED);
}
__device__
inline
int atomicXor(int* address, int val)
{
return __atomic_fetch_xor(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned int atomicXor(unsigned int* address, unsigned int val)
{
return __atomic_fetch_xor(address, val, __ATOMIC_RELAXED);
}
__device__
inline
unsigned long long atomicXor(
unsigned long long* address, unsigned long long val)
{
return __atomic_fetch_xor(address, val, __ATOMIC_RELAXED);
}
// TODO: add scoped atomics i.e. atomic{*}_system && atomic{*}_block.
+54 -2
Wyświetl plik
@@ -24,9 +24,35 @@ THE SOFTWARE.
#define HIP_INCLUDE_HIP_HCC_DETAIL_HIP_COMPLEX_H
#include "hip/hcc_detail/hip_vector_types.h"
#include <math.h>
// TODO: Clang has a bug which allows device functions to call std functions
// when std functions are introduced into default namespace by using statement.
// math.h may be included after this bug is fixed.
#if __cplusplus
#include <cmath>
#else
#include "math.h"
#endif
#if __cplusplus
#define COMPLEX_NEG_OP_OVERLOAD(type) \
__device__ __host__ static inline type operator-(const type& op) { \
type ret; \
ret.x = -op.x; \
ret.y = -op.y; \
return ret; \
}
#define COMPLEX_EQ_OP_OVERLOAD(type) \
__device__ __host__ static inline bool operator==(const type& lhs, const type& rhs) { \
return lhs.x == rhs.x && lhs.y == rhs.y; \
}
#define COMPLEX_NE_OP_OVERLOAD(type) \
__device__ __host__ static inline bool operator!=(const type& lhs, const type& rhs) { \
return !(lhs == rhs); \
}
#define COMPLEX_ADD_OP_OVERLOAD(type) \
__device__ __host__ static inline type operator+(const type& lhs, const type& rhs) { \
type ret; \
@@ -94,12 +120,16 @@ THE SOFTWARE.
ret.y = lhs.y * rhs; \
return ret; \
}
#define MAKE_COMPONENT_CONSTRUCTOR_TWO_COMPONENT(ComplexT, T) \
__device__ __host__ ComplexT(T val) : x(val), y(val) {} \
__device__ __host__ ComplexT(T val1, T val2) : x(val1), y(val2) {}
#endif
struct hipFloatComplex {
#ifdef __cplusplus
public:
typedef float value_type;
__device__ __host__ hipFloatComplex() : x(0.0f), y(0.0f) {}
__device__ __host__ hipFloatComplex(float x) : x(x), y(0.0f) {}
__device__ __host__ hipFloatComplex(float x, float y) : x(x), y(y) {}
@@ -119,6 +149,7 @@ struct hipFloatComplex {
struct hipDoubleComplex {
#ifdef __cplusplus
public:
typedef double value_type;
__device__ __host__ hipDoubleComplex() : x(0.0f), y(0.0f) {}
__device__ __host__ hipDoubleComplex(double x) : x(x), y(0.0f) {}
__device__ __host__ hipDoubleComplex(double x, double y) : x(x), y(y) {}
@@ -137,6 +168,9 @@ struct hipDoubleComplex {
#if __cplusplus
COMPLEX_NEG_OP_OVERLOAD(hipFloatComplex)
COMPLEX_EQ_OP_OVERLOAD(hipFloatComplex)
COMPLEX_NE_OP_OVERLOAD(hipFloatComplex)
COMPLEX_ADD_OP_OVERLOAD(hipFloatComplex)
COMPLEX_SUB_OP_OVERLOAD(hipFloatComplex)
COMPLEX_MUL_OP_OVERLOAD(hipFloatComplex)
@@ -156,6 +190,9 @@ COMPLEX_SCALAR_PRODUCT(hipFloatComplex, double)
COMPLEX_SCALAR_PRODUCT(hipFloatComplex, signed long long)
COMPLEX_SCALAR_PRODUCT(hipFloatComplex, unsigned long long)
COMPLEX_NEG_OP_OVERLOAD(hipDoubleComplex)
COMPLEX_EQ_OP_OVERLOAD(hipDoubleComplex)
COMPLEX_NE_OP_OVERLOAD(hipDoubleComplex)
COMPLEX_ADD_OP_OVERLOAD(hipDoubleComplex)
COMPLEX_SUB_OP_OVERLOAD(hipDoubleComplex)
COMPLEX_MUL_OP_OVERLOAD(hipDoubleComplex)
@@ -221,7 +258,6 @@ __device__ __host__ static inline hipFloatComplex hipCdivf(hipFloatComplex p, hi
__device__ __host__ static inline float hipCabsf(hipFloatComplex z) { return sqrtf(hipCsqabsf(z)); }
__device__ __host__ static inline double hipCreal(hipDoubleComplex z) { return z.x; }
__device__ __host__ static inline double hipCimag(hipDoubleComplex z) { return z.y; }
@@ -301,4 +337,20 @@ __device__ __host__ static inline hipDoubleComplex hipCfma(hipDoubleComplex p, h
return make_hipDoubleComplex(real, imag);
}
// Complex functions returning real numbers.
#define __DEFINE_HIP_COMPLEX_REAL_FUN(func, hipFun) \
__device__ __host__ inline float func(const hipFloatComplex& z) { return hipFun##f(z); } \
__device__ __host__ inline double func(const hipDoubleComplex& z) { return hipFun(z); }
__DEFINE_HIP_COMPLEX_REAL_FUN(abs, hipCabs)
__DEFINE_HIP_COMPLEX_REAL_FUN(real, hipCreal)
__DEFINE_HIP_COMPLEX_REAL_FUN(imag, hipCimag)
// Complex functions returning complex numbers.
#define __DEFINE_HIP_COMPLEX_FUN(func, hipFun) \
__device__ __host__ inline hipFloatComplex func(const hipFloatComplex& z) { return hipFun##f(z); } \
__device__ __host__ inline hipDoubleComplex func(const hipDoubleComplex& z) { return hipFun(z); }
__DEFINE_HIP_COMPLEX_FUN(conj, hipConj)
#endif
+1 -1
Wyświetl plik
@@ -21,7 +21,7 @@ THE SOFTWARE.
*/
#pragma once
#include "hip/hcc_detail/host_defines.h"
#include <assert.h>
#if defined(__cplusplus)
#include <algorithm>
+36 -36
Wyświetl plik
@@ -28,49 +28,49 @@ THE SOFTWARE.
extern "C"
{
__attribute__((const)) _Float16 __ocml_ceil_f16(_Float16);
_Float16 __ocml_cos_f16(_Float16);
__attribute__((pure)) _Float16 __ocml_exp_f16(_Float16);
__attribute__((pure)) _Float16 __ocml_exp10_f16(_Float16);
__attribute__((pure)) _Float16 __ocml_exp2_f16(_Float16);
__attribute__((const)) _Float16 __ocml_floor_f16(_Float16);
__attribute__((const))
__device__ __attribute__((const)) _Float16 __ocml_ceil_f16(_Float16);
__device__ _Float16 __ocml_cos_f16(_Float16);
__device__ __attribute__((pure)) _Float16 __ocml_exp_f16(_Float16);
__device__ __attribute__((pure)) _Float16 __ocml_exp10_f16(_Float16);
__device__ __attribute__((pure)) _Float16 __ocml_exp2_f16(_Float16);
__device__ __attribute__((const)) _Float16 __ocml_floor_f16(_Float16);
__device__ __attribute__((const))
_Float16 __ocml_fma_f16(_Float16, _Float16, _Float16);
__attribute__((const)) int __ocml_isinf_f16(_Float16);
__attribute__((const)) int __ocml_isnan_f16(_Float16);
__attribute__((pure)) _Float16 __ocml_log_f16(_Float16);
__attribute__((pure)) _Float16 __ocml_log10_f16(_Float16);
__attribute__((pure)) _Float16 __ocml_log2_f16(_Float16);
__attribute__((const)) _Float16 __llvm_amdgcn_rcp_f16(_Float16);
__attribute__((const)) _Float16 __ocml_rint_f16(_Float16);
__attribute__((const)) _Float16 __ocml_rsqrt_f16(_Float16);
_Float16 __ocml_sin_f16(_Float16);
__attribute__((const)) _Float16 __ocml_sqrt_f16(_Float16);
__attribute__((const)) _Float16 __ocml_trunc_f16(_Float16);
__device__ __attribute__((const)) int __ocml_isinf_f16(_Float16);
__device__ __attribute__((const)) int __ocml_isnan_f16(_Float16);
__device__ __attribute__((pure)) _Float16 __ocml_log_f16(_Float16);
__device__ __attribute__((pure)) _Float16 __ocml_log10_f16(_Float16);
__device__ __attribute__((pure)) _Float16 __ocml_log2_f16(_Float16);
__device__ __attribute__((const)) _Float16 __llvm_amdgcn_rcp_f16(_Float16);
__device__ __attribute__((const)) _Float16 __ocml_rint_f16(_Float16);
__device__ __attribute__((const)) _Float16 __ocml_rsqrt_f16(_Float16);
__device__ _Float16 __ocml_sin_f16(_Float16);
__device__ __attribute__((const)) _Float16 __ocml_sqrt_f16(_Float16);
__device__ __attribute__((const)) _Float16 __ocml_trunc_f16(_Float16);
typedef _Float16 __2f16 __attribute__((ext_vector_type(2)));
typedef short __2i16 __attribute__((ext_vector_type(2)));
__attribute__((const)) __2f16 __ocml_ceil_2f16(__2f16);
__2f16 __ocml_cos_2f16(__2f16);
__attribute__((pure)) __2f16 __ocml_exp_2f16(__2f16);
__attribute__((pure)) __2f16 __ocml_exp10_2f16(__2f16);
__attribute__((pure)) __2f16 __ocml_exp2_2f16(__2f16);
__attribute__((const)) __2f16 __ocml_floor_2f16(__2f16);
__attribute__((const)) __2f16 __ocml_fma_2f16(__2f16, __2f16, __2f16);
__attribute__((const)) __2i16 __ocml_isinf_2f16(__2f16);
__attribute__((const)) __2i16 __ocml_isnan_2f16(__2f16);
__attribute__((pure)) __2f16 __ocml_log_2f16(__2f16);
__attribute__((pure)) __2f16 __ocml_log10_2f16(__2f16);
__attribute__((pure)) __2f16 __ocml_log2_2f16(__2f16);
inline
__device__ __attribute__((const)) __2f16 __ocml_ceil_2f16(__2f16);
__device__ __2f16 __ocml_cos_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_exp_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_exp10_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_exp2_2f16(__2f16);
__device__ __attribute__((const)) __2f16 __ocml_floor_2f16(__2f16);
__device__ __attribute__((const)) __2f16 __ocml_fma_2f16(__2f16, __2f16, __2f16);
__device__ __attribute__((const)) __2i16 __ocml_isinf_2f16(__2f16);
__device__ __attribute__((const)) __2i16 __ocml_isnan_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_log_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_log10_2f16(__2f16);
__device__ __attribute__((pure)) __2f16 __ocml_log2_2f16(__2f16);
__device__ inline
__2f16 __llvm_amdgcn_rcp_2f16(__2f16 x) // Not currently exposed by ROCDL.
{
return __2f16{__llvm_amdgcn_rcp_f16(x.x), __llvm_amdgcn_rcp_f16(x.y)};
}
__attribute__((const)) __2f16 __ocml_rint_2f16(__2f16);
__attribute__((const)) __2f16 __ocml_rsqrt_2f16(__2f16);
__2f16 __ocml_sin_2f16(__2f16);
__attribute__((const)) __2f16 __ocml_sqrt_2f16(__2f16);
__attribute__((const)) __2f16 __ocml_trunc_2f16(__2f16);
__device__ __attribute__((const)) __2f16 __ocml_rint_2f16(__2f16);
__device__ __attribute__((const)) __2f16 __ocml_rsqrt_2f16(__2f16);
__device__ __2f16 __ocml_sin_2f16(__2f16);
__device__ __attribute__((const)) __2f16 __ocml_sqrt_2f16(__2f16);
__device__ __attribute__((const)) __2f16 __ocml_trunc_2f16(__2f16);
}
+6 -81
Wyświetl plik
@@ -98,23 +98,28 @@ struct Empty_launch_parm {};
#include "grid_launch_GGL.hpp"
#endif // GENERIC_GRID_LAUNCH
#endif // HCC
#if __HCC_OR_HIP_CLANG__
extern int HIP_TRACE_API;
#ifdef __cplusplus
#include <hip/hcc_detail/hip_ldg.h>
#endif
#include <hip/hcc_detail/hip_atomic.h>
#include <hip/hcc_detail/host_defines.h>
#include <hip/hcc_detail/math_functions.h>
#include <hip/hcc_detail/device_functions.h>
#if __HCC__
#include <hip/hcc_detail/texture_functions.h>
#include <hip/hcc_detail/surface_functions.h>
#endif // __HCC__
// TODO-HCC remove old definitions ; ~1602 hcc supports __HCC_ACCELERATOR__ define.
#if defined(__KALMAR_ACCELERATOR__) && !defined(__HCC_ACCELERATOR__)
#define __HCC_ACCELERATOR__ __KALMAR_ACCELERATOR__
#endif
// TODO-HCC add a dummy implementation of assert, need to replace with a proper kernel exit call.
#if __HIP_DEVICE_COMPILE__ == 1
#undef assert
@@ -179,10 +184,6 @@ extern int HIP_TRACE_API;
#define __HCC_C__
#endif
#endif // defined __HCC__
#if __HCC_OR_HIP_CLANG__
// TODO - hipify-clang - change to use the function call.
//#define warpSize hc::__wavesize()
static constexpr int warpSize = 64;
@@ -194,82 +195,6 @@ __device__ clock_t clock();
// abort
__device__ void abort();
// atomicAdd()
__device__ int atomicAdd(int* address, int val);
__device__ unsigned int atomicAdd(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicAdd(unsigned long long int* address,
unsigned long long int val);
__device__ float atomicAdd(float* address, float val);
// atomicSub()
__device__ int atomicSub(int* address, int val);
__device__ unsigned int atomicSub(unsigned int* address, unsigned int val);
// atomicExch()
__device__ int atomicExch(int* address, int val);
__device__ unsigned int atomicExch(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicExch(unsigned long long int* address,
unsigned long long int val);
__device__ float atomicExch(float* address, float val);
// atomicMin()
__device__ int atomicMin(int* address, int val);
__device__ unsigned int atomicMin(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicMin(unsigned long long int* address,
unsigned long long int val);
// atomicMax()
__device__ int atomicMax(int* address, int val);
__device__ unsigned int atomicMax(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicMax(unsigned long long int* address,
unsigned long long int val);
// atomicCAS()
__device__ int atomicCAS(int* address, int compare, int val);
__device__ unsigned int atomicCAS(unsigned int* address, unsigned int compare, unsigned int val);
__device__ unsigned long long int atomicCAS(unsigned long long int* address,
unsigned long long int compare,
unsigned long long int val);
// atomicAnd()
__device__ int atomicAnd(int* address, int val);
__device__ unsigned int atomicAnd(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicAnd(unsigned long long int* address,
unsigned long long int val);
// atomicOr()
__device__ int atomicOr(int* address, int val);
__device__ unsigned int atomicOr(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicOr(unsigned long long int* address,
unsigned long long int val);
// atomicXor()
__device__ int atomicXor(int* address, int val);
__device__ unsigned int atomicXor(unsigned int* address, unsigned int val);
__device__ unsigned long long int atomicXor(unsigned long long int* address,
unsigned long long int val);
// atomicInc()
__device__ unsigned int atomicInc(unsigned int* address, unsigned int val);
// atomicDec()
__device__ unsigned int atomicDec(unsigned int* address, unsigned int val);
// warp vote function __all __any __ballot
__device__ int __all(int input);
__device__ int __any(int input);
+9 -9
Wyświetl plik
@@ -508,19 +508,19 @@ inline
float __fadd_rz(float x, float y) { return __ocml_add_rtz_f32(x, y); }
__device__
inline
float __fdiv_rd(float x, float y) { return __ocml_div_rtp_f32(x, y); }
float __fdiv_rd(float x, float y) { return x / y; }
__device__
inline
float __fdiv_rn(float x, float y) { return __ocml_div_rte_f32(x, y); }
float __fdiv_rn(float x, float y) { return x / y; }
__device__
inline
float __fdiv_ru(float x, float y) { return __ocml_div_rtn_f32(x, y); }
float __fdiv_ru(float x, float y) { return x / y; }
__device__
inline
float __fdiv_rz(float x, float y) { return __ocml_div_rtz_f32(x, y); }
float __fdiv_rz(float x, float y) { return x / y; }
__device__
inline
float __fdividef(float x, float y) { return __ocml_div_rte_f32(x, y); }
float __fdividef(float x, float y) { return x / y; }
__device__
inline
float __fmaf_rd(float x, float y, float z)
@@ -1028,16 +1028,16 @@ inline
double __dadd_rz(double x, double y) { return __ocml_add_rtz_f64(x, y); }
__device__
inline
double __ddiv_rd(double x, double y) { return __ocml_div_rtp_f64(x, y); }
double __ddiv_rd(double x, double y) { return x / y; }
__device__
inline
double __ddiv_rn(double x, double y) { return __ocml_div_rte_f64(x, y); }
double __ddiv_rn(double x, double y) { return x / y; }
__device__
inline
double __ddiv_ru(double x, double y) { return __ocml_div_rtn_f64(x, y); }
double __ddiv_ru(double x, double y) { return x / y; }
__device__
inline
double __ddiv_rz(double x, double y) { return __ocml_div_rtz_f64(x, y); }
double __ddiv_rz(double x, double y) { return x / y; }
__device__
inline
double __dmul_rd(double x, double y) { return __ocml_mul_rtp_f64(x, y); }
-26
Wyświetl plik
@@ -69,8 +69,6 @@ float __ocml_cosh_f32(float);
__device__
float __ocml_cospi_f32(float);
__device__
float __ocml_div_rtz_f32(float, float);
__device__
float __ocml_i0_f32(float);
__device__
float __ocml_i1_f32(float);
@@ -290,18 +288,6 @@ __attribute__((const))
float __ocml_mul_rtz_f32(float, float);
__device__
__attribute__((const))
float __ocml_div_rte_f32(float, float);
__device__
__attribute__((const))
float __ocml_div_rtn_f32(float, float);
__device__
__attribute__((const))
float __ocml_div_rtp_f32(float, float);
__device__
__attribute__((const))
float __ocml_div_rtz_f32(float, float);
__device__
__attribute__((const))
float __ocml_sqrt_rte_f32(float);
__device__
__attribute__((const))
@@ -598,18 +584,6 @@ __attribute__((const))
double __ocml_mul_rtz_f64(double, double);
__device__
__attribute__((const))
double __ocml_div_rte_f64(double, double);
__device__
__attribute__((const))
double __ocml_div_rtn_f64(double, double);
__device__
__attribute__((const))
double __ocml_div_rtp_f64(double, double);
__device__
__attribute__((const))
double __ocml_div_rtz_f64(double, double);
__device__
__attribute__((const))
double __ocml_sqrt_rte_f64(double);
__device__
__attribute__((const))
+1 -1
Wyświetl plik
@@ -64,4 +64,4 @@ THE SOFTWARE.
#include <hip/hip_runtime_api.h>
#include <hip/hip_vector_types.h>
#endif
#endif
-123
Wyświetl plik
@@ -150,129 +150,6 @@ __device__ clock_t clock() { return (clock_t)hc::__cycle_u64(); };
// abort
__device__ void abort() { return hc::abort(); }
// atomicAdd()
__device__ int atomicAdd(int* address, int val) { return hc::atomic_fetch_add(address, val); }
__device__ unsigned int atomicAdd(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_add(address, val);
}
__device__ unsigned long long int atomicAdd(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_fetch_add((uint64_t*)address, (uint64_t)val);
}
__device__ float atomicAdd(float* address, float val) { return hc::atomic_fetch_add(address, val); }
// atomicSub()
__device__ int atomicSub(int* address, int val) { return hc::atomic_fetch_sub(address, val); }
__device__ unsigned int atomicSub(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_sub(address, val);
}
// atomicExch()
__device__ int atomicExch(int* address, int val) { return hc::atomic_exchange(address, val); }
__device__ unsigned int atomicExch(unsigned int* address, unsigned int val) {
return hc::atomic_exchange(address, val);
}
__device__ unsigned long long int atomicExch(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_exchange((uint64_t*)address, (uint64_t)val);
}
__device__ float atomicExch(float* address, float val) { return hc::atomic_exchange(address, val); }
// atomicMin()
__device__ int atomicMin(int* address, int val) { return hc::atomic_fetch_min(address, val); }
__device__ unsigned int atomicMin(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_min(address, val);
}
__device__ unsigned long long int atomicMin(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_fetch_min((uint64_t*)address, (uint64_t)val);
}
// atomicMax()
__device__ int atomicMax(int* address, int val) { return hc::atomic_fetch_max(address, val); }
__device__ unsigned int atomicMax(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_max(address, val);
}
__device__ unsigned long long int atomicMax(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_fetch_max((uint64_t*)address, (uint64_t)val);
}
// atomicCAS()
template <typename T>
__device__ T atomicCAS_impl(T* address, T compare, T val) {
// the implementation assumes the atomic is lock-free and
// has the same size as the non-atmoic equivalent type
static_assert(sizeof(T) == sizeof(std::atomic<T>),
"size mismatch between atomic and non-atomic types");
union {
T* address;
std::atomic<T>* atomic_address;
} u;
u.address = address;
T expected = compare;
// hcc should generate a system scope atomic CAS
std::atomic_compare_exchange_weak_explicit(
u.atomic_address, &expected, val, std::memory_order_acq_rel, std::memory_order_relaxed);
return expected;
}
__device__ int atomicCAS(int* address, int compare, int val) {
return atomicCAS_impl(address, compare, val);
}
__device__ unsigned int atomicCAS(unsigned int* address, unsigned int compare, unsigned int val) {
return atomicCAS_impl(address, compare, val);
}
__device__ unsigned long long int atomicCAS(unsigned long long int* address,
unsigned long long int compare,
unsigned long long int val) {
return atomicCAS_impl(address, compare, val);
}
// atomicAnd()
__device__ int atomicAnd(int* address, int val) { return hc::atomic_fetch_and(address, val); }
__device__ unsigned int atomicAnd(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_and(address, val);
}
__device__ unsigned long long int atomicAnd(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_fetch_and((uint64_t*)address, (uint64_t)val);
}
// atomicOr()
__device__ int atomicOr(int* address, int val) { return hc::atomic_fetch_or(address, val); }
__device__ unsigned int atomicOr(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_or(address, val);
}
__device__ unsigned long long int atomicOr(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_fetch_or((uint64_t*)address, (uint64_t)val);
}
// atomicXor()
__device__ int atomicXor(int* address, int val) { return hc::atomic_fetch_xor(address, val); }
__device__ unsigned int atomicXor(unsigned int* address, unsigned int val) {
return hc::atomic_fetch_xor(address, val);
}
__device__ unsigned long long int atomicXor(unsigned long long int* address,
unsigned long long int val) {
return (long long int)hc::atomic_fetch_xor((uint64_t*)address, (uint64_t)val);
}
// atomicInc
__device__ unsigned int atomicInc(unsigned int* address, unsigned int val) {
return hc::__atomic_wrapinc(address, val);
}
// atomicDec
__device__ unsigned int atomicDec(unsigned int* address, unsigned int val) {
return hc::__atomic_wrapdec(address, val);
}
// warp vote function __all __any __ballot
__device__ int __all(int input) { return hc::__all(input); }
+178 -138
Wyświetl plik
@@ -23,134 +23,37 @@ THE SOFTWARE.
* HIT_END
*/
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
// Includes HIP Runtime
#include "hip/hip_runtime.h"
#include <test_common.h>
// includes, system
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <type_traits>
#define EXIT_WAIVED 2
const char* sampleName = "hipSimpleAtomicsTest";
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// Auto-Verification Code
bool testResult = true;
////////////////////////////////////////////////////////////////////////////////
// Declaration, forward
void runTest(int argc, char** argv);
bool computeGoldBitwise(...) {
return true;
}
#define min(a, b) (a) < (b) ? (a) : (b)
#define max(a, b) (a) > (b) ? (a) : (b)
int computeGold(int* gpuData, const int len) {
int val = 0;
for (int i = 0; i < len; ++i) {
val += 10;
}
if (val != gpuData[0]) {
printf("atomicAdd failed\n");
return false;
}
val = 0;
for (int i = 0; i < len; ++i) {
val -= 10;
}
if (val != gpuData[1]) {
printf("atomicSub failed\n");
return false;
}
bool found = false;
for (int i = 0; i < len; ++i) {
// third element should be a member of [0, len)
if (i == gpuData[2]) {
found = true;
break;
}
}
if (!found) {
printf("atomicExch failed\n");
return false;
}
val = -(1 << 8);
for (int i = 0; i < len; ++i) {
// fourth element should be len-1
val = max(val, i);
}
if (val != gpuData[3]) {
printf("atomicMax failed\n");
return false;
}
val = 1 << 8;
for (int i = 0; i < len; ++i) {
val = min(val, i);
}
if (val != gpuData[4]) {
printf("atomicMin failed\n");
return false;
}
int limit = 17;
val = 0;
for (int i = 0; i < len; ++i) {
val = (val >= limit) ? 0 : val + 1;
}
if (val != gpuData[5]) {
printf("atomicInc failed\n");
return false;
}
limit = 137;
val = 0;
for (int i = 0; i < len; ++i) {
val = ((val == 0) || (val > limit)) ? limit : val - 1;
}
if (val != gpuData[6]) {
printf("atomicDec failed\n");
return false;
}
found = false;
for (int i = 0; i < len; ++i) {
// eighth element should be a member of [0, len)
if (i == gpuData[7]) {
found = true;
break;
}
}
if (!found) {
printf("atomicCAS failed\n");
return false;
}
val = 0xff;
template<typename T, typename enable_if<is_integral<T>{}>::type* = nullptr>
bool computeGoldBitwise(T* gpuData, int len) {
T val = 0xff;
for (int i = 0; i < len; ++i) {
// 9th element should be 1
@@ -189,22 +92,142 @@ int computeGold(int* gpuData, const int len) {
return true;
}
__global__ void testKernel(hipLaunchParm lp, int* g_odata) {
template<typename T>
bool computeGold(T* gpuData, int len) {
T val = 0;
for (int i = 0; i < len; ++i) {
val += 10;
}
if (val != gpuData[0]) {
printf("atomicAdd failed\n");
return false;
}
val = 0;
for (int i = 0; i < len; ++i) {
val -= 10;
}
if (val != gpuData[1]) {
printf("atomicSub failed\n");
return false;
}
bool found = false;
for (T i = 0; i < len; ++i) {
// third element should be a member of [0, len)
if (i == gpuData[2]) {
found = true;
break;
}
}
if (!found) {
printf("atomicExch failed\n");
return false;
}
val = -(1 << 8);
for (T i = 0; i < len; ++i) {
// fourth element should be len-1
val = max(val, i);
}
if (val != gpuData[3]) {
printf("atomicMax failed\n");
return false;
}
val = 1 << 8;
for (T i = 0; i < len; ++i) {
val = min(val, i);
}
if (val != gpuData[4]) {
printf("atomicMin failed\n");
return false;
}
int limit = 17;
val = 0;
for (int i = 0; i < len; ++i) {
val = (val >= limit) ? 0 : val + 1;
}
if (val != gpuData[5]) {
printf("atomicInc failed\n");
return false;
}
limit = 137;
val = 0;
for (int i = 0; i < len; ++i) {
val = ((val == 0) || (val > limit)) ? limit : val - 1;
}
if (val != gpuData[6]) {
printf("atomicDec failed\n");
return false;
}
found = false;
for (T i = 0; i < len; ++i) {
// eighth element should be a member of [0, len)
if (i == gpuData[7]) {
found = true;
break;
}
}
if (!found) {
printf("atomicCAS failed\n");
return false;
}
return computeGoldBitwise(gpuData, len);
}
__device__
void testKernelExch(...) {}
template<typename T, typename enable_if<!is_same<T, double>{}>::type* = nullptr>
__device__
void testKernelExch(T* g_odata) {
// access thread id
const unsigned int tid = blockDim.x * blockIdx.x + threadIdx.x;
// Test various atomic instructions
// Arithmetic atomic instructions
// Atomic addition
atomicAdd(&g_odata[0], 10);
// Atomic subtraction (final should be 0)
atomicSub(&g_odata[1], 10);
const T tid = blockDim.x * blockIdx.x + threadIdx.x;
// Atomic exchange
atomicExch(&g_odata[2], tid);
}
__device__
void testKernelSub(...) {}
template<
typename T,
typename enable_if<
is_same<T, int>{} || is_same<T, unsigned int>{}>::type* = nullptr>
void testKernelSub(T* g_odata) {
// Atomic subtraction (final should be 0)
atomicSub(&g_odata[1], 10);
}
__device__
void testKernelIntegral(...) {}
template<typename T, typename enable_if<is_integral<T>{}>::type* = nullptr>
__device__
void testKernelIntegral(T* g_odata) {
// access thread id
const T tid = blockDim.x * blockIdx.x + threadIdx.x;
// Atomic maximum
atomicMax(&g_odata[3], tid);
@@ -231,20 +254,21 @@ __global__ void testKernel(hipLaunchParm lp, int* g_odata) {
// Atomic XOR
atomicXor(&g_odata[10], tid);
testKernelSub(g_odata);
}
template<typename T>
__global__ void testKernel(T* g_odata) {
// Atomic addition
atomicAdd(&g_odata[0], 10);
int main(int argc, char** argv) {
printf("%s starting...\n", sampleName);
runTest(argc, argv);
hipDeviceReset();
printf("%s completed, returned %s\n", sampleName, testResult ? "OK" : "ERROR!");
exit(testResult ? EXIT_SUCCESS : EXIT_FAILURE);
testKernelIntegral(g_odata);
testKernelExch(g_odata);
}
void runTest(int argc, char** argv) {
template<typename T>
void runTest() {
hipDeviceProp_t deviceProp;
deviceProp.major = 0;
deviceProp.minor = 0;
@@ -262,10 +286,10 @@ void runTest(int argc, char** argv) {
unsigned int numThreads = 256;
unsigned int numBlocks = 64;
unsigned int numData = 11;
unsigned int memSize = sizeof(int) * numData;
unsigned int memSize = sizeof(T) * numData;
// allocate mem for the result on host side
int* hOData = (int*)malloc(memSize);
T* hOData = (T*)malloc(memSize);
// initialize the memory
for (unsigned int i = 0; i < numData; i++) hOData[i] = 0;
@@ -274,13 +298,14 @@ void runTest(int argc, char** argv) {
hOData[8] = hOData[10] = 0xff;
// allocate device memory for result
int* dOData;
T* dOData;
hipMalloc((void**)&dOData, memSize);
// copy host memory to device to initialize to zero
hipMemcpy(dOData, hOData, memSize, hipMemcpyHostToDevice);
// execute the kernel
hipLaunchKernel(testKernel, dim3(numBlocks), dim3(numThreads), 0, 0, dOData);
hipLaunchKernelGGL(
testKernel, dim3(numBlocks), dim3(numThreads), 0, 0, dOData);
// Copy result from device to host
hipMemcpy(hOData, dOData, memSize, hipMemcpyDeviceToHost);
@@ -294,3 +319,18 @@ void runTest(int argc, char** argv) {
passed();
}
int main(int argc, char** argv) {
printf("%s starting...\n", sampleName);
runTest<int>();
runTest<unsigned int>();
runTest<unsigned long long>();
runTest<float>();
runTest<double>();
hipDeviceReset();
printf("%s completed, returned %s\n", sampleName, testResult ? "OK" : "ERROR!");
exit(testResult ? EXIT_SUCCESS : EXIT_FAILURE);
}