blob: 1974d4d856da6957f7fa479ccdc9b20b16fef99b [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>
James Conroy1f58f032021-04-27 17:13:27 +010013#include <backendsCommon/TensorHandle.hpp>
Jan Eilers8eb25602020-03-09 12:13:48 +000014#include <armnn/utility/IgnoreUnused.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010015
Sadik Armagan1625efc2021-06-10 18:24:34 +010016#include <doctest/doctest.h>
telsoa01c577f2c2018-08-31 09:22:23 +010017
telsoa01c577f2c2018-08-31 09:22:23 +010018#include <set>
19
20using namespace armnn;
21
Sadik Armagan1625efc2021-06-10 18:24:34 +010022TEST_SUITE("Fp16Support")
23{
24TEST_CASE("Fp16DataTypeSupport")
telsoa01c577f2c2018-08-31 09:22:23 +010025{
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
Sadik Armagan1625efc2021-06-10 18:24:34 +010043 CHECK(inputLayer1->GetOutputSlot(0).GetTensorInfo().GetDataType() == armnn::DataType::Float16);
44 CHECK(inputLayer2->GetOutputSlot(0).GetTensorInfo().GetDataType() == armnn::DataType::Float16);
45 CHECK(additionLayer->GetOutputSlot(0).GetTensorInfo().GetDataType() == armnn::DataType::Float16);
telsoa01c577f2c2018-08-31 09:22:23 +010046}
47
Sadik Armagan1625efc2021-06-10 18:24:34 +010048TEST_CASE("Fp16AdditionTest")
telsoa01c577f2c2018-08-31 09:22:23 +010049{
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.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100107 CHECK(outputData == std::vector<Half>({ 101.0_h, 202.0_h, 303.0_h, 404.0_h})); // Add
telsoa01c577f2c2018-08-31 09:22:23 +0100108}
109
Sadik Armagan1625efc2021-06-10 18:24:34 +0100110}