blob: cf9c6f21e5ea6aa8d0c091fd76c017769aa96505 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
5#pragma once
6
7#include "WorkloadData.hpp"
8#include "WorkloadInfo.hpp"
9#include <algorithm>
10#include "Profiling.hpp"
11
12namespace armnn
13{
14
telsoa01c577f2c2018-08-31 09:22:23 +010015// Workload interface to enqueue a layer computation.
telsoa014fcda012018-03-09 14:13:49 +000016class IWorkload
17{
18public:
telsoa01c577f2c2018-08-31 09:22:23 +010019 virtual ~IWorkload() {}
telsoa014fcda012018-03-09 14:13:49 +000020
21 virtual void Execute() const = 0;
22};
23
24// NullWorkload used to denote an unsupported workload when used by the MakeWorkload<> template
25// in the various workload factories.
26// There should never be an instantiation of a NullWorkload.
27class NullWorkload : public IWorkload
28{
29 NullWorkload()=delete;
30};
31
32template <typename QueueDescriptor>
33class BaseWorkload : public IWorkload
34{
35public:
36
37 BaseWorkload(const QueueDescriptor& descriptor, const WorkloadInfo& info)
38 : m_Data(descriptor)
39 {
40 m_Data.Validate(info);
41 }
42
43 const QueueDescriptor& GetData() const { return m_Data; }
44
45protected:
46 const QueueDescriptor m_Data;
47};
48
telsoa01c577f2c2018-08-31 09:22:23 +010049// TypedWorkload used
50template <typename QueueDescriptor, armnn::DataType... DataTypes>
telsoa014fcda012018-03-09 14:13:49 +000051class TypedWorkload : public BaseWorkload<QueueDescriptor>
52{
53public:
54
55 TypedWorkload(const QueueDescriptor& descriptor, const WorkloadInfo& info)
56 : BaseWorkload<QueueDescriptor>(descriptor, info)
57 {
telsoa01c577f2c2018-08-31 09:22:23 +010058 std::vector<armnn::DataType> dataTypes = {DataTypes...};
59 armnn::DataType expectedInputType;
60
61 if (!info.m_InputTensorInfos.empty())
62 {
63 expectedInputType = info.m_InputTensorInfos.front().GetDataType();
64
65 if (std::find(dataTypes.begin(), dataTypes.end(), expectedInputType) == dataTypes.end())
66 {
67 BOOST_ASSERT_MSG(false, "Trying to create workload with incorrect type");
68 }
69 BOOST_ASSERT_MSG(std::all_of(std::next(info.m_InputTensorInfos.begin()),
70 info.m_InputTensorInfos.end(),
71 [&](auto it){
72 return it.GetDataType() == expectedInputType;
73 }),
74 "Trying to create workload with incorrect type");
75 }
76 armnn::DataType expectedOutputType;
77
78 if (!info.m_OutputTensorInfos.empty())
79 {
80 expectedOutputType = info.m_OutputTensorInfos.front().GetDataType();
81
82 if (!info.m_InputTensorInfos.empty())
83 {
84 if (expectedOutputType != expectedInputType)
85 {
86 BOOST_ASSERT_MSG(false, "Trying to create workload with incorrect type");
87 }
88 }
89 else if (std::find(dataTypes.begin(), dataTypes.end(), expectedOutputType) == dataTypes.end())
90 {
91 BOOST_ASSERT_MSG(false, "Trying to create workload with incorrect type");
92 }
93 BOOST_ASSERT_MSG(std::all_of(std::next(info.m_OutputTensorInfos.begin()),
94 info.m_OutputTensorInfos.end(),
95 [&](auto it){
96 return it.GetDataType() == expectedOutputType;
97 }),
98 "Trying to create workload with incorrect type");
99 }
100 }
101};
102
103template <typename QueueDescriptor, armnn::DataType InputDataType, armnn::DataType OutputDataType>
104class MultiTypedWorkload : public BaseWorkload<QueueDescriptor>
105{
106public:
107
108 MultiTypedWorkload(const QueueDescriptor& descriptor, const WorkloadInfo& info)
109 : BaseWorkload<QueueDescriptor>(descriptor, info)
110 {
telsoa014fcda012018-03-09 14:13:49 +0000111 BOOST_ASSERT_MSG(std::all_of(info.m_InputTensorInfos.begin(),
112 info.m_InputTensorInfos.end(),
113 [&](auto it){
telsoa01c577f2c2018-08-31 09:22:23 +0100114 return it.GetDataType() == InputDataType;
telsoa014fcda012018-03-09 14:13:49 +0000115 }),
116 "Trying to create workload with incorrect type");
117 BOOST_ASSERT_MSG(std::all_of(info.m_OutputTensorInfos.begin(),
118 info.m_OutputTensorInfos.end(),
119 [&](auto it){
telsoa01c577f2c2018-08-31 09:22:23 +0100120 return it.GetDataType() == OutputDataType;
telsoa014fcda012018-03-09 14:13:49 +0000121 }),
122 "Trying to create workload with incorrect type");
123 }
telsoa014fcda012018-03-09 14:13:49 +0000124};
125
126template <typename QueueDescriptor>
telsoa01c577f2c2018-08-31 09:22:23 +0100127using FloatWorkload = TypedWorkload<QueueDescriptor,
128 armnn::DataType::Float16,
129 armnn::DataType::Float32>;
130
131template <typename QueueDescriptor>
telsoa014fcda012018-03-09 14:13:49 +0000132using Float32Workload = TypedWorkload<QueueDescriptor, armnn::DataType::Float32>;
133
134template <typename QueueDescriptor>
135using Uint8Workload = TypedWorkload<QueueDescriptor, armnn::DataType::QuantisedAsymm8>;
136
telsoa01c577f2c2018-08-31 09:22:23 +0100137template <typename QueueDescriptor>
138using Float16ToFloat32Workload = MultiTypedWorkload<QueueDescriptor,
139 armnn::DataType::Float16,
140 armnn::DataType::Float32>;
141
142template <typename QueueDescriptor>
143using Float32ToFloat16Workload = MultiTypedWorkload<QueueDescriptor,
144 armnn::DataType::Float32,
145 armnn::DataType::Float16>;
146
telsoa014fcda012018-03-09 14:13:49 +0000147} //namespace armnn