-
Notifications
You must be signed in to change notification settings - Fork 0
/
CustomSubgraphViewConverter.cpp
154 lines (120 loc) · 4.71 KB
/
CustomSubgraphViewConverter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// Copyright © tuanhe. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include "CustomSubgraphViewConverter.hpp"
#include "CustomPreCompiledObject.hpp"
namespace armnn
{
uint32_t CustomSubgraphViewConverter::ms_NextInstanceId = 0;
CustomSubgraphViewConverter::CustomSubgraphViewConverter(const SubgraphView& subgraph,
ModelOptions modelOptions)
: m_InstanceId(ms_NextInstanceId++)
, m_Subgraph(subgraph)
{
armnn::IgnoreUnused(modelOptions);
ConstructCustomNetwork();
}
void CustomSubgraphViewConverter::ResetNextInstanceId()
{
ms_NextInstanceId = 0;
}
void CustomSubgraphViewConverter::AddInput(uint32_t inputSlotIdx)
{
const InputSlot& inputSlot = *m_Subgraph.GetInputSlot(inputSlotIdx);
const OutputSlot* connectedSlot = inputSlot.GetConnectedOutputSlot();
ARMNN_ASSERT(connectedSlot != nullptr);
Layer& inputLayer = connectedSlot->GetOwningLayer();
ARMNN_LOG(info) << "Graph input layer : " << inputLayer.GetNameStr();
if(!AddCustomLayer(inputLayer))
{
throw armnn::BackendUnavailableException("Convert input layer failed");
}
// Add input to the Ethos-N network
//ethosn_lib::TensorInfo CustomTensorInfo = BuildCustomTensorInfo(connectedSlot->GetTensorInfo(), DataLayout::NHWC);
//CustomAddOperationResult inputOperandAndId = ethosn_lib::AddInput(m_Network, CustomTensorInfo);
}
void CustomSubgraphViewConverter::AddOutput(uint32_t outputSlotIdx)
{
const OutputSlot& outputSlot = *m_Subgraph.GetOutputSlot(outputSlotIdx);
//Layer* outputLayer = &outputSlot.GetOwningLayer();
Layer& outputLayer = outputSlot.GetOwningLayer();
ARMNN_LOG(info) << "Graph output layer : " << outputLayer.GetNameStr();
if(!RecusedLayer(outputLayer))
{
throw armnn::BackendUnavailableException("Convert layer failed");
}
// Get the Ethos-N operand that should connect to this output
//auto input = AddOrRetrieveCustomOperand(&outputSlot);
// Add output operand to Ethos-N network
//ethosn_lib::TensorAndId<ethosn_lib::Output> output = ethosn_lib::AddOutput(m_Network, *input.tensor);
}
bool CustomSubgraphViewConverter::RecusedLayer(Layer& layer)
{
for(uint32_t i = 0; i < layer.GetNumInputSlots(); ++i)
{
auto& prevLayer = layer.GetInputSlot(i).GetConnectedOutputSlot()->GetOwningLayer();
if(std::find(m_ConvertedLayer.begin(), m_ConvertedLayer.end(), prevLayer.GetGuid()) == m_ConvertedLayer.end())
if(!RecusedLayer(prevLayer))
return false;
}
//previous layer had convetered
//check the current layer
if(std::find(m_ConvertedLayer.begin(), m_ConvertedLayer.end(), layer.GetGuid()) == m_ConvertedLayer.end())
if(!AddCustomLayer(layer))
return false;
return true;
}
bool CustomSubgraphViewConverter::AddCustomLayer(Layer& layer)
{
if(std::find(m_ConvertedLayer.begin(), m_ConvertedLayer.end(), layer.GetGuid()) != m_ConvertedLayer.end())
return true;
LayerFunctionPtr layerFunction = CustomLayerBridge::GetBridge().GetLayerFunction(layer.GetType());
if( nullptr == layerFunction)
{
std::stringstream errorMessage;
errorMessage << "Layer[" << GetLayerTypeAsCString(layer.GetType())
<< "] had not been registed into the backend";
throw armnn::UnimplementedException(errorMessage.str());
}
if(!layerFunction(layer, m_CustomDefined))
{
ARMNN_LOG(fatal) << "Layer " << layer.GetNameStr() << " convert failed";
return false;
}
m_ConvertedLayer.push_back(layer.GetGuid());
return true;
}
bool CustomSubgraphViewConverter::ConstructCustomNetwork()
{
// Add inputs
for (uint32_t inputSlotIdx = 0; inputSlotIdx < m_Subgraph.GetNumInputSlots(); ++inputSlotIdx)
{
AddInput(inputSlotIdx);
}
// Add outputs.
for (uint32_t outputSlotIdx = 0; outputSlotIdx < m_Subgraph.GetNumOutputSlots(); ++outputSlotIdx)
{
AddOutput(outputSlotIdx);
}
return true;
}
namespace
{
template <typename T>
void DeleteAsType(const void* const blob)
{
delete static_cast<const T*>(blob);
}
} // namespace
std::vector<CompiledBlobPtr> CustomSubgraphViewConverter::CompileNetwork()
{
auto preCompiledObject = std::make_unique<CustomPreCompiledObject>();
preCompiledObject->SetDebugName("Debug Name");
preCompiledObject->PreInferenceStage(m_CustomDefined);
std::vector<CompiledBlobPtr> compiledBlobs;
// Convert the EthosNPreCompiledObject into a "blob" (void) object and attach the custom blob deleter
compiledBlobs.emplace_back(preCompiledObject.release(), DeleteAsType<CustomPreCompiledObject>);
return compiledBlobs;
}
} // namespace armnn