diff options
-rw-r--r-- | arm_compute/graph/GraphBuilder.h | 17 | ||||
-rw-r--r-- | arm_compute/graph/frontend/Layers.h | 48 | ||||
-rw-r--r-- | src/graph/GraphBuilder.cpp | 27 |
3 files changed, 89 insertions, 3 deletions
diff --git a/arm_compute/graph/GraphBuilder.h b/arm_compute/graph/GraphBuilder.h index 1296f56482..a2a938b1cc 100644 --- a/arm_compute/graph/GraphBuilder.h +++ b/arm_compute/graph/GraphBuilder.h @@ -236,6 +236,23 @@ public: static NodeID add_flatten_node(Graph &g, NodeParams params, NodeIdxPair input); /** Adds a fully connected layer node to the graph * + * @param[in] g Graph to add the layer to + * @param[in] params Common node parameters + * @param[in] input Input to the fully connected layer node as a NodeID-Index pair + * @param[in] num_outputs Number of output neurons + * @param[in] weights_nid Node ID of the weights node data + * @param[in] bias_nid (Optional) Node ID of the bias node data. Defaults to EmptyNodeID + * @param[in] fc_info (Optional) Fully connected layer metadata + * @param[in] out_quant_info (Optional) Output quantization info + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, + NodeID weights_nid, NodeID bias_nid = EmptyNodeID, + const FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), + const QuantizationInfo out_quant_info = QuantizationInfo()); + /** Adds a fully connected layer node to the graph + * * @param[in] g Graph to add the layer to * @param[in] params Common node parameters * @param[in] input Input to the fully connected layer node as a NodeID-Index pair diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h index 1a71c89e54..d062d5a53e 100644 --- a/arm_compute/graph/frontend/Layers.h +++ b/arm_compute/graph/frontend/Layers.h @@ -578,6 +578,34 @@ public: : _num_outputs(num_outputs), _weights(std::move(weights)), _bias(std::move(bias)), + _weights_ss(nullptr), + _bias_ss(nullptr), + _fc_info(fc_info), + _weights_quant_info(std::move(weights_quant_info)), + _out_quant_info(std::move(out_quant_info)) + { + } + + /** Construct a fully connected layer. + * + * @param[in] num_outputs Number of outputs. + * @param[in] sub_stream_weights Graph sub-stream for the weights. + * @param[in] sub_stream_bias Graph sub-stream for the bias. + * @param[in] fc_info (Optional) Fully connected layer metadata + * @param[in] weights_quant_info (Optional) Weights quantization information + * @param[in] out_quant_info (Optional) Output quantization info + */ + FullyConnectedLayer(unsigned int num_outputs, + SubStream &&sub_stream_weights, + SubStream &&sub_stream_bias, + const FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(), + const QuantizationInfo weights_quant_info = QuantizationInfo(), + const QuantizationInfo out_quant_info = QuantizationInfo()) + : _num_outputs(num_outputs), + _weights(nullptr), + _bias(nullptr), + _weights_ss(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream_weights))), + _bias_ss(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream_bias))), _fc_info(fc_info), _weights_quant_info(std::move(weights_quant_info)), _out_quant_info(std::move(out_quant_info)) @@ -594,15 +622,29 @@ public: { NodeParams common_params = { name(), s.hints().target_hint }; NodeIdxPair input = { s.tail_node(), 0 }; - return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs, - std::move(_weights), std::move(_bias), _fc_info, - std::move(_weights_quant_info), std::move(_out_quant_info)); + if(_weights != nullptr) + { + return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs, + std::move(_weights), std::move(_bias), _fc_info, + std::move(_weights_quant_info), std::move(_out_quant_info)); + } + else + { + ARM_COMPUTE_ERROR_ON(_weights_ss == nullptr); + + NodeID bias_nid = (_bias_ss == nullptr) ? EmptyNodeID : _bias_ss->tail_node(); + return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs, + _weights_ss->tail_node(), bias_nid, _fc_info, + std::move(_out_quant_info)); + } } private: unsigned int _num_outputs; ITensorAccessorUPtr _weights; ITensorAccessorUPtr _bias; + std::unique_ptr<SubStream> _weights_ss; + std::unique_ptr<SubStream> _bias_ss; const FullyConnectedLayerInfo _fc_info; const QuantizationInfo _weights_quant_info; const QuantizationInfo _out_quant_info; diff --git a/src/graph/GraphBuilder.cpp b/src/graph/GraphBuilder.cpp index a944d2c25d..30f1fc6894 100644 --- a/src/graph/GraphBuilder.cpp +++ b/src/graph/GraphBuilder.cpp @@ -405,6 +405,33 @@ NodeID GraphBuilder::add_flatten_node(Graph &g, NodeParams params, NodeIdxPair i } NodeID GraphBuilder::add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, + NodeID weights_nid, NodeID bias_nid, + const FullyConnectedLayerInfo fc_info, const QuantizationInfo out_quant_info) +{ + CHECK_NODEIDX_PAIR(input, g); + ARM_COMPUTE_ERROR_ON(num_outputs == 0); + ARM_COMPUTE_ERROR_ON(weights_nid == EmptyNodeID); + + const bool has_bias = (bias_nid != EmptyNodeID); + + // Get input tensor descriptor + const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); + + // Create fully connected node and connect + NodeID fc_nid = g.add_node<FullyConnectedLayerNode>(num_outputs, out_quant_info, fc_info); + g.add_connection(input.node_id, input.index, fc_nid, 0); + g.add_connection(weights_nid, 0, fc_nid, 1); + if(has_bias) + { + g.add_connection(bias_nid, 0, fc_nid, 2); + } + + set_node_params(g, fc_nid, params); + + return fc_nid; +} + +NodeID GraphBuilder::add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor, const FullyConnectedLayerInfo fc_info, const QuantizationInfo weights_quant_info, const QuantizationInfo out_quant_info) |