blob: 70ceac2a3f9735c02b31788078746693cea16dbb [file] [log] [blame]
telsoa01c577f2c2018-08-31 09:22:23 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa01c577f2c2018-08-31 09:22:23 +01004//
5
6#if (defined(__aarch64__)) || (defined(__x86_64__)) // disable test failing on FireFly/Armv7
7
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +01008#include <armnn/test/TensorHelpers.hpp>
9
10#include <backends/CpuTensorHandle.hpp>
11#include <backends/WorkloadFactory.hpp>
12
David Beckac42efd2018-09-26 17:41:13 +010013#include <backends/cl/ClContextControl.hpp>
14#include <backends/cl/ClWorkloadFactory.hpp>
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010015#include <backends/cl/OpenClTimer.hpp>
16
David Beckac42efd2018-09-26 17:41:13 +010017#include <backends/test/TensorCopyUtils.hpp>
David Beckac42efd2018-09-26 17:41:13 +010018#include <backends/test/WorkloadTestUtils.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010019
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010020#include <arm_compute/runtime/CL/CLScheduler.h>
21
22#include <boost/format.hpp>
23#include <boost/test/unit_test.hpp>
24
25#include <iostream>
26
telsoa01c577f2c2018-08-31 09:22:23 +010027using namespace armnn;
28
29struct OpenClFixture
30{
31 // Initialising ClContextControl to ensure OpenCL is loaded correctly for each test case.
32 // NOTE: Profiling needs to be enabled in ClContextControl to be able to obtain execution
33 // times from OpenClTimer.
34 OpenClFixture() : m_ClContextControl(nullptr, true) {}
35 ~OpenClFixture() {}
36
37 ClContextControl m_ClContextControl;
38};
39
40BOOST_FIXTURE_TEST_SUITE(OpenClTimerBatchNorm, OpenClFixture)
41using FactoryType = ClWorkloadFactory;
42
43BOOST_AUTO_TEST_CASE(OpenClTimerBatchNorm)
44{
45 ClWorkloadFactory workloadFactory;
46
47 const unsigned int width = 2;
48 const unsigned int height = 3;
49 const unsigned int channels = 2;
50 const unsigned int num = 1;
51 int32_t qOffset = 0;
52 float qScale = 0.f;
53
54 TensorInfo inputTensorInfo({num, channels, height, width}, GetDataType<float>());
55 TensorInfo outputTensorInfo({num, channels, height, width}, GetDataType<float>());
56 TensorInfo tensorInfo({channels}, GetDataType<float>());
57
58 // Set quantization parameters if the requested type is a quantized type.
59 if(IsQuantizedType<float>())
60 {
61 inputTensorInfo.SetQuantizationScale(qScale);
62 inputTensorInfo.SetQuantizationOffset(qOffset);
63 outputTensorInfo.SetQuantizationScale(qScale);
64 outputTensorInfo.SetQuantizationOffset(qOffset);
65 tensorInfo.SetQuantizationScale(qScale);
66 tensorInfo.SetQuantizationOffset(qOffset);
67 }
68
69 auto input = MakeTensor<float, 4>(inputTensorInfo,
70 QuantizedVector<float>(qScale, qOffset,
71 {
72 1.f, 4.f,
73 4.f, 2.f,
74 1.f, 6.f,
75
76 1.f, 1.f,
77 4.f, 1.f,
78 -2.f, 4.f
79 }));
80 // these values are per-channel of the input
81 auto mean = MakeTensor<float, 1>(tensorInfo, QuantizedVector<float>(qScale, qOffset, {3, -2}));
82 auto variance = MakeTensor<float, 1>(tensorInfo, QuantizedVector<float>(qScale, qOffset, {4, 9}));
83 auto beta = MakeTensor<float, 1>(tensorInfo, QuantizedVector<float>(qScale, qOffset, {3, 2}));
84 auto gamma = MakeTensor<float, 1>(tensorInfo, QuantizedVector<float>(qScale, qOffset, {2, 1}));
85
86 std::unique_ptr<ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
87 std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
88
89 BatchNormalizationQueueDescriptor data;
90 WorkloadInfo info;
91 ScopedCpuTensorHandle meanTensor(tensorInfo);
92 ScopedCpuTensorHandle varianceTensor(tensorInfo);
93 ScopedCpuTensorHandle betaTensor(tensorInfo);
94 ScopedCpuTensorHandle gammaTensor(tensorInfo);
95
96 AllocateAndCopyDataToITensorHandle(&meanTensor, &mean[0]);
97 AllocateAndCopyDataToITensorHandle(&varianceTensor, &variance[0]);
98 AllocateAndCopyDataToITensorHandle(&betaTensor, &beta[0]);
99 AllocateAndCopyDataToITensorHandle(&gammaTensor, &gamma[0]);
100
101 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
102 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
103 data.m_Mean = &meanTensor;
104 data.m_Variance = &varianceTensor;
105 data.m_Beta = &betaTensor;
106 data.m_Gamma = &gammaTensor;
107 data.m_Parameters.m_Eps = 0.0f;
108
109 // for each channel:
110 // substract mean, divide by standard deviation (with an epsilon to avoid div by 0)
111 // multiply by gamma and add beta
112 std::unique_ptr<IWorkload> workload = workloadFactory.CreateBatchNormalization(data, info);
113
114 inputHandle->Allocate();
115 outputHandle->Allocate();
116
117 CopyDataToITensorHandle(inputHandle.get(), &input[0][0][0][0]);
118
119 OpenClTimer openClTimer;
120
121 BOOST_CHECK_EQUAL(openClTimer.GetName(), "OpenClKernelTimer");
122
123 //Start the timer
124 openClTimer.Start();
125
126 //Execute the workload
127 workload->Execute();
128
129 //Stop the timer
130 openClTimer.Stop();
131
132 BOOST_CHECK_EQUAL(openClTimer.GetMeasurements().size(), 1);
133
134 BOOST_CHECK_EQUAL(openClTimer.GetMeasurements().front().m_Name,
135 "OpenClKernelTimer/0: batchnormalization_layer_nchw GWS[1,3,2]");
136
137 BOOST_CHECK(openClTimer.GetMeasurements().front().m_Value > 0);
138
139}
140
141BOOST_AUTO_TEST_SUITE_END()
142
143#endif //aarch64 or x86_64