Generalize custom uniform generator for floating point data types with 16 bits
authorGiorgio Arena <giorgio.arena@arm.com>
Wed, 6 Jan 2021 11:34:57 +0000 (11:34 +0000)
committerGiorgio Arena <giorgio.arena@arm.com>
Thu, 7 Jan 2021 09:56:45 +0000 (09:56 +0000)
- 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>
17 files changed:
support/Random.h
tests/AssetsLibrary.h
tests/validation/fixtures/ArgMinMaxFixture.h
tests/validation/fixtures/ConvertFullyConnectedWeightsFixture.h
tests/validation/fixtures/ConvolutionLayerFixture.h
tests/validation/fixtures/DeconvolutionLayerFixture.h
tests/validation/fixtures/DepthwiseConvolutionLayerFixture.h
tests/validation/fixtures/DirectConvolutionLayerFixture.h
tests/validation/fixtures/DirectConvolutionLayerTensorShiftFixture.h
tests/validation/fixtures/ElementWiseUnaryFixture.h
tests/validation/fixtures/FFTFixture.h
tests/validation/fixtures/GEMMFixture.h
tests/validation/fixtures/GEMMInterleave4x4Fixture.h
tests/validation/fixtures/GEMMLowpFixture.h
tests/validation/fixtures/GEMMTranspose1xWFixture.h
tests/validation/fixtures/WinogradConvolutionLayerFixture.h
utils/Utils.h

index d5d372dc82763bcd5aa0f90d138bd4f178d3a517..7658e6d529122e29abc96a6b0b9e3c4d0f6623b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 Arm Limited.
+ * Copyright (c) 2019-2021 Arm Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -44,10 +44,10 @@ template <typename T>
 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>;
index f44c5546359bdb661373b9ffad7d6cfb07ec2531..8230a93fbdef8e502d97aa1d1517225899d478a8 100644 (file)
@@ -776,14 +776,14 @@ void AssetsLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_t
         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;
         }
@@ -881,8 +881,8 @@ void AssetsLibrary::fill_tensor_uniform_ranged(T
         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;
         }
@@ -974,13 +974,13 @@ void AssetsLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_t
         }
         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;
         }
index fdf9ac4e5b4e8c234f10591005593a12f2a3f320..f140c9846bfa95cd071998cc166bd51391a727be 100644 (file)
@@ -61,7 +61,7 @@ protected:
         {
             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;
             }
index a4705b12503091fa5fdcb7222f3f758d2908e7f1..d7984830f50f2e57f785214f7d1404ecac0e7d3d 100644 (file)
@@ -67,7 +67,7 @@ protected:
             }
             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;
             }
index 210afbef5b36ac487c6fa92c21a8af104b4e5a01..006c5eb70506e8f7cac1001a3cea4d29d4c63f97 100644 (file)
@@ -141,9 +141,14 @@ protected:
                 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;
             }
index 6394caf457b36fa9b032c8b942b043ecf631a761..6ea2335ae94891246179c17763297b9659cbb524 100644 (file)
@@ -91,7 +91,7 @@ protected:
             }
             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;
             }
index 09f8cb4c06b86e41401f24de7e085a937d9317d2..bb1c105555937127ddcbcc1c931b433c1cacbcb7 100644 (file)
@@ -99,7 +99,7 @@ protected:
             }
             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;
             }
@@ -354,7 +354,7 @@ protected:
             }
             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;
             }
index 1967e8dc4d8706027221e21d873e159795ab09c4..8e4de77535ea0f69ad6da85ccab32b50126f4cd1 100644 (file)
@@ -109,7 +109,7 @@ protected:
             }
             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;
             }
index 7e891fe682543ea0f3575da8ca8041b6bea22cd0..f39595f0de2c2c6affa7e647fd30f8aff4fcb9ce 100644 (file)
@@ -94,7 +94,7 @@ protected:
             }
             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;
             }
index 26484be2fa2c2e9a877d5fbe2d132db72079d72f..f414daf8f71c9dcd59bf4a91dfed30932d272539 100644 (file)
@@ -76,7 +76,7 @@ protected:
                 {
                     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;
                     }
index 37c2f2faecb1cf2ab68dc9705edf6d5ceff21bdc..86a97272a06813f257bd73461e921130321af45c 100644 (file)
@@ -63,7 +63,7 @@ protected:
         {
             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;
             }
@@ -151,7 +151,7 @@ protected:
         {
             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;
             }
index 0c2f0a410e12babb0c378b8c807ed9d0c0337494..192e77e5aa23f8d77beb74b870cfc5d5472b4d8c 100644 (file)
@@ -64,7 +64,7 @@ protected:
         {
             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;
             }
index 30708e4e7dc80faa77e45f749020fadf3de992ba..1ce0eafeadf35e8bdb68667bf0ffe6463b1bd2f0 100644 (file)
@@ -64,7 +64,7 @@ protected:
         {
             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;
             }
index b9140ebd3e7cf699ea6ac6747587a77d2f2535bc..24c1a24d405482473f6c41b8e4b4361d54ea6ef7 100644 (file)
@@ -79,7 +79,7 @@ void fill(U &&tensor, int i)
         }
         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;
         }
index 3d6ac76681d548c4e931ad627073b299e7e0bb53..2d2e70697ac7587032884b823209c38f460a20d4 100644 (file)
@@ -65,7 +65,7 @@ protected:
         {
             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;
             }
index 5a40815a6713b7b990e819a7033793918dcdf8dd..e1cc95337554d5ce84e125ac39164d0faece0cb3 100644 (file)
@@ -177,7 +177,7 @@ protected:
         {
             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;
             }
@@ -500,7 +500,7 @@ protected:
         {
             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;
             }
index 9862514a9e8450655537067e0108ddfe59b4f88a..9c9026edc45ac28aa8c8b4517c4b9c1d48bbe3f8 100644 (file)
@@ -294,16 +294,19 @@ inline void unmap(GCTensor &tensor)
  *  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)
     {
     }
@@ -312,9 +315,9 @@ public:
      *
      * @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:
@@ -770,10 +773,10 @@ void fill_tensor_vector(TensorType &tensor, std::vector<T> vec)
 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);