IVGCVSW-1938: Move backend-specific source files to the corresponding backend
[platform/upstream/armnn.git] / src / backends / cl / test / OpenClTimerTest.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #if (defined(__aarch64__)) || (defined(__x86_64__)) // disable test failing on FireFly/Armv7
7
8 #include <armnn/test/TensorHelpers.hpp>
9
10 #include <backends/CpuTensorHandle.hpp>
11 #include <backends/WorkloadFactory.hpp>
12
13 #include <backends/cl/ClContextControl.hpp>
14 #include <backends/cl/ClWorkloadFactory.hpp>
15 #include <backends/cl/OpenClTimer.hpp>
16
17 #include <backends/test/TensorCopyUtils.hpp>
18 #include <backends/test/WorkloadTestUtils.hpp>
19
20 #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
27 using namespace armnn;
28
29 struct 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
40 BOOST_FIXTURE_TEST_SUITE(OpenClTimerBatchNorm, OpenClFixture)
41 using FactoryType = ClWorkloadFactory;
42
43 BOOST_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
141 BOOST_AUTO_TEST_SUITE_END()
142
143 #endif //aarch64 or x86_64