From 7d66a8e3f603f2cd363f04a750847e3f9eabdfd4 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Tue, 17 Jul 2018 12:28:42 +0100 Subject: COMPMID-1386: Add support for converting weights for CL. Change-Id: I62e3ead903366baeeb1488f233a9b8b0c388c9de Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/140403 Tested-by: Jenkins Reviewed-by: Giorgio Arena Reviewed-by: Anthony Barbier --- tests/networks/AlexNetNetwork.h | 9 ++++++--- tests/validation/CL/FullyConnectedLayer.cpp | 15 ++++++++++++--- tests/validation/GLES_COMPUTE/FullyConnectedLayer.cpp | 7 ++++++- tests/validation/NEON/FullyConnectedLayer.cpp | 14 ++++++++++++-- tests/validation/fixtures/FullyConnectedLayerFixture.h | 7 ++++++- tests/validation/fixtures/UNIT/MemoryManagerFixture.h | 14 +++++++++++--- .../validation/reference/ConvertFullyConnectedWeights.cpp | 10 ++++++++-- 7 files changed, 61 insertions(+), 15 deletions(-) (limited to 'tests') diff --git a/tests/networks/AlexNetNetwork.h b/tests/networks/AlexNetNetwork.h index e92affe954..e15db2a110 100644 --- a/tests/networks/AlexNetNetwork.h +++ b/tests/networks/AlexNetNetwork.h @@ -193,6 +193,9 @@ public: /** Build the network */ void build() { + FullyConnectedLayerInfo fc_info; + fc_info.are_weights_reshaped = _reshaped_weights; + input.allocator()->init(TensorInfo(TensorShape(227U, 227U, 3U, _batches), 1, _data_type)); output.allocator()->init(TensorInfo(TensorShape(1000U, _batches), 1, _data_type)); @@ -265,13 +268,13 @@ public: act5.configure(&conv5_out, &act5_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)); pool5.configure(&act5_out, &pool5_out, PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0))); // Layer 6 - fc6.configure(&pool5_out, &w[5], &b[5], &fc6_out, true, _reshaped_weights); + fc6.configure(&pool5_out, &w[5], &b[5], &fc6_out, fc_info); act6.configure(&fc6_out, &act6_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)); // Layer 7 - fc7.configure(&act6_out, &w[6], &b[6], &fc7_out, true, _reshaped_weights); + fc7.configure(&act6_out, &w[6], &b[6], &fc7_out, fc_info); act7.configure(&fc7_out, &act7_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)); // Layer 8 - fc8.configure(&act7_out, &w[7], &b[7], &fc8_out, true, _reshaped_weights); + fc8.configure(&act7_out, &w[7], &b[7], &fc8_out, fc_info); // Softmax smx.configure(&fc8_out, &output); } diff --git a/tests/validation/CL/FullyConnectedLayer.cpp b/tests/validation/CL/FullyConnectedLayer.cpp index 9958a88419..cd050e378e 100644 --- a/tests/validation/CL/FullyConnectedLayer.cpp +++ b/tests/validation/CL/FullyConnectedLayer.cpp @@ -96,9 +96,14 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(frame const QuantizationInfo src_quantization_info = src.info()->quantization_info(); const QuantizationInfo weights_quantization_info = weights.info()->quantization_info(); + // Create Fully Connected layer info + FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = transpose_weights; + fc_info.are_weights_reshaped = !reshape_weights; + // Create and configure function. CLFullyConnectedLayer fc; - fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights); + fc.configure(&src, &weights, &bias, &dst, fc_info); // Validate valid region const ValidRegion dst_valid_region = shape_to_valid_region(dst_shape); @@ -141,12 +146,16 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip( framework::dataset::make("Expected", { false, true, true, false, false })), input_info, weights_info, bias_info, output_info, transpose_weights, reshaped_weights, expected) { + // Create Fully Connected layer info + FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = transpose_weights; + fc_info.are_weights_reshaped = reshaped_weights; + Status status = CLFullyConnectedLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &bias_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), - transpose_weights, - reshaped_weights); + fc_info); ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS); } // clang-format on diff --git a/tests/validation/GLES_COMPUTE/FullyConnectedLayer.cpp b/tests/validation/GLES_COMPUTE/FullyConnectedLayer.cpp index 49716dc946..c82a8a1a43 100644 --- a/tests/validation/GLES_COMPUTE/FullyConnectedLayer.cpp +++ b/tests/validation/GLES_COMPUTE/FullyConnectedLayer.cpp @@ -87,9 +87,14 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(frame ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); + // Create Fully Connected layer info + FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = transpose_weights; + fc_info.are_weights_reshaped = !reshape_weights; + // Create and configure function. GCFullyConnectedLayer fc; - fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights); + fc.configure(&src, &weights, &bias, &dst, fc_info); // Validate valid region const ValidRegion dst_valid_region = shape_to_valid_region(dst_shape); diff --git a/tests/validation/NEON/FullyConnectedLayer.cpp b/tests/validation/NEON/FullyConnectedLayer.cpp index 174778b8ef..80fdf1784e 100644 --- a/tests/validation/NEON/FullyConnectedLayer.cpp +++ b/tests/validation/NEON/FullyConnectedLayer.cpp @@ -99,9 +99,14 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(frame ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); + // Create Fully Connected layer info + FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = transpose_weights; + fc_info.are_weights_reshaped = !reshape_weights; + // Create and configure function. NEFullyConnectedLayer fc; - fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights); + fc.configure(&src, &weights, &bias, &dst, fc_info); // Validate valid region const ValidRegion dst_valid_region = shape_to_valid_region(dst_shape); @@ -144,7 +149,12 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip( framework::dataset::make("Expected", { false, true, true, false, false, true })), input_info, weights_info, bias_info, output_info, transpose_weights, reshaped_weights, expected) { - Status status = NEFullyConnectedLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &bias_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), transpose_weights, reshaped_weights); + // Create Fully Connected layer info + FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = transpose_weights; + fc_info.are_weights_reshaped = reshaped_weights; + + Status status = NEFullyConnectedLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &bias_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), fc_info); ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS); } // clang-format on diff --git a/tests/validation/fixtures/FullyConnectedLayerFixture.h b/tests/validation/fixtures/FullyConnectedLayerFixture.h index 895e43b735..18321480f8 100644 --- a/tests/validation/fixtures/FullyConnectedLayerFixture.h +++ b/tests/validation/fixtures/FullyConnectedLayerFixture.h @@ -130,9 +130,14 @@ protected: TensorType bias = create_tensor(bias_shape, _bias_data_type, 1, _quantization_info); TensorType dst = create_tensor(output_shape, _data_type, 1, _quantization_info); + // Create Fully Connected layer info + FullyConnectedLayerInfo fc_info; + fc_info.transpose_weights = transpose_weights; + fc_info.are_weights_reshaped = !reshape_weights; + // Create and configure function. FunctionType fc; - fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights); + fc.configure(&src, &weights, &bias, &dst, fc_info); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS); diff --git a/tests/validation/fixtures/UNIT/MemoryManagerFixture.h b/tests/validation/fixtures/UNIT/MemoryManagerFixture.h index 21ad42bf77..d8e2b0b427 100644 --- a/tests/validation/fixtures/UNIT/MemoryManagerFixture.h +++ b/tests/validation/fixtures/UNIT/MemoryManagerFixture.h @@ -239,9 +239,13 @@ protected: dst.allocator()->info().set_tensor_shape(TensorShape(24U, _cur_batches)).set_is_resizable(true).extend_padding(new_dst_padding); dst.allocator()->info().set_is_resizable(false); + // Configure FC info + FullyConnectedLayerInfo fc_info; + fc_info.retain_internal_weights = true; + // Configure functions (2nd iteration) - fc_layer_1.configure(&src, &w1, &b1, &fc1, true, false, true); - fc_layer_2.configure(&fc1, &w2, &b2, &dst, true, false, true); + fc_layer_1.configure(&src, &w1, &b1, &fc1, fc_info); + fc_layer_2.configure(&fc1, &w2, &b2, &dst, fc_info); // Fill tensors (2nd iteration) fill(AccessorType(src), 5); @@ -357,6 +361,10 @@ protected: // Get padding requirements auto fc_padding = fc.allocator()->info().padding(); + // Configure FC info + FullyConnectedLayerInfo fc_info; + fc_info.retain_internal_weights = true; + // Run rest iterations for(int i = _max_batches; i >= static_cast(_cur_batches); --i) { @@ -368,7 +376,7 @@ protected: dst.allocator()->info().set_tensor_shape(TensorShape(8U, i)); // Configure functions - fc_layer.configure(&src, &w, &b, &fc, true, false, true); + fc_layer.configure(&src, &w, &b, &fc, fc_info); smx_layer.configure(&fc, &dst); // Fill tensors diff --git a/tests/validation/reference/ConvertFullyConnectedWeights.cpp b/tests/validation/reference/ConvertFullyConnectedWeights.cpp index b0f537fa0c..e27846c726 100644 --- a/tests/validation/reference/ConvertFullyConnectedWeights.cpp +++ b/tests/validation/reference/ConvertFullyConnectedWeights.cpp @@ -36,9 +36,15 @@ SimpleTensor convert_fully_connected_weights(const SimpleTensor &src, cons { SimpleTensor dst(src.shape(), src.data_type()); + const DataLayout original_input_data_layout = (training_data_layout == DataLayout::NCHW) ? DataLayout::NHWC : DataLayout::NCHW; + + const int width_idx = get_data_layout_dimension_index(original_input_data_layout, DataLayoutDimension::WIDTH); + const int height_idx = get_data_layout_dimension_index(original_input_data_layout, DataLayoutDimension::HEIGHT); + const int channel_idx = get_data_layout_dimension_index(original_input_data_layout, DataLayoutDimension::CHANNEL); + const bool is_nchw_to_nhwc = training_data_layout == DataLayout::NCHW; - const unsigned int num_elems_per_input_plane = original_input_shape.x() * original_input_shape.y(); - const unsigned int num_channels = original_input_shape.z(); + const unsigned int num_elems_per_input_plane = original_input_shape[width_idx] * original_input_shape[height_idx]; + const unsigned int num_channels = original_input_shape[channel_idx]; const unsigned int factor_1 = is_nchw_to_nhwc ? num_elems_per_input_plane : num_channels; const unsigned int factor_2 = is_nchw_to_nhwc ? num_channels : num_elems_per_input_plane; -- cgit v1.2.1