From 72ee9b4723485c3da077d765febf45f27acb78cb Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Mon, 10 May 2021 22:26:37 +0100 Subject: Add unit-test for non-const weights on Fully Connected layers Resolves: COMPMID-4221 Signed-off-by: Georgios Pinitas Change-Id: I5c860dc1863535f0558063dfbb6ef703981cce69 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5638 Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins Reviewed-by: Giorgio Arena --- .../fixtures/FullyConnectedLayerFixture.h | 133 +++++++++++++++++++++ 1 file changed, 133 insertions(+) (limited to 'tests/validation/fixtures/FullyConnectedLayerFixture.h') diff --git a/tests/validation/fixtures/FullyConnectedLayerFixture.h b/tests/validation/fixtures/FullyConnectedLayerFixture.h index 9f6a0a2754..e5fea60923 100644 --- a/tests/validation/fixtures/FullyConnectedLayerFixture.h +++ b/tests/validation/fixtures/FullyConnectedLayerFixture.h @@ -271,6 +271,139 @@ public: quantization_info, activation_info, mixed_layout); } }; + +template +class FullyConnectedWithDynamicWeightsFixture : public framework::Fixture +{ +private: + template + void fill(U &&tensor, int i) + { + if(_data_type == DataType::F16) + { + arm_compute::utils::uniform_real_distribution_16bit distribution(-1.0f, 1.0f); + library->fill(tensor, distribution, i); + } + else if(_data_type == DataType::F32) + { + std::uniform_real_distribution distribution(-1.0f, 1.0f); + library->fill(tensor, distribution, i); + } + else + { + library->fill_tensor_uniform(tensor, i); + } + } + + void fill_transposed_weights(TensorType &weights, TensorShape weights_shape, int seed) + { + RawTensor tmp(weights_shape, _data_type, 1); + + // Fill with original shape + fill(tmp, seed); + + // Transpose elementwise + tmp = transpose(tmp); + + AccessorType weights_accessor(weights); + + for(int i = 0; i < tmp.num_elements(); ++i) + { + Coordinates coord = index2coord(tmp.shape(), i); + std::copy_n(static_cast(tmp(coord)), + tmp.element_size(), + static_cast(weights_accessor(coord))); + } + } + + void validate_with_tolerance(TensorType &target, SimpleTensor &ref) + { + if(_data_type == DataType::F32) + { + constexpr RelativeTolerance rel_tolerance_f32(0.05f); + constexpr AbsoluteTolerance abs_tolerance_f32(0.0001f); + validate(AccessorType(target), ref, rel_tolerance_f32, 0, abs_tolerance_f32); + } + else + { + validate(AccessorType(target), ref); + } + } + +public: + template + void setup(TensorShape src_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape dst_shape, + DataType data_type, ActivationLayerInfo activation_info) + { + _data_type = data_type; + + // Setup tensor meta-data + TensorInfo src_info(src_shape, 1, data_type); + _src.allocator()->init(src_info); + + TensorShape tr_weights_shape{ weights_shape[1], weights_shape[0] }; + TensorInfo wei_info(tr_weights_shape, 1, data_type); + _weights.allocator()->init(wei_info); + + TensorInfo bias_info(bias_shape, 1, data_type); + _bias.allocator()->init(bias_info); + + TensorInfo dst_info(dst_shape, 1, data_type); + _dst.allocator()->init(dst_info); + + // Configure FC layer and mark the weights as non constant + FullyConnectedLayerInfo fc_info; + fc_info.activation_info = activation_info; + fc_info.are_weights_reshaped = true; + fc_info.constant_weights = false; + FunctionType fc; + fc.configure(&_src, &_weights, &_bias, &_dst, fc_info); + + // Allocate all the tensors + _src.allocator()->allocate(); + _weights.allocator()->allocate(); + _bias.allocator()->allocate(); + _dst.allocator()->allocate(); + + // Run multiple iterations with different inputs + constexpr int num_iterations = 5; + int randomizer_offset = 0; + for(int i = 0; i < num_iterations; ++i) + { + // Run target + { + fill(AccessorType(_src), randomizer_offset); + fill_transposed_weights(_weights, weights_shape, randomizer_offset + 1); + fill(AccessorType(_bias), randomizer_offset + 2); + + fc.run(); + } + + // Run reference and compare + { + SimpleTensor src{ src_shape, data_type }; + SimpleTensor weights{ weights_shape, data_type }; + SimpleTensor bias{ bias_shape, data_type }; + + // Fill reference + fill(src, randomizer_offset); + fill(weights, randomizer_offset + 1); + fill(bias, randomizer_offset + 2); + + auto dst = reference::activation_layer(reference::fully_connected_layer(src, weights, bias, dst_shape), activation_info); + + // Validate + validate_with_tolerance(_dst, dst); + } + + randomizer_offset += 100; + } + } + +private: + TensorType _src{}, _weights{}, _bias{}, _dst{}; + DataType _data_type{ DataType::UNKNOWN }; +}; } // namespace validation } // namespace test } // namespace arm_compute -- cgit v1.2.1