blob: ee5163f6688dce211845577c668c980e453285fd [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
David Beckac42efd2018-09-26 17:41:13 +01006#include <armnn/Descriptors.hpp>
7#include <armnn/IRuntime.hpp>
8#include <armnn/INetwork.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00009#include <Half.hpp>
arovir01616e7752018-10-01 17:08:59 +010010
David Beckac42efd2018-09-26 17:41:13 +010011#include <Graph.hpp>
12#include <Optimizer.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000013#include <backendsCommon/CpuTensorHandle.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010014
15#include <boost/core/ignore_unused.hpp>
16#include <boost/test/unit_test.hpp>
17
telsoa01c577f2c2018-08-31 09:22:23 +010018#include <set>
19
20using namespace armnn;
21
22BOOST_AUTO_TEST_SUITE(Fp16Support)
23
24BOOST_AUTO_TEST_CASE(Fp16DataTypeSupport)
25{
26 Graph graph;
27
28 Layer* const inputLayer1 = graph.AddLayer<InputLayer>(1, "input1");
29 Layer* const inputLayer2 = graph.AddLayer<InputLayer>(2, "input2");
30
31 Layer* const additionLayer = graph.AddLayer<AdditionLayer>("addition");
32 Layer* const outputLayer = graph.AddLayer<armnn::OutputLayer>(0, "output");
33
34 TensorInfo fp16TensorInfo({1, 2, 3, 5}, armnn::DataType::Float16);
35 inputLayer1->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(0));
36 inputLayer2->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(1));
37 additionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
38
39 inputLayer1->GetOutputSlot().SetTensorInfo(fp16TensorInfo);
40 inputLayer2->GetOutputSlot().SetTensorInfo(fp16TensorInfo);
41 additionLayer->GetOutputSlot().SetTensorInfo(fp16TensorInfo);
42
43 BOOST_CHECK(inputLayer1->GetOutputSlot(0).GetTensorInfo().GetDataType() == armnn::DataType::Float16);
44 BOOST_CHECK(inputLayer2->GetOutputSlot(0).GetTensorInfo().GetDataType() == armnn::DataType::Float16);
45 BOOST_CHECK(additionLayer->GetOutputSlot(0).GetTensorInfo().GetDataType() == armnn::DataType::Float16);
telsoa01c577f2c2018-08-31 09:22:23 +010046}
47
48BOOST_AUTO_TEST_CASE(Fp16AdditionTest)
49{
50 using namespace half_float::literal;
51 // Create runtime in which test will run
52 IRuntime::CreationOptions options;
Aron Virginas-Tar3b278e92018-10-12 13:00:55 +010053 IRuntimePtr runtime(IRuntime::Create(options));
telsoa01c577f2c2018-08-31 09:22:23 +010054
55 // Builds up the structure of the network.
56 INetworkPtr net(INetwork::Create());
57
telsoa01c577f2c2018-08-31 09:22:23 +010058 IConnectableLayer* inputLayer1 = net->AddInputLayer(0);
59 IConnectableLayer* inputLayer2 = net->AddInputLayer(1);
60 IConnectableLayer* additionLayer = net->AddAdditionLayer();
61 IConnectableLayer* outputLayer = net->AddOutputLayer(0);
62
63 inputLayer1->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(0));
64 inputLayer2->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(1));
65 additionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
66
67 //change to float16
68 TensorInfo fp16TensorInfo(TensorShape({4}), DataType::Float16);
69 inputLayer1->GetOutputSlot(0).SetTensorInfo(fp16TensorInfo);
70 inputLayer2->GetOutputSlot(0).SetTensorInfo(fp16TensorInfo);
71 additionLayer->GetOutputSlot(0).SetTensorInfo(fp16TensorInfo);
72
73 // optimize the network
David Beckf0b48452018-10-19 15:20:56 +010074 std::vector<BackendId> backends = {Compute::GpuAcc};
telsoa01c577f2c2018-08-31 09:22:23 +010075 IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
76
77 // Loads it into the runtime.
telsoa01c577f2c2018-08-31 09:22:23 +010078 NetworkId netId;
79 runtime->LoadNetwork(netId, std::move(optNet));
80
81 std::vector<Half> input1Data
82 {
83 1.0_h, 2.0_h, 3.0_h, 4.0_h
84 };
85
86 std::vector<Half> input2Data
87 {
88 100.0_h, 200.0_h, 300.0_h, 400.0_h
89 };
90
91 InputTensors inputTensors
92 {
93 {0,ConstTensor(runtime->GetInputTensorInfo(netId, 0), input1Data.data())},
94 {1,ConstTensor(runtime->GetInputTensorInfo(netId, 0), input2Data.data())}
95 };
96
97 std::vector<Half> outputData(input1Data.size());
98 OutputTensors outputTensors
99 {
100 {0,Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
101 };
102
103 // Does the inference.
104 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
105
106 // Checks the results.
107 BOOST_TEST(outputData == std::vector<Half>({ 101.0_h, 202.0_h, 303.0_h, 404.0_h})); // Add
108}
109
arovir01616e7752018-10-01 17:08:59 +0100110BOOST_AUTO_TEST_SUITE_END()