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