aboutsummaryrefslogtreecommitdiff
path: root/tests/validation/fixtures/GEMMFixture.h
diff options
context:
space:
mode:
authorJakub Sujak <jakub.sujak@arm.com>2023-08-24 14:01:20 +0100
committerJakub Sujak <jakub.sujak@arm.com>2023-09-04 14:41:16 +0000
commit0d27b2ee8d811d66693555ac1e7be44d93e662e2 (patch)
tree8b62a464a8bb9cd46702c8b5a60f3a97e3821b41 /tests/validation/fixtures/GEMMFixture.h
parent7ff03b67ba7ce669223f4d807e18fa3efa2f729b (diff)
downloadComputeLibrary-0d27b2ee8d811d66693555ac1e7be44d93e662e2.tar.gz
Remove legacy PostOps code
PostOps was the experimental interface for Dynamic Fusion. It is now replaced by the new Dynamic Fusion interface with code generation using the Compute Kernel Writer. Resolves: COMPMID-6190 Change-Id: I813b48facef2fd6f3aee332588886b4f9b3d33d8 Signed-off-by: Jakub Sujak <jakub.sujak@arm.com> Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/10219 Benchmark: Arm Jenkins <bsgcomp@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: SiCong Li <sicong.li@arm.com> Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'tests/validation/fixtures/GEMMFixture.h')
-rw-r--r--tests/validation/fixtures/GEMMFixture.h740
1 files changed, 14 insertions, 726 deletions
diff --git a/tests/validation/fixtures/GEMMFixture.h b/tests/validation/fixtures/GEMMFixture.h
index f1e0ee9150..afde3d8067 100644
--- a/tests/validation/fixtures/GEMMFixture.h
+++ b/tests/validation/fixtures/GEMMFixture.h
@@ -21,14 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef ARM_COMPUTE_TEST_GEMM_FIXTURE
-#define ARM_COMPUTE_TEST_GEMM_FIXTURE
+#ifndef ACL_TESTS_VALIDATION_FIXTURES_GEMMFIXTURE_H
+#define ACL_TESTS_VALIDATION_FIXTURES_GEMMFIXTURE_H
#include "arm_compute/core/KernelDescriptors.h"
#include "arm_compute/core/TensorShape.h"
#include "arm_compute/core/Types.h"
-#include "arm_compute/core/experimental/IPostOp.h"
-#include "src/core/experimental/PostOpUtils.h"
#include "tests/AssetsLibrary.h"
#include "tests/Globals.h"
#include "tests/IAccessor.h"
@@ -38,7 +36,6 @@
#include "tests/validation/reference/ActivationLayer.h"
#include "tests/validation/reference/ElementwiseOperations.h"
#include "tests/validation/reference/GEMM.h"
-#include "tests/validation/reference/PostOps.h"
#include <random>
@@ -304,8 +301,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -426,8 +422,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -580,8 +575,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs_reshaped },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -734,8 +728,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs_reshaped },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -908,8 +901,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs_reshaped },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -960,262 +952,6 @@ protected:
SimpleTensor<T> _reference{};
};
-/** (EXPERIMENTAL_POST_OPS)*/
-template <typename TensorType, typename AccessorType, typename T, typename ReshapeLHSOperatorType, typename ReshapeRHSOperatorType, typename GEMMOperatorType, bool fp_mixed_precision = false>
-class GEMMMatrixMultiplyReshapedWithPostOpsValidationFixture : public framework::Fixture
-{
-public:
- using PostOpArgBroadcast = std::tuple<bool, bool, bool>; // Instruct fixture if we need broadcasting in dimension 0, 1, 2 of each PostOp argument
-public:
- void setup(unsigned int m, unsigned int n, unsigned int k, unsigned int batch_size, unsigned int m0, unsigned int n0, unsigned int k0, unsigned int v0, unsigned int h0, bool interleave_lhs,
- bool interleave_rhs, bool export_to_cl_image, DataType data_type, float alpha, float beta, bool broadcast_bias, bool lhs_transpose, const ActivationLayerInfo &act_info,
- const experimental::PostOpList<PostOpArgBroadcast> &post_ops)
- {
- GEMMLHSMatrixInfo lhs_info;
- lhs_info.m0 = m0;
- lhs_info.k0 = k0;
- lhs_info.v0 = v0;
- lhs_info.interleave = interleave_lhs;
- lhs_info.transpose = lhs_transpose;
-
- GEMMRHSMatrixInfo rhs_info;
- rhs_info.n0 = n0;
- rhs_info.k0 = k0;
- rhs_info.h0 = h0;
- rhs_info.interleave = interleave_rhs;
- rhs_info.transpose = !lhs_transpose;
- rhs_info.export_to_cl_image = export_to_cl_image;
-
- // Set the tensor shapes for LHS and RHS matrices
- const TensorShape lhs_shape(k, m, batch_size);
- const TensorShape rhs_shape(n, k, batch_size);
- const TensorShape bias_shape(n,
- broadcast_bias ? 1 : m,
- broadcast_bias ? 1 : batch_size);
- auto post_ops_with_shapes = experimental::transform_post_op_list_arguments<PostOpArgBroadcast, TensorShape>(post_ops,
- [ = ](auto broadcast)
- {
- return TensorShape
- {
- std::get<0>(broadcast) ? 1 : n,
- std::get<1>(broadcast) ? 1 : m,
- std::get<2>(broadcast) ? 1 : batch_size,
- };
- });
-
- _target = compute_target(lhs_shape, rhs_shape, bias_shape, lhs_info, rhs_info, data_type, alpha, beta, broadcast_bias, act_info, post_ops_with_shapes);
- if(validate_result)
- {
- _reference = compute_reference(lhs_shape, rhs_shape, data_type, alpha, beta, broadcast_bias, act_info, post_ops_with_shapes);
- }
- }
-
-protected:
- template <typename U>
- void fill(U &&tensor, int i)
- {
- static_assert(std::is_floating_point<T>::value || std::is_same<T, half>::value, "Only floating point data types supported.");
- using DistributionType = typename std::conditional<std::is_same<T, half>::value, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>::type;
-
- DistributionType distribution{ T(-1.0f), T(1.0f) };
- library->fill(tensor, distribution, i);
-
- // Fill border with infinity in order to check the presence of NaN values (i.e. inf * 0)
- DistributionType distribution_inf{ T(std::numeric_limits<float>::infinity()), T(std::numeric_limits<float>::infinity()) };
- library->fill_borders_with_garbage(tensor, distribution_inf, i);
- }
-
- TensorType compute_target(const TensorShape &lhs_shape, const TensorShape &rhs_shape, const TensorShape &bias_shape, const GEMMLHSMatrixInfo &lhs_info, const GEMMRHSMatrixInfo &rhs_info,
- DataType data_type, float alpha, float beta, bool broadcast_bias, const ActivationLayerInfo &act_info, const experimental::PostOpList<TensorShape> &post_ops)
- {
- // Create tensors
- TensorType lhs = create_tensor<TensorType>(lhs_shape, data_type, 1);
- TensorType rhs = create_tensor<TensorType>(rhs_shape, data_type, 1);
- TensorType bias = create_tensor<TensorType>(bias_shape, data_type, 1);
-
- // Create post op tensors and populate post op with them
- std::vector<TensorType> post_op_tensors_holder{};
- auto populated_post_ops = experimental::transform_post_op_list_arguments<TensorShape, ITensorInfo *>(post_ops,
- [&post_op_tensors_holder, &data_type](auto shape)
- {
- auto t = create_tensor<TensorType>(shape, data_type, 1);
- post_op_tensors_holder.push_back(std::move(t));
- return post_op_tensors_holder.back().info();
- });
- TensorType lhs_reshaped;
- TensorType rhs_reshaped;
- TensorType dst;
-
- const unsigned int M = lhs_shape[1];
- const unsigned int N = rhs_shape[0];
- const unsigned int K = lhs_shape[0];
- GEMMKernelInfo kernel_info;
- kernel_info.m = M;
- kernel_info.n = N;
- kernel_info.k = K;
- kernel_info.depth_output_gemm3d = 0;
- kernel_info.reinterpret_input_as_3d = false;
- kernel_info.broadcast_bias = broadcast_bias;
- kernel_info.activation_info = act_info;
- kernel_info.fp_mixed_precision = fp_mixed_precision;
- kernel_info.post_ops = populated_post_ops;
-
- // The output tensor will be auto-initialized within the function
-
- // Create and configure function
- ReshapeLHSOperatorType reshape_lhs;
- ReshapeRHSOperatorType reshape_rhs;
- GEMMOperatorType gemm;
-
- validate_result = bool(reshape_rhs.validate(rhs.info(), rhs_reshaped.info(), rhs_info));
- validate_result = validate_result || !rhs_info.export_to_cl_image;
- if(!validate_result)
- {
- return nullptr;
- }
-
- reshape_lhs.configure(lhs.info(), lhs_reshaped.info(), lhs_info);
- reshape_rhs.configure(rhs.info(), rhs_reshaped.info(), rhs_info);
- gemm.configure(lhs_reshaped.info(), rhs_reshaped.info(), bias.info(), dst.info(), alpha, beta, lhs_info, rhs_info, kernel_info);
-
- ARM_COMPUTE_ASSERT(lhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(rhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(bias.info()->is_resizable());
- for(const auto &tensor : post_op_tensors_holder)
- {
- ARM_COMPUTE_ASSERT(tensor.info()->is_resizable());
- }
-
- // We do not pad when using image as it needs to comply to strict pitch alignment restrictions
- if(!rhs_info.export_to_cl_image)
- {
- add_padding_x({ &lhs, &rhs, &lhs_reshaped, &rhs_reshaped, &bias, &dst });
- for(auto &tensor : post_op_tensors_holder)
- {
- add_padding_x({ &tensor });
- }
- }
-
- // Allocate tensors
- lhs.allocator()->allocate();
- rhs.allocator()->allocate();
- lhs_reshaped.allocator()->allocate();
- rhs_reshaped.allocator()->allocate();
- bias.allocator()->allocate();
- dst.allocator()->allocate();
- for(auto &tensor : post_op_tensors_holder)
- {
- tensor.allocator()->allocate();
- }
-
- ARM_COMPUTE_ASSERT(!lhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!rhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!bias.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!lhs_reshaped.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!rhs_reshaped.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!dst.info()->is_resizable());
- for(const auto &tensor : post_op_tensors_holder)
- {
- ARM_COMPUTE_ASSERT(!tensor.info()->is_resizable());
- }
-
- // Fill tensors
- fill(AccessorType(lhs), 0);
- fill(AccessorType(rhs), 1);
- fill(AccessorType(bias), 2);
- for(size_t i = 0; i < post_op_tensors_holder.size(); ++i)
- {
- fill(AccessorType(post_op_tensors_holder.at(i)), 3 + i);
- }
-
- // Compute GEMM
- ITensorPack reshape_lhs_pack = { { ACL_SRC, &lhs }, { ACL_DST, &lhs_reshaped } };
- reshape_lhs.run(reshape_lhs_pack);
- ITensorPack reshape_rhs_pack = { { ACL_SRC, &rhs }, { ACL_DST, &rhs_reshaped } };
- reshape_rhs.run(reshape_rhs_pack);
- ITensorPack gemm_pack({ { ACL_SRC_0, &lhs_reshaped },
- { ACL_SRC_1, &rhs_reshaped },
- { ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
- for(size_t i = 0; i < post_op_tensors_holder.size(); ++i)
- {
- gemm_pack.add_tensor(experimental::get_post_op_arg_type(i), &post_op_tensors_holder.at(i));
- }
- gemm.run(gemm_pack);
-
- return dst;
- }
-
- SimpleTensor<T> compute_reference(const TensorShape &lhs_shape, const TensorShape &rhs_shape, DataType data_type, float alpha, float beta, bool broadcast_bias,
- const ActivationLayerInfo &act_info, const experimental::PostOpList<TensorShape> &post_ops)
- {
- TensorShape dst_shape = lhs_shape;
- dst_shape[0] = rhs_shape[0];
- dst_shape[1] = lhs_shape[1];
-
- // Create reference
- SimpleTensor<T> lhs{ lhs_shape, data_type, 1 };
- SimpleTensor<T> rhs{ rhs_shape, data_type, 1 };
- SimpleTensor<T> bias{ dst_shape, data_type, 1 };
- // Create post op tensors and populate post op with them
- auto populated_post_ops = experimental::transform_post_op_list_arguments<TensorShape, SimpleTensor<T>>(post_ops, [&data_type](auto shape)
- {
- return SimpleTensor<T> { shape, data_type, 1 };
- });
-
- const int n = rhs_shape[0];
- const int m = lhs_shape[1];
- const int batch_size = lhs_shape[2];
-
- // Fill reference
- int tensor_idx = 0;
- fill(lhs, tensor_idx++);
- fill(rhs, tensor_idx++);
- fill(bias, tensor_idx++);
- for(auto &op : populated_post_ops.get_list())
- {
- for(auto tensor : op->arguments())
- {
- fill(*tensor, tensor_idx++);
- }
- }
-
- if(broadcast_bias)
- {
- // In case of broadcast, we need to simply copy the first into the following "M" ones
- for(int i = 1; i < m * batch_size; i++)
- {
- memcpy(bias.data() + i * n, bias.data(), n * sizeof(T));
- }
- }
-
- SimpleTensor<T> out;
- if(fp_mixed_precision)
- {
- out = reference::gemm_mixed_precision<T>(lhs, rhs, bias, alpha, beta);
- }
- else
- {
- out = reference::gemm<T>(lhs, rhs, bias, alpha, beta);
- }
- // Ignore activation info if post ops are used instead
- if(populated_post_ops.size() > 0)
- {
- out = reference::post_ops<T>(out, populated_post_ops);
- }
- else
- {
- out = reference::activation_layer(out, act_info);
- }
- return out;
- }
-
- bool validate_result = true;
- TensorType _target{};
- SimpleTensor<T> _reference{};
-};
-
template <typename TensorType, typename AccessorType, typename T, typename ReshapeLHSOperatorType, typename ReshapeRHSOperatorType, typename GEMMOperatorType, bool fp_mixed_precision = false>
class GEMMMatrixMultiplyReshaped3DValidationFixture : public framework::Fixture
{
@@ -1344,8 +1080,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs_reshaped },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -1515,8 +1250,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -1560,242 +1294,6 @@ protected:
SimpleTensor<T> _reference{};
};
-/** (EXPERIMENTAL_POST_OPS)*/
-template <typename TensorType, typename AccessorType, typename T, typename ReshapeRHSOperatorType, typename GEMMOperatorType>
-class GEMMMatrixMultiplyReshapedOnlyRHSWithPostOpsValidationFixture : public framework::Fixture
-{
-public:
- using PostOpArgBroadcast = std::tuple<bool, bool, bool>; // Instruct fixture if we need broadcasting in dimension 0, 1, 2 of each PostOp argument
- void setup(unsigned int m, unsigned int n, unsigned int k, unsigned int batch_size, unsigned int m0, unsigned int n0, unsigned int k0, unsigned int h0,
- bool interleave_rhs, bool transpose_rhs, bool export_to_cl_image, DataType data_type, float alpha, float beta, bool broadcast_bias, const ActivationLayerInfo &act_info,
- const experimental::PostOpList<PostOpArgBroadcast> &post_ops)
- {
- GEMMLHSMatrixInfo lhs_info;
- lhs_info.m0 = m0;
- lhs_info.k0 = k0;
-
- GEMMRHSMatrixInfo rhs_info;
- rhs_info.n0 = n0;
- rhs_info.k0 = k0;
- rhs_info.h0 = h0;
- rhs_info.interleave = interleave_rhs;
- rhs_info.transpose = transpose_rhs;
- rhs_info.export_to_cl_image = export_to_cl_image;
-
- // Set the tensor shapes for LHS and RHS matrices
- const TensorShape lhs_shape(k, m, batch_size);
- const TensorShape rhs_shape(n, k, batch_size);
- const TensorShape bias_shape(n,
- broadcast_bias ? 1 : m,
- broadcast_bias ? 1 : batch_size);
- auto post_ops_with_shapes = experimental::transform_post_op_list_arguments<PostOpArgBroadcast, TensorShape>(post_ops,
- [ = ](auto broadcast)
- {
- return TensorShape
- {
- std::get<0>(broadcast) ? 1 : n,
- std::get<1>(broadcast) ? 1 : m,
- std::get<2>(broadcast) ? 1 : batch_size,
- };
- });
-
- _target = compute_target(lhs_shape, rhs_shape, bias_shape, lhs_info, rhs_info, data_type, alpha, beta, broadcast_bias, act_info, post_ops_with_shapes);
- if(validate_result)
- {
- _reference = compute_reference(lhs_shape, rhs_shape, data_type, alpha, beta, broadcast_bias, act_info, post_ops_with_shapes);
- }
- }
-
-protected:
- template <typename U>
- void fill(U &&tensor, int i)
- {
- static_assert(std::is_floating_point<T>::value || std::is_same<T, half>::value, "Only floating point data types supported.");
- using DistributionType = typename std::conditional<std::is_same<T, half>::value, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>::type;
-
- DistributionType distribution{ T(-1.0f), T(1.0f) };
- library->fill(tensor, distribution, i);
-
- // Fill border with infinity in order to check the presence of NaN values (i.e. inf * 0)
- DistributionType distribution_inf{ T(std::numeric_limits<float>::infinity()), T(std::numeric_limits<float>::infinity()) };
- library->fill_borders_with_garbage(tensor, distribution_inf, i);
- }
-
- TensorType compute_target(const TensorShape &lhs_shape, const TensorShape &rhs_shape, const TensorShape &bias_shape, const GEMMLHSMatrixInfo &lhs_info, const GEMMRHSMatrixInfo &rhs_info,
- DataType data_type, float alpha, float beta, bool broadcast_bias, const ActivationLayerInfo &act_info, const experimental::PostOpList<TensorShape> &post_ops)
- {
- // Create tensors
- TensorType lhs = create_tensor<TensorType>(lhs_shape, data_type, 1);
- TensorType rhs = create_tensor<TensorType>(rhs_shape, data_type, 1);
- TensorType bias = create_tensor<TensorType>(bias_shape, data_type, 1);
- TensorType rhs_reshaped;
- TensorType dst;
- // Create post op tensors and populate post op with them
- std::vector<TensorType> post_op_tensors_holder{};
- auto populated_post_ops = experimental::transform_post_op_list_arguments<TensorShape, ITensorInfo *>(post_ops,
- [&post_op_tensors_holder, &data_type](auto shape)
- {
- auto t = create_tensor<TensorType>(shape, data_type, 1);
- post_op_tensors_holder.push_back(std::move(t));
- return post_op_tensors_holder.back().info();
- });
-
- const unsigned int M = lhs_shape[1];
- const unsigned int N = rhs_shape[0];
- const unsigned int K = lhs_shape[0];
- GEMMKernelInfo kernel_info;
- kernel_info.m = M;
- kernel_info.n = N;
- kernel_info.k = K;
- kernel_info.depth_output_gemm3d = 0;
- kernel_info.reinterpret_input_as_3d = false;
- kernel_info.broadcast_bias = broadcast_bias;
- kernel_info.activation_info = act_info;
- kernel_info.post_ops = populated_post_ops;
-
- // The output tensor will be auto-initialized within the function
-
- // Create and configure function
- ReshapeRHSOperatorType reshape_rhs;
- GEMMOperatorType gemm;
-
- validate_result = bool(reshape_rhs.validate(rhs.info(), rhs_reshaped.info(), rhs_info));
- validate_result = validate_result || !rhs_info.export_to_cl_image;
- if(!validate_result)
- {
- return nullptr;
- }
-
- reshape_rhs.configure(rhs.info(), rhs_reshaped.info(), rhs_info);
- gemm.configure(lhs.info(), rhs_reshaped.info(), bias.info(), dst.info(), alpha, beta, lhs_info, rhs_info, kernel_info);
-
- ARM_COMPUTE_ASSERT(lhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(rhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(bias.info()->is_resizable());
- for(const auto &tensor : post_op_tensors_holder)
- {
- ARM_COMPUTE_ASSERT(tensor.info()->is_resizable());
- }
-
- // We do not pad when using image as it needs to comply to strict pitch alignment restrictions
- if(!rhs_info.export_to_cl_image)
- {
- add_padding_x({ &lhs, &rhs, &rhs_reshaped, &bias, &dst });
- for(auto &tensor : post_op_tensors_holder)
- {
- add_padding_x({ &tensor });
- }
- }
-
- // Allocate tensors
- lhs.allocator()->allocate();
- rhs.allocator()->allocate();
- rhs_reshaped.allocator()->allocate();
- bias.allocator()->allocate();
- dst.allocator()->allocate();
- for(auto &tensor : post_op_tensors_holder)
- {
- tensor.allocator()->allocate();
- }
-
- ARM_COMPUTE_ASSERT(!lhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!rhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!rhs_reshaped.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!bias.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!dst.info()->is_resizable());
- for(const auto &tensor : post_op_tensors_holder)
- {
- ARM_COMPUTE_ASSERT(!tensor.info()->is_resizable());
- }
-
- // Fill tensors
- fill(AccessorType(lhs), 0);
- fill(AccessorType(rhs), 1);
- fill(AccessorType(bias), 2);
- for(size_t i = 0; i < post_op_tensors_holder.size(); ++i)
- {
- fill(AccessorType(post_op_tensors_holder.at(i)), 3 + i);
- }
-
- // Compute GEMM
- ITensorPack reshape_rhs_pack = { { ACL_SRC, &rhs }, { ACL_DST, &rhs_reshaped } };
- reshape_rhs.run(reshape_rhs_pack);
- ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
- { ACL_SRC_1, &rhs_reshaped },
- { ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
- for(size_t i = 0; i < post_op_tensors_holder.size(); ++i)
- {
- gemm_pack.add_tensor(experimental::get_post_op_arg_type(i), &post_op_tensors_holder.at(i));
- }
- gemm.run(gemm_pack);
-
- return dst;
- }
-
- SimpleTensor<T> compute_reference(const TensorShape &lhs_shape, const TensorShape &rhs_shape, DataType data_type, float alpha, float beta, bool broadcast_bias,
- const ActivationLayerInfo &act_info, const experimental::PostOpList<TensorShape> &post_ops)
- {
- TensorShape dst_shape = lhs_shape;
- dst_shape[0] = rhs_shape[0];
- dst_shape[1] = lhs_shape[1];
-
- // Create reference
- SimpleTensor<T> lhs{ lhs_shape, data_type, 1 };
- SimpleTensor<T> rhs{ rhs_shape, data_type, 1 };
- SimpleTensor<T> bias{ dst_shape, data_type, 1 };
- // Create post op tensors and populate post op with them
- auto populated_post_ops = experimental::transform_post_op_list_arguments<TensorShape, SimpleTensor<T>>(post_ops, [&data_type](auto shape)
- {
- return SimpleTensor<T> { shape, data_type, 1 };
- });
-
- const int n = rhs_shape[0];
- const int m = lhs_shape[1];
- const int batch_size = lhs_shape[2];
-
- // Fill reference
- int tensor_idx = 0;
- fill(lhs, tensor_idx++);
- fill(rhs, tensor_idx++);
- fill(bias, tensor_idx++);
- for(auto &op : populated_post_ops.get_list())
- {
- for(auto tensor : op->arguments())
- {
- fill(*tensor, tensor_idx++);
- }
- }
-
- if(broadcast_bias)
- {
- // In case of broadcast, we need to simply copy the first into the following "M" ones
- for(int i = 1; i < m * batch_size; i++)
- {
- memcpy(bias.data() + i * n, bias.data(), n * sizeof(T));
- }
- }
-
- SimpleTensor<T> out;
- out = reference::gemm<T>(lhs, rhs, bias, alpha, beta);
- // Ignore activation info if post ops are used instead
- if(populated_post_ops.size() > 0)
- {
- out = reference::post_ops<T>(out, populated_post_ops);
- }
- else
- {
- out = reference::activation_layer(out, act_info);
- }
- return out;
- }
-
- bool validate_result = true;
- TensorType _target{};
- SimpleTensor<T> _reference{};
-};
-
template <typename TensorType, typename AccessorType, typename T, typename ReshapeRHSOperatorType, typename GEMMOperatorType>
class GEMMMatrixMultiplyReshapedOnlyRHS3DValidationFixture : public framework::Fixture
{
@@ -1921,8 +1419,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -2057,8 +1554,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -2102,212 +1598,6 @@ protected:
};
template <typename TensorType, typename AccessorType, typename T, typename GEMMOperatorType>
-class GEMMMatrixMultiplyNativeWithPostOpsValidationFixture : public framework::Fixture
-{
-public:
- using PostOpArgBroadcast = std::tuple<bool, bool, bool>; // Instruct fixture if we need broadcasting in dimension 0, 1, 2 of each PostOp argument
-public:
- void setup(unsigned int m, unsigned int n, unsigned int k, unsigned int batch_size, unsigned int m0, unsigned int n0, unsigned int k0, DataType data_type, float alpha, float beta, bool broadcast_bias,
- const ActivationLayerInfo &act_info, const experimental::PostOpList<PostOpArgBroadcast> &post_ops)
- {
- GEMMLHSMatrixInfo lhs_info;
- lhs_info.m0 = m0;
- lhs_info.k0 = k0;
-
- GEMMRHSMatrixInfo rhs_info;
- rhs_info.n0 = n0;
- rhs_info.k0 = k0;
-
- // Set the tensor shapes for LHS and RHS matrices
- const TensorShape lhs_shape(k, m, batch_size);
- const TensorShape rhs_shape(n, k, batch_size);
- const TensorShape bias_shape(n,
- broadcast_bias ? 1 : m,
- broadcast_bias ? 1 : batch_size);
- const auto post_ops_with_shapes = experimental::transform_post_op_list_arguments<PostOpArgBroadcast, TensorShape>(post_ops,
- [ = ](auto broadcast)
- {
- return TensorShape
- {
- std::get<0>(broadcast) ? 1 : n,
- std::get<1>(broadcast) ? 1 : m,
- std::get<2>(broadcast) ? 1 : batch_size,
- };
- });
-
- _target = compute_target(lhs_shape, rhs_shape, bias_shape, lhs_info, rhs_info, data_type, alpha, beta, broadcast_bias, act_info, post_ops_with_shapes);
- _reference = compute_reference(lhs_shape, rhs_shape, data_type, alpha, beta, broadcast_bias, act_info, post_ops_with_shapes);
- }
-
-protected:
- template <typename U>
- void fill(U &&tensor, int i)
- {
- static_assert(std::is_floating_point<T>::value || std::is_same<T, half>::value, "Only floating point data types supported.");
- using DistributionType = typename std::conditional<std::is_same<T, half>::value, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>::type;
-
- DistributionType distribution{ T(-1.0f), T(1.0f) };
- library->fill(tensor, distribution, i);
-
- // Fill border with infinity in order to check the presence of NaN values (i.e. inf * 0)
- DistributionType distribution_inf{ T(std::numeric_limits<float>::infinity()), T(std::numeric_limits<float>::infinity()) };
- library->fill_borders_with_garbage(tensor, distribution_inf, i);
- }
-
- TensorType compute_target(const TensorShape &lhs_shape, const TensorShape &rhs_shape, const TensorShape &bias_shape, const GEMMLHSMatrixInfo &lhs_info, const GEMMRHSMatrixInfo &rhs_info,
- DataType data_type, float alpha, float beta, bool broadcast_bias, const ActivationLayerInfo &act_info, const experimental::PostOpList<TensorShape> &post_ops)
- {
- // Create tensors
- TensorType lhs = create_tensor<TensorType>(lhs_shape, data_type, 1);
- TensorType rhs = create_tensor<TensorType>(rhs_shape, data_type, 1);
- TensorType bias = create_tensor<TensorType>(bias_shape, data_type, 1);
- TensorType dst;
- // Create post op tensors and populate post op with them
- std::vector<TensorType> post_op_tensors_holder{};
- auto populated_post_ops = experimental::transform_post_op_list_arguments<TensorShape, ITensorInfo *>(post_ops,
- [&post_op_tensors_holder, &data_type](auto shape)
- {
- auto t = create_tensor<TensorType>(shape, data_type, 1);
- post_op_tensors_holder.push_back(std::move(t));
- return post_op_tensors_holder.back().info();
- });
-
- const unsigned int M = lhs_shape[1];
- const unsigned int N = rhs_shape[0];
- const unsigned int K = lhs_shape[0];
- GEMMKernelInfo kernel_info;
- kernel_info.m = M;
- kernel_info.n = N;
- kernel_info.k = K;
- kernel_info.depth_output_gemm3d = 0;
- kernel_info.reinterpret_input_as_3d = false;
- kernel_info.broadcast_bias = broadcast_bias;
- kernel_info.activation_info = act_info;
- kernel_info.post_ops = populated_post_ops;
-
- // Create and configure function
- GEMMOperatorType gemm;
- gemm.configure(lhs.info(), rhs.info(), bias.info(), dst.info(), alpha, beta, lhs_info, rhs_info, kernel_info);
-
- ARM_COMPUTE_ASSERT(lhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(rhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(bias.info()->is_resizable());
- for(const auto &tensor : post_op_tensors_holder)
- {
- ARM_COMPUTE_ASSERT(tensor.info()->is_resizable());
- }
-
- add_padding_x({ &lhs, &rhs, &bias, &dst });
- for(auto &tensor : post_op_tensors_holder)
- {
- add_padding_x({ &tensor });
- }
-
- // Allocate tensors
- lhs.allocator()->allocate();
- rhs.allocator()->allocate();
- bias.allocator()->allocate();
- dst.allocator()->allocate();
- for(auto &tensor : post_op_tensors_holder)
- {
- tensor.allocator()->allocate();
- }
-
- ARM_COMPUTE_ASSERT(!lhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!rhs.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!bias.info()->is_resizable());
- ARM_COMPUTE_ASSERT(!dst.info()->is_resizable());
- for(const auto &tensor : post_op_tensors_holder)
- {
- ARM_COMPUTE_ASSERT(!tensor.info()->is_resizable());
- }
-
- // Fill tensors
- fill(AccessorType(lhs), 0);
- fill(AccessorType(rhs), 1);
- fill(AccessorType(bias), 2);
- for(size_t i = 0; i < post_op_tensors_holder.size(); ++i)
- {
- fill(AccessorType(post_op_tensors_holder.at(i)), 3 + i);
- }
-
- // Compute GEMM
- ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
- { ACL_SRC_1, &rhs },
- { ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
- for(size_t i = 0; i < post_op_tensors_holder.size(); ++i)
- {
- gemm_pack.add_tensor(experimental::get_post_op_arg_type(i), &post_op_tensors_holder.at(i));
- }
- gemm.run(gemm_pack);
-
- return dst;
- }
-
- SimpleTensor<T> compute_reference(const TensorShape &lhs_shape, const TensorShape &rhs_shape, DataType data_type, float alpha, float beta, bool broadcast_bias,
- const ActivationLayerInfo &act_info, const experimental::PostOpList<TensorShape> &post_ops)
- {
- TensorShape dst_shape = lhs_shape;
- dst_shape[0] = rhs_shape[0];
- dst_shape[1] = lhs_shape[1];
-
- // Create reference
- SimpleTensor<T> lhs{ lhs_shape, data_type, 1 };
- SimpleTensor<T> rhs{ rhs_shape, data_type, 1 };
- SimpleTensor<T> bias{ dst_shape, data_type, 1 };
- // Create post op tensors and populate post op with them
- auto populated_post_ops = experimental::transform_post_op_list_arguments<TensorShape, SimpleTensor<T>>(post_ops, [&data_type](auto shape)
- {
- return SimpleTensor<T> { shape, data_type, 1 };
- });
-
- const int n = rhs_shape[0];
- const int m = lhs_shape[1];
- const int batch_size = lhs_shape[2];
-
- // Fill reference
- int tensor_idx = 0;
- fill(lhs, tensor_idx++);
- fill(rhs, tensor_idx++);
- fill(bias, tensor_idx++);
- for(auto &op : populated_post_ops.get_list())
- {
- for(auto tensor : op->arguments())
- {
- fill(*tensor, tensor_idx++);
- }
- }
-
- if(broadcast_bias)
- {
- // In case of broadcast, we need to simply copy the first into the following "M" ones
- for(int i = 1; i < m * batch_size; i++)
- {
- memcpy(bias.data() + i * n, bias.data(), n * sizeof(T));
- }
- }
-
- SimpleTensor<T> out;
- out = reference::gemm<T>(lhs, rhs, bias, alpha, beta);
- // Ignore activation info if post ops are used instead
- if(populated_post_ops.size() > 0)
- {
- out = reference::post_ops<T>(out, populated_post_ops);
- }
- else
- {
- out = reference::activation_layer(out, act_info);
- }
- return out;
- }
-
- TensorType _target{};
- SimpleTensor<T> _reference{};
-};
-
-template <typename TensorType, typename AccessorType, typename T, typename GEMMOperatorType>
class GEMMMatrixMultiplyNative3DValidationFixture : public framework::Fixture
{
public:
@@ -2398,8 +1688,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -2557,8 +1846,7 @@ protected:
ITensorPack gemm_pack({ { ACL_SRC_0, &lhs },
{ ACL_SRC_1, &rhs_reshaped },
{ ACL_SRC_2, &bias },
- { ACL_DST, &dst }
- });
+ { ACL_DST, &dst } });
gemm.run(gemm_pack);
return dst;
@@ -2608,4 +1896,4 @@ protected:
} // namespace validation
} // namespace test
} // namespace arm_compute
-#endif /* ARM_COMPUTE_TEST_GEMM_FIXTURE */
+#endif // ACL_TESTS_VALIDATION_FIXTURES_GEMMFIXTURE_H