- Change name of uniform_real_distribution_fp16 to uniform_real_distribution_16bit, and make it also accept bfloat16 data type
Resolves: COMPMID-4057
Signed-off-by: Giorgio Arena <giorgio.arena@arm.com>
Change-Id: Id2f1a84b9c9f09cb260a0785add4fc5954d5853a
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/4768
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
/*
- * Copyright (c) 2019-2020 Arm Limited.
+ * Copyright (c) 2019-2021 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
class RangedUniformDistribution
{
public:
- static constexpr bool is_half = std::is_same<T, half>::value;
- static constexpr bool is_integral = std::is_integral<T>::value && !is_half;
+ static constexpr bool is_fp_16bit = std::is_same<T, half>::value || std::is_same<T, bfloat16>::value;
+ static constexpr bool is_integral = std::is_integral<T>::value && !is_fp_16bit;
- using fp_dist = typename std::conditional<is_half, arm_compute::utils::uniform_real_distribution_fp16, std::uniform_real_distribution<T>>::type;
+ using fp_dist = typename std::conditional<is_fp_16bit, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>::type;
using DT = typename std::conditional<is_integral, std::uniform_int_distribution<T>, fp_dist>::type;
using result_type = T;
using range_pair = std::pair<result_type, result_type>;
case DataType::BFLOAT16:
{
// It doesn't make sense to check [-inf, inf], so hard code it to a big number
- std::uniform_real_distribution<float> distribution_bf16(-1000.f, 1000.f);
+ arm_compute::utils::uniform_real_distribution_16bit<bfloat16> distribution_bf16(-1000.f, 1000.f);
fill(tensor, distribution_bf16, seed_offset);
break;
}
case DataType::F16:
{
// It doesn't make sense to check [-inf, inf], so hard code it to a big number
- arm_compute::utils::uniform_real_distribution_fp16 distribution_f16{ -100.f, 100.f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution_f16{ -100.f, 100.f };
fill(tensor, distribution_f16, seed_offset);
break;
}
case DataType::BFLOAT16:
{
// It doesn't make sense to check [-inf, inf], so hard code it to a big number
- const auto converted_pairs = detail::convert_range_pair<float>(excluded_range_pairs);
- RangedUniformDistribution<float> distribution_bf16(-1000.f, 1000.f, converted_pairs);
+ const auto converted_pairs = detail::convert_range_pair<bfloat16>(excluded_range_pairs);
+ RangedUniformDistribution<bfloat16> distribution_bf16(bfloat16(-1000.f), bfloat16(1000.f), converted_pairs);
fill(tensor, distribution_bf16, seed_offset);
break;
}
}
case DataType::BFLOAT16:
{
- std::uniform_real_distribution<float> distribution_bf16(low, high);
+ arm_compute::utils::uniform_real_distribution_16bit<bfloat16> distribution_bf16(low, high);
fill(tensor, distribution_bf16, seed_offset);
break;
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution_f16{ float(low), float(high) };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution_f16{ float(low), float(high) };
fill(tensor, distribution_f16, seed_offset);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, 0);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
break;
}
case DataType::BFLOAT16:
+ {
+ arm_compute::utils::uniform_real_distribution_16bit<bfloat16> distribution{ -1.0f, 1.0f };
+ library->fill(tensor, distribution, i);
+ break;
+ }
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ float(-1.0f), float(1.0f) };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ float(-1.0f), float(1.0f) };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -2.0f, 2.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -2.0f, 2.0f };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -5.0f, 5.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -5.0f, 5.0f };
library->fill(tensor, distribution, 0);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ float(lo), float(hi) };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ float(lo), float(hi) };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
}
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ -1.0f, 1.0f };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ float(min), float(max) };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ float(min), float(max) };
library->fill(tensor, distribution, i);
break;
}
{
case DataType::F16:
{
- arm_compute::utils::uniform_real_distribution_fp16 distribution{ float(min), float(max) };
+ arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ float(min), float(max) };
library->fill(tensor, distribution, i);
break;
}
* uniform_real_distribution<half> generates values that get rounded off to zero, causing
* differences between ACL and reference implementation
*/
-class uniform_real_distribution_fp16
+template <typename T>
+class uniform_real_distribution_16bit
{
+ static_assert(std::is_same<T, half>::value || std::is_same<T, bfloat16>::value, "Only half and bfloat16 data types supported");
+
public:
- using result_type = half;
+ using result_type = T;
/** Constructor
*
* @param[in] min Minimum value of the distribution
* @param[in] max Maximum value of the distribution
*/
- explicit uniform_real_distribution_fp16(float min = 0.f, float max = 1.0)
+ explicit uniform_real_distribution_16bit(float min = 0.f, float max = 1.0)
: dist(min, max)
{
}
*
* @param[in] gen an uniform random bit generator object
*/
- half operator()(std::mt19937 &gen)
+ T operator()(std::mt19937 &gen)
{
- return half(dist(gen));
+ return T(dist(gen));
}
private:
template <typename T, typename TensorType>
void fill_random_tensor(TensorType &tensor, std::random_device::result_type seed, T lower_bound = std::numeric_limits<T>::lowest(), T upper_bound = std::numeric_limits<T>::max())
{
- constexpr bool is_half = std::is_same<T, half>::value;
- constexpr bool is_integral = std::is_integral<T>::value && !is_half;
+ constexpr bool is_fp_16bit = std::is_same<T, half>::value || std::is_same<T, bfloat16>::value;
+ constexpr bool is_integral = std::is_integral<T>::value && !is_fp_16bit;
- using fp_dist_type = typename std::conditional<is_half, arm_compute::utils::uniform_real_distribution_fp16, std::uniform_real_distribution<T>>::type;
+ using fp_dist_type = typename std::conditional<is_fp_16bit, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>::type;
using dist_type = typename std::conditional<is_integral, std::uniform_int_distribution<T>, fp_dist_type>::type;
std::mt19937 gen(seed);