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