diff options
Diffstat (limited to 'arm_compute/graph')
86 files changed, 5604 insertions, 1696 deletions
diff --git a/arm_compute/graph/Edge.h b/arm_compute/graph/Edge.h new file mode 100644 index 0000000000..003b0dee94 --- /dev/null +++ b/arm_compute/graph/Edge.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_EDGE_H__ +#define __ARM_COMPUTE_GRAPH_EDGE_H__ + +#include "arm_compute/graph/INode.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/Types.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; + +/** Graph Edge */ +class Edge final +{ +public: + /** Default Constructor + * + * @param[in] id Edge id + * @param[in] producer Producer node id + * @param[in] producer_idx Producer node output index + * @param[in] consumer Consumer node id + * @param[in] consumer_idx Consumer node input index + * @param[in] tensor Tensor associated with the edge + */ + Edge(EdgeID id, INode *producer, unsigned int producer_idx, INode *consumer, unsigned int consumer_idx, Tensor *tensor) + : _id(id), _producer(producer), _consumer(consumer), _producer_idx(producer_idx), _consumer_idx(consumer_idx), _tensor(tensor) + + { + } + /** Returns edge id + * + * @return Edge id + */ + EdgeID id() const + { + return _id; + } + /** Returns producer node id + * + * @return Producer node id + */ + NodeID producer_id() const + { + return (_producer == nullptr) ? EmptyNodeID : _producer->id(); + } + /** Returns sink node id + * + * @return Sink node id + */ + NodeID consumer_id() const + { + return (_consumer == nullptr) ? EmptyNodeID : _consumer->id(); + } + /** Returns producer node + * + * @return Producer node + */ + INode *producer() const + { + return _producer; + } + /** Returns consumer node + * + * @return Consumer node + */ + INode *consumer() const + { + return _consumer; + } + /** Returns the index of the output that produces the result in the producer node + * + * @return Producer node output index + */ + unsigned int producer_idx() const + { + return _producer_idx; + } + /** Returns the index of the input that consumes the result in the consumer node + * + * @return Consumer node input index + */ + unsigned int consumer_idx() const + { + return _consumer_idx; + } + /** Returns the tensor associated with this edge + * + * @return Tensor id + */ + Tensor *tensor() const + { + return _tensor; + } + /** Returns the tensor id associated with this edge + * + * @return Tensor id + */ + TensorID tensor_id() const + { + return (_tensor == nullptr) ? NullTensorID : _tensor->id(); + } + /** Bind the edge to another tensor + * + * @note If tensor is nullptr then nothing happens + * + * @param[in] tensor Tensor to bind the edge to + */ + void update_bound_tensor(Tensor *tensor) + { + _tensor = (tensor != nullptr) ? tensor : _tensor; + } + +private: + friend class Graph; + +private: + EdgeID _id; + INode *_producer; + INode *_consumer; + unsigned int _producer_idx; + unsigned int _consumer_idx; + Tensor *_tensor; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_EDGE_H__ */ diff --git a/arm_compute/graph/Error.h b/arm_compute/graph/Error.h deleted file mode 100644 index 0c8ed266c0..0000000000 --- a/arm_compute/graph/Error.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_ERROR_H__ -#define __ARM_COMPUTE_GRAPH_ERROR_H__ - -#include "arm_compute/graph/ITensorObject.h" - -namespace arm_compute -{ -namespace graph -{ -/** Evaluate if a tensor object is null. If the condition is true then an error message is printed and an exception thrown - * - * @param[in] function Function in which the error occurred. - * @param[in] file Name of the file where the error occurred. - * @param[in] line Line on which the error occurred. - * @param[in] tensor_object Tensor object to evaluate - * @param[in] tensor_objects (Optional) Further allowed tensor objects. - */ -template <typename... Ts> -void error_on_unallocated_tensor_object(const char *function, const char *file, int line, - const ITensorObject *tensor_object, Ts... tensor_objects) -{ - ARM_COMPUTE_UNUSED(function); - ARM_COMPUTE_UNUSED(file); - ARM_COMPUTE_UNUSED(line); - ARM_COMPUTE_UNUSED(tensor_object); - - ARM_COMPUTE_ERROR_ON_LOC(tensor_object == nullptr || tensor_object->tensor() == nullptr, function, file, line); - - const std::array<const ITensorObject *, sizeof...(Ts)> tensor_objects_array{ { std::forward<Ts>(tensor_objects)... } }; - ARM_COMPUTE_UNUSED(tensor_objects_array); - - ARM_COMPUTE_ERROR_ON_LOC(std::any_of(tensor_objects_array.begin(), tensor_objects_array.end(), [&](const ITensorObject * tensor_obj) - { - return (tensor_obj == nullptr || tensor_object->tensor() == nullptr); - }), - function, file, line); -} -#define ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(...) ::arm_compute::graph::error_on_unallocated_tensor_object(__func__, __FILE__, __LINE__, __VA_ARGS__) -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_ERROR_H__ */ diff --git a/arm_compute/graph/Graph.h b/arm_compute/graph/Graph.h index 72130878f8..16f5f97986 100644 --- a/arm_compute/graph/Graph.h +++ b/arm_compute/graph/Graph.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -24,130 +24,238 @@ #ifndef __ARM_COMPUTE_GRAPH_GRAPH_H__ #define __ARM_COMPUTE_GRAPH_GRAPH_H__ -#include "arm_compute/core/CL/CLTypes.h" +#include "arm_compute/graph/Edge.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/SubTensor.h" #include "arm_compute/graph/Tensor.h" #include "arm_compute/graph/Types.h" + +#include "support/Mutex.h" #include "support/ToolchainSupport.h" +#include <map> #include <memory> +#include <string> +#include <thread> +#include <utility> +#include <vector> namespace arm_compute { -class IFunction; - namespace graph { -/** Graph class */ +/** Graph class + * + * Represents a multiple source - multiple sink directed graph + */ class Graph final { public: - /** Constructor */ - Graph(); - /** Destructor */ - ~Graph(); - /** Prevent instances from being copy constructed */ + Graph() = default; + /** Constructor + * + * @param[in] id Graph identification number. Can be used to differentiate between graphs. Default value 0 + * @param[in] name Graph name. Default value empty string + */ + Graph(GraphID id, std::string name); + /** Prevent instances of this class from being copied (As this class contains pointers) */ Graph(const Graph &) = delete; - /** Prevent instances from being copy assigned */ - const Graph &operator=(const Graph &) = delete; - /** Prevent instances from being move constructed */ - Graph(Graph &&) = delete; - /** Prevent instances from being move assigned */ - Graph &operator=(Graph &&) = delete; - /** Initialize the graph - * - * @param[in] use_cl_tuner Use the CLTuner if this value is true - */ - void graph_init(const bool use_cl_tuner = false); - /** Executes the graph */ - void run(); + /** Prevent instances of this class from being copy assigned (As this class contains pointers) */ + Graph &operator=(const Graph &) = delete; + /** Allow instances of this class to be moved */ + Graph(Graph &&) = default; + /** Allow instances of this class to be move assigned */ + Graph &operator=(Graph &&) = default; /** Adds a node to the graph * - * @param[in] node Node to add + * @note Models a single output node + * + * @tparam NT Node operation + * @tparam Ts Arguments to operation + * + * @param args Node arguments + * + * @return ID of the node + */ + template <typename NT, typename... Ts> + NodeID add_node(Ts &&... args); + /** Remove the node with the given ID + * + * @param[in] nid ID of the node to remove + * + * @return True if the removal took place else false + */ + bool remove_node(NodeID nid); + /** Adds a connection between two nodes + * + * @param[in] source ID of the source node + * @param[in] source_idx Output index of the source node + * @param[in] sink ID of the sink node + * @param[in] sink_idx Input index of the sink node + * + * @return ID of this connection + */ + EdgeID add_connection(NodeID source, size_t source_idx, NodeID sink, size_t sink_idx); + /** Removes an edge (connection) + * + * @param[in] eid Connection to remove + * + * @return True if the removal took place else false + */ + bool remove_connection(EdgeID eid); + /** Returns graph name + * + * @return Graph name + */ + std::string name() const; + /** Returns graph id + * + * @return Graph id */ - void add_node(std::unique_ptr<INode> node); - /** Adds a tensor to the graph + GraphID id() const; + /** Returns graph input nodes * - * @param[in] tensor Tensor to add + * @return vector containing the graph inputs */ - void add_tensor_object(std::unique_ptr<ITensorObject> tensor); - /** Check if the OpenCL target is available + const std::vector<NodeID> &inputs(); + /** Returns nodes of graph + * + * @warning Nodes can be nullptr if they have been removed during the mutation steps of the graph + * + * @return Nodes of graph */ - static bool opencl_is_available(); - /** Returns the GPU target + std::vector<std::unique_ptr<INode>> &nodes(); + /** Returns nodes of graph + * + * @warning Nodes can be nullptr if they have been removed during the mutation steps of the graph + * + * @return Nodes of graph */ - static GPUTarget gpu_target(); - /** Manually sets the output of the current node + const std::vector<std::unique_ptr<INode>> &nodes() const; + /** Returns edges of graph + * + * @warning Edges can be nullptr if they have been removed during the mutation steps of the graph * - * @param[in] tmp Output info to set + * @return Edges of graph */ - void set_temp(TensorInfo &&tmp); + const std::vector<std::unique_ptr<Edge>> &edges() const; + /** Returns tensors of graph + * + * @warning Tensor can be nullptr if they have been removed during the mutation steps of the graph + * + * @return Tensors of graph + */ + std::vector<std::unique_ptr<Tensor>> &tensors(); + /** Returns tensors of graph + * + * @warning Tensor can be nullptr if they have been removed during the mutation steps of the graph + * + * @return Tensors of graph + */ + const std::vector<std::unique_ptr<Tensor>> &tensors() const; + /** Get node object given its id + * + * @warning Can be nullptr if node was removed during the mutation steps of the graph + * + * @param[in] id Node ID + * + * @return The actual node object + */ + const INode *node(NodeID id) const; + /** Get node object given its id + * + * @warning Can be nullptr if node was removed during the mutation steps of the graph + * + * @param[in] id Node ID + * + * @return The actual node object + */ + INode *node(NodeID id); + /** Get edge object given its id + * + * @warning Can be nullptr if node was removed during the mutation steps of the graph + * + * @param[in] id Edge ID + * + * @return The actual edge object + */ + const Edge *edge(EdgeID id) const; + /** Get edge object given its id + * + * @warning Can be nullptr if node was removed during the mutation steps of the graph + * + * @param[in] id Edge ID + * + * @return The actual edge object + */ + Edge *edge(EdgeID id); + /** Get tensor object given its id + * + * @warning Can be nullptr if tensor was removed during the mutation steps of the graph + * + * @param[in] id Tensor ID + * + * @return The actual tensor object + */ + const Tensor *tensor(TensorID id) const; + /** Get tensor object given its id + * + * @warning Can be nullptr if tensor was removed during the mutation steps of the graph + * + * @param[in] id Tensor ID + * + * @return The actual tensor object + */ + Tensor *tensor(TensorID id); - /** Returns the graph hints that are currently used +private: + /** Creates a tensor object * - * @return Graph hints + * @param[in] desc Tensor descriptor + * + * @return Tensor ID */ - GraphHints &hints(); + TensorID create_tensor(TensorDescriptor desc = TensorDescriptor()); private: - class Private; - std::unique_ptr<Private> _pimpl; /**< Internal implementation class */ + GraphID _id = GraphID(0); /**< Graph id */ + std::string _name = {}; /**< Graph name */ + std::vector<std::unique_ptr<INode>> _nodes = {}; /**< Graph nodes */ + std::vector<std::unique_ptr<Edge>> _edges = {}; /**< Graph edges */ + std::vector<std::unique_ptr<Tensor>> _tensors = {}; /**< Graph tensors */ + std::map<NodeType, std::vector<NodeID>> _tagged_nodes = {}; /**< Graph nodes map with the node type as key */ + arm_compute::Mutex _mtx = {}; /**< Mutex used for graph construction */ }; -/** Overloaded stream operator to add a tensor through its tensor info to the graph - * - * @param[in, out] graph Graph to add the tensor - * @param[in] info Tensor information of the tensor to be added - * - * @return Updated graph - */ -Graph &operator<<(Graph &graph, TensorInfo &&info); -/** Overloaded stream operator to add a tensor to the graph - * - * @param[in, out] graph Graph to add the tensor - * @param[in] tensor Tensor to be added - * - * @return Updated graph - */ -Graph &operator<<(Graph &graph, Tensor &&tensor); -/** Overloaded stream operator to add a sub-tensor to the graph - * - * @param[in, out] graph Graph to add the tensor - * @param[in] sub_tensor Sub-tensor to be added - * - * @return Updated graph - */ -Graph &operator<<(Graph &graph, SubTensor &&sub_tensor); -/** Overloaded stream operator to provide a target hint to the graph - * - * @param[in, out] graph Graph to provide the hint to - * @param[in] target_hint Target hint to be considered - * - * @return Updated graph - */ -Graph &operator<<(Graph &graph, TargetHint target_hint); -/** Overloaded stream operator to provide a convolution method hint to the graph - * - * @param[in, out] graph Graph to provide the hint to - * @param[in] conv_method_hint Convolution method hint to be considered - * - * @return Updated graph - */ -Graph &operator<<(Graph &graph, ConvolutionMethodHint conv_method_hint); -/** Overloaded stream operator to add a node to the graph - * - * @param[in, out] graph Graph to add the tensor - * @param[in] node Node to be added - * - * @return Updated graph - */ -template <typename Node> -Graph &operator<<(Graph &graph, Node node) +template <typename NT, typename... Ts> +inline NodeID Graph::add_node(Ts &&... args) { - graph.add_node(arm_compute::support::cpp14::make_unique<Node>(std::move(node))); - return graph; + std::lock_guard<arm_compute::Mutex> lock(_mtx); + + // Create node + NodeID nid = _nodes.size(); + auto node = support::cpp14::make_unique<NT>(std::forward<Ts>(args)...); + node->set_graph(this); + node->set_id(nid); + + // Keep track of input nodes + if(node->type() == NodeType::Input) + { + _tagged_nodes[NodeType::Input].push_back(nid); + } + + // Associate a new tensor with each output + for(auto &output : node->_outputs) + { + output = create_tensor(); + } + + // Propagate node shape if possible + node->forward_descriptors(); + + // Add node to the graph nodes + _nodes.push_back(std::move(node)); + + return nid; } } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/GraphBuilder.h b/arm_compute/graph/GraphBuilder.h new file mode 100644 index 0000000000..e01cfb1bc6 --- /dev/null +++ b/arm_compute/graph/GraphBuilder.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H__ +#define __ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H__ + +#include "arm_compute/graph/ITensorAccessor.h" +#include "arm_compute/graph/Types.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declaration +class Graph; + +/** Graph builder class + * + * Builds and compiles a graph + */ +class GraphBuilder final +{ +public: + /** Adds a Const node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] desc Tensor descriptor of the node + * @param[in] accessor (Optional) Accessor of the const node data + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_const_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor = nullptr); + /** Adds an input layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] desc Tensor descriptor of the Tensor + * @param[in] accessor (Optional) Accessor of the input node data + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_input_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor = nullptr); + /** Adds an output layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the output node as a NodeID-Index pair + * @param[in] accessor (Optional) Accessor of the output node data + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor = nullptr); + /** Adds an activation layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the activation layer node as a NodeID-Index pair + * @param[in] act_info Activation layer information + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_activation_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info); + /** Adds a batch normalization layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the batch normalization layer node as a NodeID-Index pair + * @param[in] epsilon Epsilon parameter + * @param[in] mean_accessor Const Node ID that contains the mean values + * @param[in] var_accessor Const Node ID that contains the variance values + * @param[in] beta_accessor Const Node ID that contains the beta values. Can be EmptyNodeID + * @param[in] gamma_accessor Const Node ID that contains the gamma values. Can be EmptyNodeID + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_batch_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, float epsilon, + ITensorAccessorUPtr mean_accessor = nullptr, ITensorAccessorUPtr var_accessor = nullptr, + ITensorAccessorUPtr beta_accessor = nullptr, ITensorAccessorUPtr gamma_accessor = nullptr); + /** Adds a convolution layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the convolution layer node as a NodeID-Index pair + * @param[in] kernel_spatial_extend Spatial extend of convolution kernels + * @param[in] depth Number of convolution kernels + * @param[in] conv_info Convolution layer information + * @param[in] num_groups (Optional) Number of groups for a grouped convolution. Defaults to 1 + * @param[in] method (Optional) Convolution method to use + * @param[in] weights_accessor (Optional) Accessor of the weights node data + * @param[in] bias_accessor (Optional) Accessor of the bias node data + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, + Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo conv_info, + unsigned int num_groups = 1, ConvolutionMethod method = ConvolutionMethod::DEFAULT, + ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr); + /** Adds a depth concatenate node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] inputs Inputs to the depth concatenate layer node as a NodeID-Index pair + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_depth_concatenate_node(Graph &g, NodeParams params, std::vector<NodeIdxPair> inputs); + /** Adds a depth-wise convolution layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the depthwise convolution layer node as a NodeID-Index pair + * @param[in] kernel_spatial_extend Spatial extend of convolution kernels + * @param[in] conv_info Convolution layer information + * @param[in] method (Optional) Convolution method to use + * @param[in] weights_accessor (Optional) Accessor of the weights node data + * @param[in] bias_accessor (Optional) Accessor of the bias node data + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_depthwise_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, + Size2D kernel_spatial_extend, PadStrideInfo conv_info, + DepthwiseConvolutionMethod method = DepthwiseConvolutionMethod::DEFAULT, + ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr); + /** Adds an element-wise layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input0 First input to the element-wise operation layer node as a NodeID-Index pair + * @param[in] input1 Second input to the element-wise operation layer node as a NodeID-Index pair + * @param[in] operation Element-wise operation to perform + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_elementwise_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation); + /** Adds a flatten layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the flatten layer node as a NodeID-Index pair + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + 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_accessor (Optional) Accessor of the weights node data + * @param[in] bias_accessor (Optional) Accessor of the bias node data + * + * @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, + ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr); + /** Adds a normalization layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the normalization layer node as a NodeID-Index pair + * @param[in] norm_info Normalization layer information + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info); + /** Adds a pooling layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the pooling layer node as a NodeID-Index pair + * @param[in] pool_info Pooling layer information + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_pooling_node(Graph &g, NodeParams params, NodeIdxPair input, PoolingLayerInfo pool_info); + /** Adds a reshape layer node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the reshape layer node as a NodeID-Index pair + * @param[in] shape Output reshaped shape + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_reshape_node(Graph &g, NodeParams params, NodeIdxPair input, TensorShape shape); + /** Adds a softmax node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the softmax layer node as a NodeID-Index pair + * @param[in] beta Beta parameter + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_softmax_node(Graph &g, NodeParams params, NodeIdxPair input, float beta = 1.f); + /** Adds a split node to the graph + * + * @param[in] g Graph to add the node to + * @param[in] params Common node parameters + * @param[in] input Input to the split layer node as a NodeID-Index pair + * @param[in] num_splits Number of different splits + * @param[in] axis (Optional) Split axis. Defaults to 0 + * + * @return Node ID of the created node, EmptyNodeID in case of error + */ + static NodeID add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis = 0); +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H__ */ diff --git a/arm_compute/graph/GraphContext.h b/arm_compute/graph/GraphContext.h index 98bc8c02f8..2f9ab665ce 100644 --- a/arm_compute/graph/GraphContext.h +++ b/arm_compute/graph/GraphContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,68 +21,74 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_CONTEXT_H__ -#define __ARM_COMPUTE_GRAPH_CONTEXT_H__ +#ifndef __ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H__ +#define __ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H__ #include "arm_compute/graph/Types.h" +#include "arm_compute/runtime/IMemoryManager.h" + +#include <map> +#include <memory> + namespace arm_compute { namespace graph { -/** Hints that can be passed to the graph to expose parameterization */ -class GraphHints +/** Contains structs required for memory management */ +struct MemoryManagerContext +{ + Target target = { Target::UNSPECIFIED }; /**< Target */ + std::shared_ptr<arm_compute::IMemoryManager> mm = { nullptr }; /**< Memory manager */ +}; + +/** Graph context **/ +class GraphContext final { public: - /** Default Constructor */ - GraphHints(TargetHint target_hint = TargetHint::DONT_CARE, - ConvolutionMethodHint conv_method_hint = ConvolutionMethodHint::GEMM); - /** Sets target execution hint + /** Constructor */ + GraphContext(); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + GraphContext(const GraphContext &) = delete; + /** Default move constructor */ + GraphContext(GraphContext &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + GraphContext &operator=(const GraphContext &) = delete; + /** Default move assignment operator */ + GraphContext &operator=(GraphContext &&) = default; + /** Graph configuration accessor * - * @param target_hint Target execution hint - */ - void set_target_hint(TargetHint target_hint); - /** Sets convolution method to use + * @note Every alteration has to be done before graph finalization * - * @param convolution_method Convolution method to use + * @return The graph configuration */ - void set_convolution_method_hint(ConvolutionMethodHint convolution_method); - /** Returns target execution hint + const GraphConfig &config() const; + /** Sets graph configuration * - * @return target execution hint + * @param[in] config Configuration to use */ - TargetHint target_hint() const; - /** Returns convolution method hint + void set_config(const GraphConfig &config); + /** Inserts a memory manager context * - * @return convolution method hint - */ - ConvolutionMethodHint convolution_method_hint() const; - -private: - TargetHint _target_hint; /**< Target execution hint */ - ConvolutionMethodHint _convolution_method_hint; /**< Convolution method hint */ -}; - -/** Graph context */ -class GraphContext -{ -public: - /** Default Constuctor */ - GraphContext(); - /** Returns graph hints + * @param[in] memory_ctx Memory manage context * - * @return Graph hints + * @return If the insertion succeeded else false */ - GraphHints &hints(); - /** Returns graph hints + bool insert_memory_management_ctx(MemoryManagerContext &&memory_ctx); + /** Gets a memory manager context for a given target + * + * @param[in] target To retrieve the management context * - * @return Graph hints + * @return Management context for the target if exists else nullptr */ - const GraphHints &hints() const; + MemoryManagerContext *memory_management_ctx(Target target); + /** Finalizes memory managers in graph context */ + void finalize(); private: - GraphHints _hints; /**< Graph hints */ + GraphConfig _config; /**< Graph configuration */ + std::map<Target, MemoryManagerContext> _memory_managers; /**< Memory managers for each target */ }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_CONTEXT_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_GRAPH_CONTEXT_H__ */ diff --git a/arm_compute/graph/GraphManager.h b/arm_compute/graph/GraphManager.h new file mode 100644 index 0000000000..9526a0b4cc --- /dev/null +++ b/arm_compute/graph/GraphManager.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_GRAPH_MANAGER_H__ +#define __ARM_COMPUTE_GRAPH_GRAPH_MANAGER_H__ + +#include "arm_compute/graph/Types.h" +#include "arm_compute/graph/Workload.h" + +#include <map> + +namespace arm_compute +{ +namespace graph +{ +// Forward declaration +class Graph; +class GraphContext; +class PassManager; + +/** Graph manager class + * + * Manages a list of graphs along with their resources + */ +class GraphManager final +{ +public: + /** Default Constructor **/ + GraphManager(); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + GraphManager(const GraphManager &) = delete; + /** Default move constructor */ + GraphManager(GraphManager &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + GraphManager &operator=(const GraphManager &) = delete; + /** Default move assignment operator */ + GraphManager &operator=(GraphManager &&) = default; + /** Finalizes a given graph + * + * @warning At this given time finalize_graph will alter the passed graph, + * plan is to avoid by copying the graph structure, + * or provide another entry-point for this functionality as it will increase the memory requirements + * + * @param[in] graph Graph to finalize + * @param[in] ctx Graph context + * @param[in] pm Pass manager to use for any optimization passes + * @param[in] target Execution target (Single target execution is currently supported) + */ + void finalize_graph(Graph &graph, GraphContext &ctx, PassManager &pm, Target target); + /** Executes a graph + * + * @param[in] graph Graph to execute + */ + void execute_graph(Graph &graph); + /** Invalidates the graph execution workload + * + * @param[in] graph Graph to invalidate + */ + void invalidate_graph(Graph &graph); + +private: + std::map<GraphID, ExecutionWorkload> _workloads = {}; /**< Graph workloads */ +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_GRAPH_MANAGER_H__ */ diff --git a/arm_compute/graph/IDeviceBackend.h b/arm_compute/graph/IDeviceBackend.h new file mode 100644 index 0000000000..fa6fbae1ea --- /dev/null +++ b/arm_compute/graph/IDeviceBackend.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_IDEVICEBACKEND_H__ +#define __ARM_COMPUTE_GRAPH_IDEVICEBACKEND_H__ + +#include "arm_compute/graph/ITensorHandle.h" +#include "arm_compute/graph/Types.h" +#include "arm_compute/runtime/IFunction.h" +#include "arm_compute/runtime/IMemoryManager.h" + +#include <memory> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; +class GraphContext; +class Tensor; +class INode; + +namespace backends +{ +/** Device backend interface */ +class IDeviceBackend +{ +public: + /** Virtual Destructor */ + virtual ~IDeviceBackend() = default; + /** Initializes the backend */ + virtual void initialize_backend() = 0; + /** Setups the given graph context + * + * @param[in] ctx Graph context + */ + virtual void setup_backend_context(GraphContext &ctx) = 0; + /** Checks if an instantiated backend is actually supported + * + * @return True if the backend is supported else false + */ + virtual bool is_backend_supported() = 0; + /** Create a backend Tensor + * + * @param[in] tensor The tensor we want to create a backend tensor for + * + * @return Backend tensor handle + */ + virtual std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) = 0; + /** Create a backend Sub-Tensor + * + * @param[in] parent Parent sub-tensor handle + * @param[in] shape Shape of the sub-tensor + * @param[in] coords Starting coordinates of the sub-tensor + * @param[in] extend_parent Extends parent shape if true + * + * @return Backend sub-tensor handle + */ + virtual std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) = 0; + /** Configure a backend Node + * + * @note This creates an appropriate configured backend function for the given node + * + * @param[in] node The node we want to configure + * @param[in] ctx Context to use + * + * @return Backend execution function + */ + virtual std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) = 0; + /** Validate a node + * + * @param[in] node The node we want to validate + * + * @return An error status + */ + virtual Status validate_node(INode &node) = 0; + /** Create a backend memory manager given its affinity + * + * @param[in] affinity Memory Manager affinity + * + * @return Memory manager + */ + virtual std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) = 0; +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_IDEVICEBACKEND_H__ diff --git a/arm_compute/graph/IGraphMutator.h b/arm_compute/graph/IGraphMutator.h new file mode 100644 index 0000000000..714fd7c3d0 --- /dev/null +++ b/arm_compute/graph/IGraphMutator.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_IGRAPHMUTATOR_H__ +#define __ARM_COMPUTE_GRAPH_IGRAPHMUTATOR_H__ + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; + +/** Graph mutator interface */ +class IGraphMutator +{ +public: + /** Virtual Destructor */ + virtual ~IGraphMutator() = default; + /** Walk the graph and perform a specific mutation + * + * @param[in, out] g Graph to walk and mutate + */ + virtual void mutate(Graph &g) = 0; + /** Returns mutator name + * + * @return Mutator name + */ + virtual const char *name() = 0; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_IGRAPHMUTATOR_H__ */ diff --git a/arm_compute/graph/nodes/FloorLayer.h b/arm_compute/graph/IGraphPrinter.h index 146e2c16dd..aba52b1f74 100644 --- a/arm_compute/graph/nodes/FloorLayer.h +++ b/arm_compute/graph/IGraphPrinter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,25 +21,31 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__ +#define __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__ + +#include <ostream> -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** Floor layer node */ -class FloorLayer final : public INode +// Forward declarations +class Graph; + +/** Graph printer interface */ +class IGraphPrinter { public: - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + /** Virtual Destructor */ + virtual ~IGraphPrinter() = default; + /** Print graph + * + * @param[in] g Graph to print + * @param[out] os Output stream + */ + virtual void print(const Graph &g, std::ostream &os) = 0; }; - } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_FLOOR_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__ */ diff --git a/arm_compute/graph/INode.h b/arm_compute/graph/INode.h index be4575de91..5d9c36e098 100644 --- a/arm_compute/graph/INode.h +++ b/arm_compute/graph/INode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -24,65 +24,228 @@ #ifndef __ARM_COMPUTE_GRAPH_INODE_H__ #define __ARM_COMPUTE_GRAPH_INODE_H__ -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/ITensorObject.h" +#include "arm_compute/core/Error.h" +#include "arm_compute/graph/TensorDescriptor.h" #include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" -#include <memory> +#include <set> namespace arm_compute { namespace graph { +// Forward declarations +class Graph; +class Edge; +class INodeVisitor; +class Tensor; + /** Node interface */ class INode { public: - /** Virtual Destructor */ + /** Constructor */ + INode(); + /** Destructor **/ virtual ~INode() = default; - /** Interface to be implemented that instantiates the node + /** Prevent instances of this class from being copied (As this class contains pointers) */ + INode(const INode &) = delete; + /** Prevent instances of this class from being copy assigned (As this class contains pointers) */ + INode &operator=(const INode &) = delete; + /** Allow instances of this class to be moved */ + INode(INode &&) = default; + /** Allow instances of this class to be move assigned */ + INode &operator=(INode &&) = default; + /** Validate node * - * @param[in] ctx Graph context to be used - * @param[in] input Input tensor of the node - * @param[in] output Output tensor of the node + * @return Status containing any errors + */ + virtual Status validate() = 0; + /** Returns node's type * - * @return a pointer to the function which implements the node. + * @return Node's type */ - virtual std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) = 0; - /** Override the existing target hint + virtual NodeType type() const = 0; + /** Accepts a node visitor * - * @note If the input is DONT_CARE then the method has to pick a technology, - * else it can accept the hint or override it (But not with DONT_CARE) + * @param[in] v Visitor to accept + */ + virtual void accept(INodeVisitor &v) = 0; + /** Forwards descriptor information to outputs if possible + * + * @return True if descriptor information could be forwarded otherwise false + */ + virtual bool forward_descriptors() = 0; + /** Calculates output configuration * - * @param[in] target_hint Target hint to be considered + * @param[in] idx Output index to configure * - * @return The updated target hint + * @return Output descriptor configuration */ - TargetHint override_target_hint(TargetHint target_hint) const; - /** Method to check if the node supports in-place operations. + virtual TensorDescriptor configure_output(size_t idx) const = 0; + /** Returns node's name * - * @return True if the node supports in-place operations, false otherwise. + * @return Node name */ - virtual bool supports_in_place() const; - /** Set the value of the _supports_in_place attribute. + std::string name() const; + /** Returns node's ID * - * @param[in] value Boolean value to assign to _supports_in_place. + * @return Node's ID */ - void set_supports_in_place(bool value); - -protected: - /** Interface to be implement that override the hints + NodeID id() const; + /** Returns node's Graph + * + * @return Node's graph + */ + const Graph *graph() const; + /** Returns node's Graph + * + * @return Node's graph + */ + Graph *graph(); + /** Sets the graph that this node is registered to + * + * @param[in] g Back reference to graph + */ + void set_graph(Graph *g); + /** Sets the node id + * + * @param[in] id Node id + */ + void set_id(NodeID id); + /** Sets common node parameters + * + * @param[in] common_params Common node parameters to set + */ + void set_common_node_parameters(NodeParams common_params); + /** Sets target preference * - * @param[in] hints Hints to be considered + * @note This is not the target that the graph executor might choose, its just an indication * - * @return The updated hints + * @param[in] target Target preference */ - virtual GraphHints node_override_hints(GraphHints hints) const; + void set_requested_target(Target target); + /** Sets the final execution target + * + * @note GraphManager might change this target + * + * @param[in] target Final execution target + */ + void set_assigned_target(Target target); + /** Sets the output tensor of at a given index + * + * @note All edges will get updated + * + * @param[in] tid Tensor ID + * @param[in] idx Output index + */ + void set_output_tensor(TensorID tid, size_t idx); + /** Returns inputs of the node + * + * @return Inputs of the node + */ + const std::vector<TensorID> &inputs() const; + /** Returns outputs of the node + * + * @return Outputs of the node + */ + const std::vector<TensorID> &outputs() const; + /** Returns input edge set + * + * @return Set of input edges + */ + const std::vector<EdgeID> &input_edges() const; + /** Returns output edge set + * + * @return Set of output edges + */ + const std::set<EdgeID> &output_edges() const; + /** Returns the tensor ID of a given input of the node + * + * @note Precondition : idx should be a valid input index + * + * @param[in] idx Index of the node input + * + * @return TensorID of the requested input + */ + TensorID input_id(size_t idx) const; + /** Returns the tensor ID of a given output of the node + * + * @note Precondition : idx should be a valid output index + * + * @param[in] idx Index of the node output + * + * @return TensorID of the requested output + */ + TensorID output_id(size_t idx) const; + /** Returns the tensor of a given input of the node + * + * @note Precondition : idx should be a valid input index + * + * @param[in] idx Index of the node input + * + * @return Tensor of the requested input + */ + Tensor *input(size_t idx) const; + /** Returns the tensor of a given output of the node + * + * @note Precondition : idx should be a valid output index + * + * @param[in] idx Index of the node output + * + * @return Tensor of the requested output + */ + Tensor *output(size_t idx) const; + /** Returns the edge ID of a given input of the node + * + * @note Precondition : idx should be a valid input index + * + * @param[in] idx Index of the node input + * + * @return EdgeID of the requested input + */ + EdgeID input_edge_id(size_t idx) const; + /** Returns the edge of a given input of the node + * + * @note Precondition : idx should be a valid input index + * + * @param[in] idx Index of the node input + * + * @return Edge of the requested input + */ + Edge *input_edge(size_t idx) const; + /** Returns number of inputs of the node + * + * @return Number of inputs + */ + size_t num_inputs() const; + /** Returns number of outputs of the node + * + * @return Number of outputs + */ + size_t num_outputs() const; + /** Returns requested target for this node + * + * @return Requested execution target + */ + Target requested_target() const; + /** Returns assigned target for this node + * + * @return Assigned target of this node + */ + Target assigned_target() const; + +protected: + friend class Graph; protected: - TargetHint _target_hint{ TargetHint::DONT_CARE }; - bool _supports_in_place{ false }; + Graph *_graph; /**< Backward reference to graph owning the node */ + NodeID _id; /**< Node ID */ + NodeParams _common_params; /**< Node common params */ + std::vector<TensorID> _outputs; /**< Output of the node */ + std::vector<EdgeID> _input_edges; /**< Inputs edge set */ + std::set<EdgeID> _output_edges; /**< Output edge set */ + Target _assigned_target; /**< Assigned target by the Graph executor */ }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/INodeVisitor.h b/arm_compute/graph/INodeVisitor.h new file mode 100644 index 0000000000..b5446c4a55 --- /dev/null +++ b/arm_compute/graph/INodeVisitor.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_INODEVISITOR_H__ +#define __ARM_COMPUTE_GRAPH_INODEVISITOR_H__ + +#include "arm_compute/graph/nodes/NodesFwd.h" + +namespace arm_compute +{ +namespace graph +{ +/** Node visitor interface */ +class INodeVisitor +{ +public: + /** Default destructor. */ + virtual ~INodeVisitor() = default; + /** Visit INode. + * + * @param[in] n Node to visit. + */ + virtual void visit(INode &n) = 0; + /** Visit ActivationLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(ActivationLayerNode &n) = 0; + /** Visit BatchNormalizationLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(BatchNormalizationLayerNode &n) = 0; + /** Visit ConstNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(ConstNode &n) = 0; + /** Visit ConvolutionLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(ConvolutionLayerNode &n) = 0; + /** Visit DepthConcatenateLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(DepthConcatenateLayerNode &n) = 0; + /** Visit DepthwiseConvolutionLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(DepthwiseConvolutionLayerNode &n) = 0; + /** Visit EltwiseLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(EltwiseLayerNode &n) = 0; + /** Visit FlattenLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(FlattenLayerNode &n) = 0; + /** Visit FullyConnectedLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(FullyConnectedLayerNode &n) = 0; + /** Visit InputNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(InputNode &n) = 0; + /** Visit NormalizationLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(NormalizationLayerNode &n) = 0; + /** Visit OutputNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(OutputNode &n) = 0; + /** Visit PoolingLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(PoolingLayerNode &n) = 0; + /** Visit ReshapeLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(ReshapeLayerNode &n) = 0; + /** Visit SoftmaxLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(SoftmaxLayerNode &n) = 0; + /** Visit SplitLayerNode. + * + * @param[in] n Node to visit. + */ + virtual void visit(SplitLayerNode &n) = 0; +}; + +/** Default visitor implementation + * + * Implements visit methods by calling a default function. + * Inherit from DefaultNodeVisitor if you don't want to provide specific implementation for all nodes. + */ +class DefaultNodeVisitor : public INodeVisitor +{ +public: + /** Default destructor */ + virtual ~DefaultNodeVisitor() = default; + +#ifndef DOXYGEN_SKIP_THIS + // Inherited methods overridden + virtual void visit(INode &n) override + { + default_visit(); + } + virtual void visit(ActivationLayerNode &n) override + { + default_visit(); + } + virtual void visit(BatchNormalizationLayerNode &n) override + { + default_visit(); + } + virtual void visit(ConstNode &n) override + { + default_visit(); + } + virtual void visit(ConvolutionLayerNode &n) override + { + default_visit(); + } + virtual void visit(DepthConcatenateLayerNode &n) override + { + default_visit(); + } + virtual void visit(DepthwiseConvolutionLayerNode &n) override + { + default_visit(); + } + virtual void visit(EltwiseLayerNode &n) override + { + default_visit(); + } + virtual void visit(FlattenLayerNode &n) override + { + default_visit(); + } + virtual void visit(FullyConnectedLayerNode &n) override + { + default_visit(); + } + virtual void visit(InputNode &n) override + { + default_visit(); + } + virtual void visit(NormalizationLayerNode &n) override + { + default_visit(); + } + virtual void visit(OutputNode &n) override + { + default_visit(); + } + virtual void visit(PoolingLayerNode &n) override + { + default_visit(); + } + virtual void visit(ReshapeLayerNode &n) override + { + default_visit(); + } + virtual void visit(SoftmaxLayerNode &n) override + { + default_visit(); + } + virtual void visit(SplitLayerNode &n) override + { + default_visit(); + } +#endif /* DOXYGEN_SKIP_THIS */ + + /** Function to be overloaded by the client and implement default behavior for the + * non-overloaded visitors + */ + virtual void default_visit() = 0; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_INODEVISITOR_H__ */ diff --git a/arm_compute/graph/IOperation.h b/arm_compute/graph/IOperation.h deleted file mode 100644 index b1afb21db7..0000000000 --- a/arm_compute/graph/IOperation.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_IOPERATION_H__ -#define __ARM_COMPUTE_GRAPH_IOPERATION_H__ - -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" - -#include <memory> - -namespace arm_compute -{ -namespace graph -{ -/** Operation functor interface */ -class IOperation -{ -public: - /** Virtual Destructor */ - virtual ~IOperation() = default; - /** Interface to be implemented that configures an operation - * - * @param[in] ctx Node parameters to be used by the operation - * - * @return a pointer to the function which implements the operation. - */ - virtual std::unique_ptr<arm_compute::IFunction> configure(NodeContext &ctx) = 0; - /** Interface to be implemented that returns the target of the operation - * - * @return Target of the operation - */ - virtual TargetHint target() const = 0; -}; - -#define REGISTER_SIMPLE_OPERATION(NAME, TARGET, OP) \ - class NAME : public IOperation \ - { \ - public: \ - std::unique_ptr<arm_compute::IFunction> configure(NodeContext &ctx) final; \ - TargetHint target() const final \ - { \ - return TargetHint::TARGET; \ - } \ - }; \ - static detail::OperationRegistrar<NAME> NAME##_registrar(OP); \ - std::unique_ptr<arm_compute::IFunction> NAME::configure(NodeContext &ctx) - -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_IOPERATION_H__ */ diff --git a/arm_compute/graph/ITensorAccessor.h b/arm_compute/graph/ITensorAccessor.h index d6a254ab73..2df39c29e1 100644 --- a/arm_compute/graph/ITensorAccessor.h +++ b/arm_compute/graph/ITensorAccessor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,10 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_ITENSORACCESSOR_H__ -#define __ARM_COMPUTE_GRAPH_ITENSORACCESSOR_H__ +#ifndef __ARM_COMPUTE_GRAPH_ITENSOR_ACCESSOR_H__ +#define __ARM_COMPUTE_GRAPH_ITENSOR_ACCESSOR_H__ -#include "arm_compute/graph/Types.h" +#include "arm_compute/core/ITensor.h" + +#include <memory> namespace arm_compute { @@ -44,6 +46,8 @@ public: */ virtual bool access_tensor(ITensor &tensor) = 0; }; + +using ITensorAccessorUPtr = std::unique_ptr<ITensorAccessor>; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_ITENSORACCESSOR_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_SUB_STREAM_H__ */
\ No newline at end of file diff --git a/arm_compute/graph/ITensorHandle.h b/arm_compute/graph/ITensorHandle.h new file mode 100644 index 0000000000..cc7132e316 --- /dev/null +++ b/arm_compute/graph/ITensorHandle.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_ITENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_ITENSORHANDLE_H__ + +#include "arm_compute/core/ITensor.h" + +namespace arm_compute +{ +namespace graph +{ +/** Tensor handle interface object */ +class ITensorHandle +{ +public: + /** Default virtual destructor */ + virtual ~ITensorHandle() = default; + /** Allocates backend memory for the handle */ + virtual void allocate() = 0; + /** Backend tensor object accessor */ + virtual arm_compute::ITensor &tensor() = 0; + /** Backend tensor object const accessor */ + virtual const arm_compute::ITensor &tensor() const = 0; + /** Maps backend tensor object + * + * @param[in] blocking Flags if the mapping operations should be blocking + */ + virtual void map(bool blocking) = 0; + /** Un-maps a backend tensor object */ + virtual void unmap() = 0; + /** Releases backend tensor if is marked as unused + * + * + * @note This has no effect on sub-tensors + * @warning Parent tensors don't keep track of sub-tensors, + * thus if a parent is set as unused then all sub-tensors will be invalidated, + * on the other hand if a sub-tensor is marked as unused then the parent tensor won't be released + */ + virtual void release_if_unused() = 0; + /** Checks if a backing tensor is a sub-tensor object or not + * + * @return True if the backend tensor is a sub-tensor else false + */ + virtual bool is_subtensor() const = 0; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_ITENSORHANDLE_H__ */ diff --git a/arm_compute/graph/ITensorObject.h b/arm_compute/graph/ITensorObject.h deleted file mode 100644 index 1b6f929305..0000000000 --- a/arm_compute/graph/ITensorObject.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_ITENSOROBJECT_H__ -#define __ARM_COMPUTE_GRAPH_ITENSOROBJECT_H__ - -#include "arm_compute/graph/ITensorAccessor.h" -#include "arm_compute/graph/Types.h" -#include "support/ToolchainSupport.h" - -#include <memory> - -namespace arm_compute -{ -namespace graph -{ -/** Tensor object interface */ -class ITensorObject -{ -public: - /** Default Destructor */ - virtual ~ITensorObject() = default; - /** Calls accessor on tensor - * - * @return True if succeeds else false - */ - virtual bool call_accessor() = 0; - /** Checks if tensor has an accessor set. - * - * @return True if an accessor has been set else false - */ - virtual bool has_accessor() const = 0; - /** Sets target of the tensor - * - * @param[in] target Target where the tensor should be pinned in - * - * @return Backend tensor - */ - virtual ITensor *set_target(TargetHint target) = 0; - /** Returns a pointer to the internal tensor - * - * @return Tensor - */ - virtual ITensor *tensor() = 0; - /** Returns a pointer to the internal tensor - * - * @return const Tensor - */ - virtual const ITensor *tensor() const = 0; - /** Return the target that this tensor is pinned on - * - * @return Target of the tensor - */ - virtual TargetHint target() const = 0; - /** Allocates the tensor */ - virtual void allocate() = 0; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_ITENSOROBJECT_H__ */ diff --git a/arm_compute/graph/Logger.h b/arm_compute/graph/Logger.h new file mode 100644 index 0000000000..8b87f47b3d --- /dev/null +++ b/arm_compute/graph/Logger.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_LOGGER_H__ +#define __ARM_COMPUTE_GRAPH_LOGGER_H__ + +#include "arm_compute/core/utils/logging/Macros.h" + +/** Create a default core logger + * + * @note It will eventually create all default loggers in don't exist + */ +#define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER() \ + do \ + { \ + if(arm_compute::logging::LoggerRegistry::get().logger("GRAPH") == nullptr) \ + { \ + arm_compute::logging::LoggerRegistry::get().create_reserved_loggers(); \ + } \ + } while(false) + +#define ARM_COMPUTE_LOG_GRAPH(log_level, x) \ + ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ + ARM_COMPUTE_LOG_STREAM("GRAPH", log_level, x) + +#define ARM_COMPUTE_LOG_GRAPH_VERBOSE(x) \ + ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ + ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::VERBOSE, x) + +#define ARM_COMPUTE_LOG_GRAPH_INFO(x) \ + ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ + ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::INFO, x) + +#define ARM_COMPUTE_LOG_GRAPH_WARNING(x) \ + ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ + ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::WARN, x) + +#define ARM_COMPUTE_LOG_GRAPH_ERROR(x) \ + ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ + ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::ERROR, x) + +#endif /* __ARM_COMPUTE_GRAPH_LOGGER_H__ */ diff --git a/arm_compute/graph/NodeContext.h b/arm_compute/graph/NodeContext.h deleted file mode 100644 index 17ae49740b..0000000000 --- a/arm_compute/graph/NodeContext.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_NODE_CONTEXT_H__ -#define __ARM_COMPUTE_GRAPH_NODE_CONTEXT_H__ - -#include "arm_compute/core/Error.h" -#include "arm_compute/graph/NodeParameter.h" -#include "arm_compute/graph/Types.h" -#include "support/ToolchainSupport.h" - -#include <map> -#include <memory> -#include <string> - -namespace arm_compute -{ -namespace graph -{ -/** Node Context class - * - * Node context class is used to hold all the parameters required by a node to execute - */ -class NodeContext -{ -public: - /** Default Constructor - * - * @param[in] operation Name of the operation - */ - NodeContext(OperationType operation) - : _operation(operation), _target(TargetHint::DONT_CARE), _inputs(), _outputs(), _parameters() {}; - /** Sets the execution target of the node - * - * @param[in] target Execution target of the node - */ - void set_target(TargetHint target); - /** Adds an input tensor to the context - * - * @param[in] input Input to add - */ - void add_input(arm_compute::ITensor *input); - /** Adds an output to the context - * - * @param[in] output Output to add - */ - void add_output(arm_compute::ITensor *output); - /** Adds a parameter to the context - * - * @param[in] name Parameter name - * @param[in] parameter Parameter to add - */ - template <typename T> - void add_parameter(std::string name, T parameter); - /** Returns the operation of this node. - * - * @return The operation type - */ - OperationType operation() const; - /** Returns the execution target of this node - * - * @return The execution target - */ - TargetHint target() const; - /** Returns input tensor of a given index - * - * @param[in] idx Index of the input tensor - * - * @return A pointer the requested input tensor else nullptr - */ - arm_compute::ITensor *input(size_t idx) const; - /** Returns output tensor of a given index - * - * @param[in] idx Index of the output tensor - * - * @return A pointer the requested output tensor else nullptr - */ - arm_compute::ITensor *output(size_t idx) const; - /** Returns the parameter with the given name - * - * @param[in] name Parameter name - * - * @return The requested parameter else an empty object - */ - template <typename T> - T parameter(std::string name) const; - /** Returns number of inputs - * - * @return Number of inputs - */ - size_t num_inputs() const; - /** Returns number of output - * - * @return Number of outputs - */ - size_t num_outputs() const; - -private: - OperationType _operation; - TargetHint _target; - std::vector<arm_compute::ITensor *> _inputs; - std::vector<arm_compute::ITensor *> _outputs; - std::map<std::string, std::unique_ptr<NodeParameterBase>> _parameters; -}; - -template <typename T> -inline void NodeContext::add_parameter(std::string name, T parameter) -{ - ARM_COMPUTE_ERROR_ON_MSG(_parameters.find(name) != _parameters.end(), "Parameter already exists!"); - _parameters[name] = support::cpp14::make_unique<NodeParameter<T>>(name, parameter); -} - -template <typename T> -inline T NodeContext::parameter(std::string name) const -{ - auto it = _parameters.find(name); - ARM_COMPUTE_ERROR_ON(it == _parameters.end()); - return static_cast<NodeParameter<T> *>(it->second.get())->value(); -} -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_NODE_CONTEXT_H__ */ diff --git a/arm_compute/graph/PassManager.h b/arm_compute/graph/PassManager.h new file mode 100644 index 0000000000..9f32a458d0 --- /dev/null +++ b/arm_compute/graph/PassManager.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_PASSMANAGER_H__ +#define __ARM_COMPUTE_GRAPH_PASSMANAGER_H__ + +#include "arm_compute/graph/IGraphMutator.h" + +#include <memory> +#include <vector> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; + +/** Pass manager + * + * Responsible for performing the mutating graph passes with a given order + **/ +class PassManager final +{ +public: + /** Constructor */ + PassManager(); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + PassManager(const PassManager &) = delete; + /** Default move constructor */ + PassManager(PassManager &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + PassManager &operator=(const PassManager &) = delete; + /** Default move assignment operator */ + PassManager &operator=(PassManager &&) = default; + /** Mutation passes accessors + * + * @return Returns the vector with the mutation passes that are to be executed on a graph + */ + const std::vector<std::unique_ptr<IGraphMutator>> &passes() const; + /** Accessor of a pass at a given index + * + * @param[in] index Index of the requested pass + * + * @return A pointer to the given pass if exists else nullptr + */ + IGraphMutator *pass(size_t index); + /** Appends a mutation pass + * + * @param[in] pass Pass to append + */ + void append(std::unique_ptr<IGraphMutator> pass); + /** Clears all the passes */ + void clear(); + /** Runs all the mutation passes on a given graph + * + * @param[in] g Graph to run the mutations on + */ + void run_all(Graph &g); + /** Runs a specific mutation pass on a given graph + * + * @param[in] g Graph to run the mutation on + * @param[in] index Index of the mutation to execute + */ + void run(Graph &g, size_t index); + +private: + std::vector<std::unique_ptr<IGraphMutator>> _passes; /**< Vector of graph passes */ +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_PASSMANAGER_H__ */ diff --git a/arm_compute/graph/SubGraph.h b/arm_compute/graph/SubGraph.h deleted file mode 100644 index e3217e7095..0000000000 --- a/arm_compute/graph/SubGraph.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_SUBGRAPH_H__ -#define __ARM_COMPUTE_GRAPH_SUBGRAPH_H__ - -#include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/SubTensor.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" - -#include <memory> - -namespace arm_compute -{ -namespace graph -{ -/** SubGraph class */ -class SubGraph -{ -public: - /** Constructor */ - SubGraph(); - /** Adds a node to the graph - * - * @param[in] node Node to add - */ - void add_node(std::unique_ptr<INode> node); - /** Adds a tensor to the graph - * - * @param[in] tensor Tensor to add - */ - void add_tensor_object(std::unique_ptr<ITensorObject> tensor); - /** Constructs a graph from a subgraph - * - * @param[in] ctx Parent graph context - * @param[in] input Input to the graph - * @param[in] output Output to the graph - * - * @return A graph - */ - std::unique_ptr<Graph> construct(const GraphContext &ctx, std::unique_ptr<ITensorObject> input, std::unique_ptr<ITensorObject> output); - /** Checks if the subgraph has an input - * - * @return True if the sub-graph has an input else false - */ - bool has_input() const; - /** Checks if the subgraph has an output - * - * @return True if the sub-graph has an output else false - */ - bool has_output() const; - -private: - std::vector<std::unique_ptr<INode>> _nodes; - std::unique_ptr<ITensorObject> _input; - std::unique_ptr<ITensorObject> _output; -}; - -SubGraph &operator<<(SubGraph &graph, Tensor &&tensor); -SubGraph &operator<<(SubGraph &graph, SubTensor &&sub_tensor); - -template <typename Node> -SubGraph &operator<<(SubGraph &sub_graph, Node node) -{ - sub_graph.add_node(arm_compute::support::cpp14::make_unique<Node>(std::move(node))); - return sub_graph; -} -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_INODE_H__ */ diff --git a/arm_compute/graph/SubTensor.h b/arm_compute/graph/SubTensor.h deleted file mode 100644 index 43b835d49c..0000000000 --- a/arm_compute/graph/SubTensor.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_SUBTENSOR_H__ -#define __ARM_COMPUTE_GRAPH_SUBTENSOR_H__ - -#include "arm_compute/graph/ITensorAccessor.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" -#include "support/ToolchainSupport.h" - -#include <memory> - -namespace arm_compute -{ -namespace graph -{ -/** SubTensor class */ -class SubTensor final : public ITensorObject -{ -public: - /** Default Constructor */ - SubTensor(); - /** Constructor - * - * @param[in] parent Parent to create sub-tensor from - * @param[in] tensor_shape Sub-tensor shape - * @param[in] coords Starting coordinates of the sub-tensor in the parent tensor - * @param[in] extend_parent (Optional) Extend parent with subtensor shape if subtensor indexes out of bounds - */ - SubTensor(Tensor &parent, TensorShape tensor_shape, Coordinates coords, bool extend_parent = false); - /** Constructor - * - * @param[in] parent Parent to create sub-tensor from - * @param[in] tensor_shape Sub-tensor shape - * @param[in] coords Starting coordinates of the sub-tensor in the parent tensor - * @param[in] target Execution target - * @param[in] extend_parent (Optional) Extend parent with subtensor shape if subtensor indexes out of bounds - */ - SubTensor(arm_compute::ITensor *parent, TensorShape tensor_shape, Coordinates coords, TargetHint target, bool extend_parent = false); - /** Prevent instances of this class from being copied (As this class contains pointers) */ - SubTensor(const SubTensor &) = delete; - /** Prevent instances of this class from being copied (As this class contains pointers) */ - SubTensor &operator=(const SubTensor &) = delete; - /** Allow instances of this class to be moved */ - SubTensor(SubTensor &&) = default; - /** Allow instances of this class to be moved */ - SubTensor &operator=(SubTensor &&) = default; - /** Default Destructor */ - ~SubTensor() = default; - - // Inherited methods overriden: - bool call_accessor() override; - bool has_accessor() const override; - arm_compute::ITensor *set_target(TargetHint target) override; - arm_compute::ITensor *tensor() override; - const arm_compute::ITensor *tensor() const override; - TargetHint target() const override; - void allocate() override; - -private: - /** Instantiates a sub-tensor */ - void instantiate_subtensor(); - -private: - TargetHint _target; /**< Target that this tensor is pinned on */ - TensorShape _tensor_shape; /**< SubTensor shape */ - Coordinates _coords; /**< SubTensor Coordinates */ - arm_compute::ITensor *_parent; /**< Parent tensor */ - std::unique_ptr<arm_compute::ITensor> _subtensor; /**< SubTensor */ - bool _extend_parent; /**< Parent extension flag */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_SUBTENSOR_H__ */ diff --git a/arm_compute/graph/Tensor.h b/arm_compute/graph/Tensor.h index e5821dc812..5199ac2328 100644 --- a/arm_compute/graph/Tensor.h +++ b/arm_compute/graph/Tensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -24,99 +24,91 @@ #ifndef __ARM_COMPUTE_GRAPH_TENSOR_H__ #define __ARM_COMPUTE_GRAPH_TENSOR_H__ -#include "arm_compute/graph/ITensorAccessor.h" -#include "arm_compute/graph/ITensorObject.h" #include "arm_compute/graph/Types.h" -#include "support/ToolchainSupport.h" + +#include "arm_compute/graph/ITensorAccessor.h" +#include "arm_compute/graph/ITensorHandle.h" +#include "arm_compute/graph/TensorDescriptor.h" #include <memory> +#include <set> namespace arm_compute { namespace graph { -/** Tensor class */ -class Tensor final : public ITensorObject +/** Tensor object **/ +class Tensor final { public: - /** Constructor + /** Default constructor * - * @param[in] info Tensor info to use + * @param[in] id Tensor ID + * @param[in] desc Tensor information */ - Tensor(TensorInfo &&info); - /** Constructor + Tensor(TensorID id, TensorDescriptor desc); + /** Tensor ID accessor * - * @param[in] accessor Tensor accessor + * @return Tensor ID */ - template <typename AccessorType> - Tensor(std::unique_ptr<AccessorType> accessor) - : _target(TargetHint::DONT_CARE), _info(), _accessor(std::move(accessor)), _tensor(nullptr) - { - } - /** Constructor + TensorID id() const; + /** TensorInfo metadata accessor * - * @param[in] accessor Tensor accessor + * @return Tensor descriptor metadata */ - template <typename AccessorType> - Tensor(AccessorType &&accessor) - : _target(TargetHint::DONT_CARE), _info(), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr) - { - } - /** Constructor + TensorDescriptor &desc(); + /** TensorInfo metadata accessor * - * @param[in] info Tensor info to use - * @param[in] accessor Tensor accessor + * @return Tensor descriptor metadata */ - template <typename AccessorType> - Tensor(TensorInfo &&info, std::unique_ptr<AccessorType> &&accessor) - : _target(TargetHint::DONT_CARE), _info(info), _accessor(std::move(accessor)), _tensor(nullptr) - { - } - /** Constructor + const TensorDescriptor &desc() const; + /** Sets the backend tensor * - * @param[in] info Tensor info to use - * @param[in] accessor Tensor accessor + * @param[in] backend_tensor Backend tensor to set */ - template <typename AccessorType> - Tensor(TensorInfo &&info, AccessorType &&accessor) - : _target(TargetHint::DONT_CARE), _info(info), _accessor(arm_compute::support::cpp14::make_unique<AccessorType>(std::forward<AccessorType>(accessor))), _tensor(nullptr) - { - } - /** Default Destructor */ - ~Tensor() = default; - /** Move Constructor + void set_handle(std::unique_ptr<ITensorHandle> backend_tensor); + /** Backend tensor handle accessor * - * @param[in] src Tensor to move + * @return Backend tensor handle */ - Tensor(Tensor &&src) noexcept; - - /** Sets the given TensorInfo to the tensor + ITensorHandle *handle(); + /** Sets the backend tensor accessor * - * @param[in] info TensorInfo to set + * @param[in] accessor Accessor to set */ - void set_info(TensorInfo &&info); - /** Returns tensor's TensorInfo + void set_accessor(std::unique_ptr<ITensorAccessor> accessor); + /** Backend tensor accessor * - * @return TensorInfo of the tensor + * @return Backend tensor accessor */ - const TensorInfo &info() const; - /** Allocates and fills the tensor if needed */ - void allocate_and_fill_if_needed(); - - // Inherited methods overriden: - bool call_accessor() override; - bool has_accessor() const override; - arm_compute::ITensor *set_target(TargetHint target) override; - arm_compute::ITensor *tensor() override; - const arm_compute::ITensor *tensor() const override; - TargetHint target() const override; - void allocate() override; + ITensorAccessor *accessor(); + /** Calls accessor on tensor + * + * @return True if the accessor was called else false + */ + bool call_accessor(); + /** Binds the tensor with an edge + * + * @param[in] eid Edge ID that is bound to the tensor + */ + void bind_edge(EdgeID eid); + /** Unbinds an edge from a tensor + * + * @param[in] eid Edge to unbind + */ + void unbind_edge(EdgeID eid); + /** Accessor the edges that are bound with the tensor + * + * @return Bound edges + */ + const std::set<EdgeID> bound_edges() const; private: - TargetHint _target; /**< Target that this tensor is pinned on */ - TensorInfo _info; /**< Tensor metadata */ - std::unique_ptr<ITensorAccessor> _accessor; /**< Tensor Accessor */ - std::unique_ptr<arm_compute::ITensor> _tensor; /**< Tensor */ + TensorID _id; /**< Tensor id */ + TensorDescriptor _desc; /**< Tensor metadata */ + std::unique_ptr<ITensorHandle> _handle; /**< Tensor Handle */ + std::unique_ptr<ITensorAccessor> _accessor; /**< Tensor Accessor */ + std::set<EdgeID> _bound_edges; /**< Edges bound to this tensor */ }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/CL/CLUnmap.h b/arm_compute/graph/TensorDescriptor.h index 17745c436b..fc0095e3b9 100644 --- a/arm_compute/graph/CL/CLUnmap.h +++ b/arm_compute/graph/TensorDescriptor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,43 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_CLUNMAP_H__ -#define __ARM_COMPUTE_GRAPH_CLUNMAP_H__ +#ifndef __ARM_COMPUTE_GRAPH_TENSOR_DESCRIPTOR_H__ +#define __ARM_COMPUTE_GRAPH_TENSOR_DESCRIPTOR_H__ #include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" namespace arm_compute { -class ICLTensor; - namespace graph { -class ITensorObject; -/** OpenCL un-map function */ -class CLUnmap : public arm_compute::IFunction +/** Tensor metadata class */ +struct TensorDescriptor final { -public: + /** Default Constructor **/ + TensorDescriptor() = default; /** Constructor * - * @param[in] tensor Tensor to un-map + * @param[in] tensor_shape Tensor shape + * @param[in] tensor_data_type Tensor data type + * @param[in] tensor_target Target to allocate the tensor for */ - CLUnmap(ITensorObject *tensor); - /** Prevent instances from being copy constructed */ - CLUnmap(const CLUnmap &) = delete; - /** Prevent instances from being copy assigned */ - const CLUnmap &operator=(const CLUnmap &) = delete; - /** Allow instances to be move constructed */ - CLUnmap(CLUnmap &&) = default; - /** Allow instances to be move assigned */ - CLUnmap &operator=(CLUnmap &&) = default; - - // Inherited methods overriden: - void run() override; + TensorDescriptor(TensorShape tensor_shape, DataType tensor_data_type, Target tensor_target = Target::UNSPECIFIED) + : shape(tensor_shape), data_type(tensor_data_type), target(tensor_target) + { + } -private: - arm_compute::ICLTensor *_tensor; /**< Tensor */ + TensorShape shape{}; /**< Tensor shape */ + DataType data_type{ DataType::UNKNOWN }; /**< Data type */ + Target target{ Target::UNSPECIFIED }; /**< Target */ }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_CLUNMAP_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_TENSOR_DESCRIPTOR_H__ */ diff --git a/arm_compute/graph/TypePrinter.h b/arm_compute/graph/TypePrinter.h new file mode 100644 index 0000000000..d9bc8376bd --- /dev/null +++ b/arm_compute/graph/TypePrinter.h @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_TYPE_PRINTER_H__ +#define __ARM_COMPUTE_GRAPH_TYPE_PRINTER_H__ + +#include "arm_compute/core/Error.h" +#include "arm_compute/core/Types.h" +#include "arm_compute/graph/Types.h" + +namespace arm_compute +{ +namespace graph +{ +/** Formatted output of the Dimensions type. */ +template <typename T> +inline ::std::ostream &operator<<(::std::ostream &os, const arm_compute::Dimensions<T> &dimensions) +{ + if(dimensions.num_dimensions() > 0) + { + os << dimensions[0]; + + for(unsigned int d = 1; d < dimensions.num_dimensions(); ++d) + { + os << "x" << dimensions[d]; + } + } + + return os; +} + +/** Formatted output of the Size2D type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const Size2D &size) +{ + os << size.width << "x" << size.height; + + return os; +} + +/** Formatted output of the DataType type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const DataType &data_type) +{ + switch(data_type) + { + case DataType::UNKNOWN: + os << "UNKNOWN"; + break; + case DataType::U8: + os << "U8"; + break; + case DataType::QS8: + os << "QS8"; + break; + case DataType::QASYMM8: + os << "QASYMM8"; + break; + case DataType::S8: + os << "S8"; + break; + case DataType::U16: + os << "U16"; + break; + case DataType::S16: + os << "S16"; + break; + case DataType::QS16: + os << "QS16"; + break; + case DataType::U32: + os << "U32"; + break; + case DataType::S32: + os << "S32"; + break; + case DataType::U64: + os << "U64"; + break; + case DataType::S64: + os << "S64"; + break; + case DataType::F16: + os << "F16"; + break; + case DataType::F32: + os << "F32"; + break; + case DataType::F64: + os << "F64"; + break; + case DataType::SIZET: + os << "SIZET"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the Target. */ +inline ::std::ostream &operator<<(::std::ostream &os, const Target &target) +{ + switch(target) + { + case Target::UNSPECIFIED: + os << "UNSPECIFIED"; + break; + case Target::NEON: + os << "NEON"; + break; + case Target::CL: + os << "CL"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the activation function type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const ActivationLayerInfo::ActivationFunction &act_function) +{ + switch(act_function) + { + case ActivationLayerInfo::ActivationFunction::ABS: + os << "ABS"; + break; + case ActivationLayerInfo::ActivationFunction::LINEAR: + os << "LINEAR"; + break; + case ActivationLayerInfo::ActivationFunction::LOGISTIC: + os << "LOGISTIC"; + break; + case ActivationLayerInfo::ActivationFunction::RELU: + os << "RELU"; + break; + case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU: + os << "BOUNDED_RELU"; + break; + case ActivationLayerInfo::ActivationFunction::LEAKY_RELU: + os << "LEAKY_RELU"; + break; + case ActivationLayerInfo::ActivationFunction::SOFT_RELU: + os << "SOFT_RELU"; + break; + case ActivationLayerInfo::ActivationFunction::SQRT: + os << "SQRT"; + break; + case ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU: + os << "LU_BOUNDED_RELU"; + break; + case ActivationLayerInfo::ActivationFunction::SQUARE: + os << "SQUARE"; + break; + case ActivationLayerInfo::ActivationFunction::TANH: + os << "TANH"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +inline std::string to_string(const ActivationLayerInfo::ActivationFunction &act_function) +{ + std::stringstream str; + str << act_function; + return str.str(); +} + +/** Formatted output of the PoolingType type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const PoolingType &pool_type) +{ + switch(pool_type) + { + case PoolingType::AVG: + os << "AVG"; + break; + case PoolingType::MAX: + os << "MAX"; + break; + case PoolingType::L2: + os << "L2"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the NormType type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const NormType &norm_type) +{ + switch(norm_type) + { + case NormType::CROSS_MAP: + os << "CROSS_MAP"; + break; + case NormType::IN_MAP_1D: + os << "IN_MAP_1D"; + break; + case NormType::IN_MAP_2D: + os << "IN_MAP_2D"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the EltwiseOperation type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const EltwiseOperation &eltwise_op) +{ + switch(eltwise_op) + { + case EltwiseOperation::ADD: + os << "ADD"; + break; + case EltwiseOperation::MUL: + os << "MUL"; + break; + case EltwiseOperation::SUB: + os << "SUB"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the ConvolutionMethod type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethod &method) +{ + switch(method) + { + case ConvolutionMethod::DEFAULT: + os << "DEFAULT"; + break; + case ConvolutionMethod::DIRECT: + os << "DIRECT"; + break; + case ConvolutionMethod::GEMM: + os << "GEMM"; + break; + case ConvolutionMethod::WINOGRAD: + os << "WINOGRAD"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the DepthwiseConvolutionMethod type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const DepthwiseConvolutionMethod &method) +{ + switch(method) + { + case DepthwiseConvolutionMethod::DEFAULT: + os << "DEFAULT"; + break; + case DepthwiseConvolutionMethod::GEMV: + os << "GEMV"; + break; + case DepthwiseConvolutionMethod::OPTIMIZED_3x3: + os << "OPTIMIZED_3x3"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +/** Formatted output of the PadStrideInfo type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const PadStrideInfo &pad_stride_info) +{ + os << pad_stride_info.stride().first << "," << pad_stride_info.stride().second; + os << ";"; + os << pad_stride_info.pad_left() << "," << pad_stride_info.pad_right() << "," + << pad_stride_info.pad_top() << "," << pad_stride_info.pad_bottom(); + + return os; +} +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_TYPE_PRINTER_H__ */ diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h index db5bbb8604..00d37a3354 100644 --- a/arm_compute/graph/Types.h +++ b/arm_compute/graph/Types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -24,96 +24,148 @@ #ifndef __ARM_COMPUTE_GRAPH_TYPES_H__ #define __ARM_COMPUTE_GRAPH_TYPES_H__ -#include "arm_compute/core/ITensor.h" -#include "arm_compute/core/SubTensorInfo.h" -#include "arm_compute/core/TensorInfo.h" -#include "arm_compute/core/utils/logging/Macros.h" +#include "arm_compute/core/Error.h" +#include "arm_compute/core/Types.h" +#include "arm_compute/core/utils/strong_type/StrongType.h" +#include "arm_compute/core/utils/strong_type/StrongTypeAttributes.h" -/** Create a default core logger - * - * @note It will eventually create all default loggers in don't exist - */ -#define ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER() \ - do \ - { \ - if(arm_compute::logging::LoggerRegistry::get().logger("GRAPH") == nullptr) \ - { \ - arm_compute::logging::LoggerRegistry::get().create_reserved_loggers(); \ - } \ - } while(false) - -#define ARM_COMPUTE_LOG_GRAPH(log_level, x) \ - ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ - ARM_COMPUTE_LOG_STREAM("GRAPH", log_level, x) - -#define ARM_COMPUTE_LOG_GRAPH_INFO(x) \ - ARM_COMPUTE_CREATE_DEFAULT_GRAPH_LOGGER(); \ - ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::INFO, x) +#include <limits> +#include <string> namespace arm_compute { namespace graph { -using arm_compute::ActivationLayerInfo; +using arm_compute::Status; + using arm_compute::Coordinates; using arm_compute::DataType; -using arm_compute::DimensionRoundingType; -using arm_compute::ITensorInfo; +using arm_compute::TensorShape; +using arm_compute::Size2D; + +using arm_compute::ActivationLayerInfo; using arm_compute::NormType; using arm_compute::NormalizationLayerInfo; using arm_compute::PadStrideInfo; using arm_compute::PoolingLayerInfo; using arm_compute::PoolingType; -using arm_compute::SubTensorInfo; -using arm_compute::TensorInfo; -using arm_compute::TensorShape; -using arm_compute::WeightsInfo; +using arm_compute::DimensionRoundingType; + +/** TODO (geopin01): Make ids strongly typed */ +using TensorID = unsigned int; +using NodeID = unsigned int; +using EdgeID = unsigned int; +using Activation = arm_compute::ActivationLayerInfo::ActivationFunction; + +/**< GraphID strong type */ +using GraphID = strong_type::StrongType<unsigned int, struct graph_id_t, strong_type::Comparable>; +/* TODO (geopin01): Strong types for NodeID */ + +/**< Constant TensorID specifying an equivalent of null tensor */ +constexpr TensorID NullTensorID = std::numeric_limits<TensorID>::max(); +/**< Constant NodeID specifying an equivalent of null node */ +constexpr NodeID EmptyNodeID = std::numeric_limits<NodeID>::max(); +/**< Constant EdgeID specifying an equivalent of null edge */ +constexpr EdgeID EmptyEdgeID = std::numeric_limits<EdgeID>::max(); + +// Forward declarations +class TensorDescriptor; + +/** Graph configuration structure */ +struct GraphConfig +{ + bool use_function_memory_manager{ false }; /**< Use a memory manager to manage per-funcion auxilary memory */ + bool use_transition_memory_manager{ false }; /**< Use a memory manager to manager transition buffer memory */ + bool use_tuner{ false }; /**< Use a tuner in tunable backends */ + unsigned int num_threads{ 0 }; /**< Number of threads to use (thread capable backends), if 0 the backend will auto-initialize */ +}; -using arm_compute::logging::LogLevel; -using arm_compute::ConvertPolicy; +/**< Data layout format */ +enum class DataLayout +{ + NCHW, /** N(Batches), C(Channels), H(Height), W(Width) from slow to fast moving dimension */ + NHWC /** N(Batches), H(Height), W(Width), C(Channels) from slow to fast moving dimension */ +}; + +/**< Device target types */ +enum class Target +{ + UNSPECIFIED, /**< Unspecified Target */ + NEON, /**< NEON capable target device */ + CL, /**< OpenCL capable target device */ + GC, /**< GLES compute capable target device */ +}; -/**< Execution hint to the graph executor */ -enum class TargetHint +/** Supported Element-wise operations */ +enum class EltwiseOperation { - DONT_CARE, /**< Run node in any device */ - OPENCL, /**< Run node on an OpenCL capable device (GPU) */ - NEON /**< Run node on a NEON capable device */ + ADD, /**< Arithmetic addition */ + SUB, /**< Arithmetic subtraction */ + MUL /**< Arithmetic multiplication */ }; -/** Convolution method hint to the graph executor */ -enum class ConvolutionMethodHint +/** Supported Convolution layer methods */ +enum class ConvolutionMethod { - GEMM, /**< Convolution using GEMM */ - DIRECT, /**< Direct convolution */ - WINOGRAD /**< Winograd convolution */ + DEFAULT, /**< Default approach using internal heuristics */ + GEMM, /**< GEMM based convolution */ + DIRECT, /**< Deep direct convolution */ + WINOGRAD /**< Winograd based convolution */ }; -/** Supported layer operations */ -enum class OperationType +/** Supported Depthwise Convolution layer methods */ +enum class DepthwiseConvolutionMethod +{ + DEFAULT, /**< Default approach using internal heuristics */ + GEMV, /**< Generic GEMV based depthwise convolution */ + OPTIMIZED_3x3, /**< Optimized 3x3 direct depthwise convolution */ +}; + +/** Supported nodes */ +enum class NodeType { ActivationLayer, - ArithmeticAddition, BatchNormalizationLayer, ConvolutionLayer, - DepthConvertLayer, + DepthConcatenateLayer, DepthwiseConvolutionLayer, - DequantizationLayer, + EltwiseLayer, FlattenLayer, - FloorLayer, FullyConnectedLayer, - L2NormalizeLayer, NormalizationLayer, PoolingLayer, - QuantizationLayer, ReshapeLayer, - SoftmaxLayer + SoftmaxLayer, + SplitLayer, + + Input, + Output, + Const, +}; + +/** Backend Memory Manager affinity **/ +enum class MemoryManagerAffinity +{ + Buffer, /**< Affinity at buffer level */ + Offset /**< Affinity at offset level */ +}; + +/** NodeID-index struct + * + * Used to describe connections + */ +struct NodeIdxPair +{ + NodeID node_id; /**< Node ID */ + size_t index; /**< Index */ }; -/** Branch layer merging method */ -enum class BranchMergeMethod +/** Common node parameters */ +struct NodeParams { - DEPTH_CONCATENATE /**< Concatenate across depth */ + std::string name; /**< Node name */ + Target target; /**< Node target */ }; } // namespace graph } // namespace arm_compute -#endif /*__ARM_COMPUTE_GRAPH_TYPES_H__*/ +#endif /* __ARM_COMPUTE_GRAPH_TYPES_H__ */ diff --git a/arm_compute/graph/Utils.h b/arm_compute/graph/Utils.h new file mode 100644 index 0000000000..83deb70348 --- /dev/null +++ b/arm_compute/graph/Utils.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_UTILS_H__ +#define __ARM_COMPUTE_GRAPH_UTILS_H__ + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/PassManager.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward Declaration +class GraphContext; + +/** Returns the tensor descriptor of a given tensor + * + * @param[in] g Graph that the tensor belongs to + * @param[in] tid Tensor ID + * + * @return Tensor descriptor if tensor was found else empty descriptor + */ +inline TensorDescriptor get_tensor_descriptor(const Graph &g, TensorID tid) +{ + const Tensor *tensor = g.tensor(tid); + return (tensor != nullptr) ? tensor->desc() : TensorDescriptor(); +} +/** Sets an accessor on a given tensor + * + * @param[in] tensor Tensor to set the accessor to + * @param[in] accessor Accessor to set + * + * @return True if accessor was set else false + */ +inline Status set_tensor_accessor(Tensor *tensor, std::unique_ptr<ITensorAccessor> accessor) +{ + ARM_COMPUTE_RETURN_ERROR_ON(tensor == nullptr); + tensor->set_accessor(std::move(accessor)); + + return Status{}; +} +/** Checks if a specific target is supported + * + * @param[in] target Target to check + * + * @return True if target is support else false + */ +bool is_target_supported(Target target); +/** Returns default target for execution + * + * @note If an OpenCL backend exists then OpenCL is returned, + * else if the NEON backend exists returns NEON as target. + * If no backends are registered an error is raised. + * + * @return Default target + */ +Target get_default_target(); +/** Forces a single target to all graph constructs + * + * @param[in] g Graph to force target on + * @param[in] target Target to force + */ +void force_target_to_graph(Graph &g, Target target); +/** Creates a default @ref PassManager + * + * @param[in] target Target to create the pass manager for + * + * @return A PassManager with default mutating passes + */ +PassManager create_default_pass_manager(Target target); +/** Default setups the graph context if not done manually + * + * @param[in] ctx Graph Context + */ +void setup_default_graph_context(GraphContext &ctx); +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_UTILS_H__ */ diff --git a/arm_compute/graph/Workload.h b/arm_compute/graph/Workload.h new file mode 100644 index 0000000000..b19c932636 --- /dev/null +++ b/arm_compute/graph/Workload.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_WORKLOAD_H__ +#define __ARM_COMPUTE_GRAPH_WORKLOAD_H__ + +#include "arm_compute/runtime/IFunction.h" + +#include <memory> +#include <vector> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class ITensorHandle; +class INode; +class Tensor; + +/** Execution task + * + * Contains all the information required to execute a given task + */ +struct ExecutionTask +{ + // TODO (geopin01) : Support vector of functions? + std::unique_ptr<arm_compute::IFunction> task = {}; /**< Task to execute */ + INode *node = {}; /**< Node bound to this workload */ + std::vector<ITensorHandle *> commit_handles = {}; /**< Handles needs to sync for this task to execute */ + std::vector<ITensorHandle *> release_handles = {}; /**< Handles that can be released after this node execution */ + + /** Function operator */ + void operator()(); +}; + +/** Execution workload */ +struct ExecutionWorkload +{ + std::vector<Tensor *> inputs = {}; /**< Input handles */ + std::vector<Tensor *> outputs = {}; /**< Output handles */ + std::vector<ExecutionTask> tasks = {}; /**< Execution workload */ +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_WORKLOAD_H__ */ diff --git a/arm_compute/graph/algorithms/Algorithms.h b/arm_compute/graph/algorithms/Algorithms.h new file mode 100644 index 0000000000..f89856f327 --- /dev/null +++ b/arm_compute/graph/algorithms/Algorithms.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_ALGORITHMS_H__ +#define __ARM_COMPUTE_GRAPH_ALGORITHMS_H__ + +#include "arm_compute/graph/algorithms/BFS.h" + +#endif /* __ARM_COMPUTE_GRAPH_ALGORITHMS_H__ */ diff --git a/arm_compute/graph/algorithms/BFS.h b/arm_compute/graph/algorithms/BFS.h new file mode 100644 index 0000000000..36ca872f15 --- /dev/null +++ b/arm_compute/graph/algorithms/BFS.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_ALGORITHM_BFS_H__ +#define __ARM_COMPUTE_GRAPH_ALGORITHM_BFS_H__ + +#include "arm_compute/graph/Graph.h" + +#include <list> +#include <vector> + +namespace arm_compute +{ +namespace graph +{ +namespace detail +{ +/** Checks if all the input dependencies of a node have been visited + * + * @param[in] node Node to check + * @param[in] visited Vector that contains the visited information + * + * @return True if all inputs dependencies have been visited else false + */ +inline bool all_inputs_are_visited(const INode *node, const std::vector<bool> &visited) +{ + ARM_COMPUTE_ERROR_ON(node == nullptr); + const Graph *graph = node->graph(); + ARM_COMPUTE_ERROR_ON(graph == nullptr); + + bool are_all_visited = true; + for(const auto &input_edge_id : node->input_edges()) + { + if(input_edge_id != EmptyNodeID) + { + const Edge *input_edge = graph->edge(input_edge_id); + ARM_COMPUTE_ERROR_ON(input_edge == nullptr); + ARM_COMPUTE_ERROR_ON(input_edge->producer() == nullptr); + if(!visited[input_edge->producer_id()]) + { + are_all_visited = false; + break; + } + } + } + + return are_all_visited; +} +} // namespace detail + +/** Breadth first search traversal + * + * @param g Graph to traverse + * + * @return A vector with the node id traversal order + */ +inline std::vector<NodeID> bfs(Graph &g) +{ + std::vector<NodeID> bfs_order_vector; + + // Created visited vector + std::vector<bool> visited(g.nodes().size(), false); + + // Create BFS queue + std::list<NodeID> queue; + + // Push inputs and mark as visited + for(auto &input : g.inputs()) + { + if(input != EmptyNodeID) + { + visited[input] = true; + queue.push_back(input); + } + } + + // Iterate over vector and edges + while(!queue.empty()) + { + // Dequeue a node from queue and process + NodeID n = queue.front(); + bfs_order_vector.push_back(n); + queue.pop_front(); + + const INode *node = g.node(n); + ARM_COMPUTE_ERROR_ON(node == nullptr); + for(const auto &eid : node->output_edges()) + { + const Edge *e = g.edge(eid); + ARM_COMPUTE_ERROR_ON(e == nullptr); + if(!visited[e->consumer_id()] && detail::all_inputs_are_visited(e->consumer(), visited)) + { + visited[e->consumer_id()] = true; + queue.push_back(e->consumer_id()); + } + } + } + + return bfs_order_vector; +} +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_ALGORITHM_BFS_H__ */ diff --git a/arm_compute/graph/OperationRegistrar.h b/arm_compute/graph/backends/BackendRegistrar.h index ee171c3510..f7f2f7f9d2 100644 --- a/arm_compute/graph/OperationRegistrar.h +++ b/arm_compute/graph/backends/BackendRegistrar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,39 +21,41 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR -#define ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR +#ifndef ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__ +#define ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__ -#include "arm_compute/graph/OperationRegistry.h" #include "arm_compute/graph/Types.h" +#include "arm_compute/graph/backends/BackendRegistry.h" -#include <string> #include <utility> namespace arm_compute { namespace graph { +namespace backends +{ namespace detail { -/** Helper class to statically register an operation */ +/** Helper class to statically register a backend */ template <typename T> -class OperationRegistrar final +class BackendRegistrar final { public: - /** Add a new test case with the given name to the framework. + /** Add a new backend to the backend registry * - * @param[in] operation Operation type + * @param[in] target Execution target */ - OperationRegistrar(OperationType operation); + BackendRegistrar(Target target); }; template <typename T> -inline OperationRegistrar<T>::OperationRegistrar(OperationType operation) +inline BackendRegistrar<T>::BackendRegistrar(Target target) { - OperationRegistry::get().add_operation<T>(std::move(operation)); + BackendRegistry::get().add_backend<T>(target); } } // namespace detail +} // namespace backends } // namespace graph } // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR */
\ No newline at end of file +#endif /* ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__ */
\ No newline at end of file diff --git a/arm_compute/graph/OperationRegistry.h b/arm_compute/graph/backends/BackendRegistry.h index ae68bf45a2..69114ed26d 100644 --- a/arm_compute/graph/OperationRegistry.h +++ b/arm_compute/graph/backends/BackendRegistry.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,66 +21,71 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_H__ -#define __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_H__ +#ifndef __ARM_COMPUTE_GRAPH_BACKEND_REGISTRY_H__ +#define __ARM_COMPUTE_GRAPH_BACKEND_REGISTRY_H__ -#include "arm_compute/graph/IOperation.h" +#include "arm_compute/graph/IDeviceBackend.h" #include "arm_compute/graph/Types.h" #include "support/ToolchainSupport.h" #include <map> #include <memory> -#include <string> namespace arm_compute { namespace graph { -/** Registry holding all the supported operations */ -class OperationRegistry +namespace backends +{ +/** Registry holding all the supported backends */ +class BackendRegistry final { public: - /** Gets operation registry instance + /** Gets backend registry instance * - * @return Operation registry instance + * @return Backend registry instance */ - static OperationRegistry &get(); - /** Finds an operation in the registry + static BackendRegistry &get(); + /** Finds a backend in the registry * - * @param[in] operation Type of the operation to find - * @param[in] target Target of the operation + * @param[in] target Backend target * - * @return Pointer to the operation functor if found, else nullptr + * @return Pointer to the backend interface if found, else nullptr */ - IOperation *find_operation(OperationType operation, TargetHint target); - /** Checks if an operation for a given target exists + IDeviceBackend *find_backend(Target target); + /** Checks if a backend for a given target exists * - * @param[in] operation Operation type - * @param[in] target Execution target + * @param[in] target Execution target * * @return True if exists else false */ - bool contains(OperationType operation, TargetHint target) const; - /** Registers an operation to the registry + bool contains(Target target) const; + /** Backends accessor + * + * @return Map containing the registered backends + */ + const std::map<Target, std::unique_ptr<IDeviceBackend>> &backends() const; + /** Registers a backend to the registry * - * @param operation Operation to register + * @param[in] target Execution target to register for */ template <typename T> - void add_operation(OperationType operation); + void add_backend(Target target); private: /** Default Constructor */ - OperationRegistry(); + BackendRegistry(); private: - std::map<OperationType, std::vector<std::unique_ptr<IOperation>>> _registered_ops; + std::map<Target, std::unique_ptr<IDeviceBackend>> _registered_backends; }; template <typename T> -inline void OperationRegistry::add_operation(OperationType operation) +inline void BackendRegistry::add_backend(Target target) { - _registered_ops[operation].emplace_back(support::cpp14::make_unique<T>()); + _registered_backends[target] = support::cpp14::make_unique<T>(); } +} // namespace backends } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_BACKEND_REGISTRY_H__ */ diff --git a/arm_compute/graph/backends/CL/CLDeviceBackend.h b/arm_compute/graph/backends/CL/CLDeviceBackend.h new file mode 100644 index 0000000000..5adbe0e1a8 --- /dev/null +++ b/arm_compute/graph/backends/CL/CLDeviceBackend.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_CLDEVICEBACKEND_H__ +#define __ARM_COMPUTE_GRAPH_CLDEVICEBACKEND_H__ + +#include "arm_compute/graph/IDeviceBackend.h" + +#include "arm_compute/runtime/CL/CLBufferAllocator.h" +#include "arm_compute/runtime/CL/CLTuner.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** OpenCL device backend */ +class CLDeviceBackend final : public IDeviceBackend +{ +public: + /** Default Constructor */ + CLDeviceBackend(); + /** Destructor */ + ~CLDeviceBackend(); + /** Switchs on or off the kernel tuning + * + * @note When true the tuner set is used, if no tuner is set a new default one is created + * + * @param[in] enable_tuning Enables tuning if false else true + */ + void set_kernel_tuning(bool enable_tuning); + + // Inherited overridden methods + void initialize_backend() override; + void setup_backend_context(GraphContext &ctx) override; + bool is_backend_supported() override; + std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override; + std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; + +private: + CLTuner _tuner; /**< CL kernel tuner */ + CLBufferAllocator _allocator; /**< CL buffer affinity allocator */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_CLDEVICEBACKEND_H__ diff --git a/arm_compute/graph/backends/CL/CLFunctionFactory.h b/arm_compute/graph/backends/CL/CLFunctionFactory.h new file mode 100644 index 0000000000..6caca547cf --- /dev/null +++ b/arm_compute/graph/backends/CL/CLFunctionFactory.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__ +#define __ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__ + +#include "arm_compute/runtime/IFunction.h" + +#include <memory> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; +class GraphContext; + +namespace backends +{ +/** Factory for generating OpenCL backend functions **/ +class CLFunctionFactory final +{ +public: + /** Create a backend execution function depending on the node type + * + * @param[in] node Node to create the backend function for + * @param[in] ctx Context to use + * + * @return Backend function + */ + static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx); +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph/nodes/FlattenLayer.h b/arm_compute/graph/backends/CL/CLNodeValidator.h index c5f51a2b3e..9bd4842cf7 100644 --- a/arm_compute/graph/nodes/FlattenLayer.h +++ b/arm_compute/graph/backends/CL/CLNodeValidator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,25 +21,32 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__ +#define __ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__ -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" +#include "arm_compute/core/Error.h" namespace arm_compute { namespace graph { -/** Flatten layer node */ -class FlattenLayer final : public INode +// Forward declarations +class INode; + +namespace backends +{ +class CLNodeValidator final { public: - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + /** Validate a node + * + * @param[in] node Node to validate + * + * @return An error status + */ + static Status validate(INode *node); }; +} // namespace backends } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_H__ */ +#endif //__ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__ diff --git a/arm_compute/graph/backends/CL/CLSubTensorHandle.h b/arm_compute/graph/backends/CL/CLSubTensorHandle.h new file mode 100644 index 0000000000..4be5842c70 --- /dev/null +++ b/arm_compute/graph/backends/CL/CLSubTensorHandle.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_CLSUBTENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_CLSUBTENSORHANDLE_H__ + +#include "arm_compute/graph/ITensorHandle.h" + +#include "arm_compute/runtime/CL/CLSubTensor.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** OpenCL Sub-Tensor handle interface object **/ +class CLSubTensorHandle final : public ITensorHandle +{ +public: + /** Default constructor + * + * @param[in] parent_handle Parent tensor handle + * @param[in] shape Sub-Tensor shape + * @param[in] coords Starting coordinates + * @param[in] extend_parent Extends parent shape if true + */ + CLSubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent = false); + /** Destructor: free the tensor's memory */ + ~CLSubTensorHandle() = default; + /** Allow instances of this class to be move constructed */ + CLSubTensorHandle(CLSubTensorHandle &&) = default; + /** Allow instances of this class to be moved */ + CLSubTensorHandle &operator=(CLSubTensorHandle &&) = default; + + // Inherited overridden methods + void allocate() override; + arm_compute::ITensor &tensor() override; + const arm_compute::ITensor &tensor() const override; + void map(bool blocking) override; + void unmap() override; + void release_if_unused() override; + bool is_subtensor() const override; + +private: + arm_compute::CLSubTensor _sub_tensor; /**< Backend Sub-Tensor */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_CLSUBTENSORHANDLE_H__ */ diff --git a/arm_compute/graph/backends/CL/CLTensorHandle.h b/arm_compute/graph/backends/CL/CLTensorHandle.h new file mode 100644 index 0000000000..8f5a70cbbb --- /dev/null +++ b/arm_compute/graph/backends/CL/CLTensorHandle.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_CLTENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_CLTENSORHANDLE_H__ + +#include "arm_compute/graph/ITensorHandle.h" + +#include "arm_compute/runtime/CL/CLTensor.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** OpenCL Tensor handle interface object **/ +class CLTensorHandle final : public ITensorHandle +{ +public: + /** Default Constructor + * + * @param[in] info Tensor metadata + */ + CLTensorHandle(const ITensorInfo &info); + /** Destructor: free the tensor's memory */ + ~CLTensorHandle() = default; + /** Allow instances of this class to be move constructed */ + CLTensorHandle(CLTensorHandle &&) = default; + /** Allow instances of this class to be moved */ + CLTensorHandle &operator=(CLTensorHandle &&) = default; + + // Inherited overridden methods + void allocate() override; + arm_compute::ITensor &tensor() override; + const arm_compute::ITensor &tensor() const override; + void map(bool blocking) override; + void unmap() override; + void release_if_unused() override; + bool is_subtensor() const override; + +private: + arm_compute::CLTensor _tensor; /**< Backend Tensor */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_CLTENSORHANDLE_H__ */ diff --git a/arm_compute/graph/backends/GLES/GCDeviceBackend.h b/arm_compute/graph/backends/GLES/GCDeviceBackend.h new file mode 100644 index 0000000000..be81a8f1f2 --- /dev/null +++ b/arm_compute/graph/backends/GLES/GCDeviceBackend.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H__ +#define __ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H__ + +#include "arm_compute/graph/IDeviceBackend.h" + +#include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** GLES Compute device backend */ +class GCDeviceBackend final : public IDeviceBackend +{ +public: + /** Default Constructor */ + GCDeviceBackend(); + + // Inherited overridden methods + void initialize_backend() override; + void setup_backend_context(GraphContext &ctx) override; + bool is_backend_supported() override; + std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override; + std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; + +private: + GCBufferAllocator _allocator; /**< GLES buffer affinity allocator */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_GCDEVICEBACKEND_H__ diff --git a/arm_compute/graph/backends/GLES/GCFunctionFactory.h b/arm_compute/graph/backends/GLES/GCFunctionFactory.h new file mode 100644 index 0000000000..c819c034f6 --- /dev/null +++ b/arm_compute/graph/backends/GLES/GCFunctionFactory.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__ +#define __ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__ + +#include "arm_compute/runtime/IFunction.h" + +#include <memory> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; +class GraphContext; + +namespace backends +{ +/** Factory for generating GLES compute backend functions **/ +class GCFunctionFactory final +{ +public: + /** Create a backend execution function depending on the node type + * + * @param[in] node Node to create the backend function for + * @param[in] ctx Context to use + * + * @return Backend function + */ + static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx); +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/backends/GLES/GCNodeValidator.h index b5d1bc53fd..6fdfbdd894 100644 --- a/arm_compute/graph/nodes/SoftmaxLayer.h +++ b/arm_compute/graph/backends/GLES/GCNodeValidator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,24 +21,32 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__ +#define __ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__ + +#include "arm_compute/core/Error.h" -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** Softmax layer node */ -class SoftmaxLayer final : public INode +// Forward declarations +class INode; + +namespace backends +{ +class GCNodeValidator final { public: - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + /** Validate a node + * + * @param[in] node Node to validate + * + * @return An error status + */ + static Status validate(INode *node); }; +} // namespace backends } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */ +#endif //__ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__ diff --git a/arm_compute/graph/backends/GLES/GCTensorHandle.h b/arm_compute/graph/backends/GLES/GCTensorHandle.h new file mode 100644 index 0000000000..774268fd3f --- /dev/null +++ b/arm_compute/graph/backends/GLES/GCTensorHandle.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H__ + +#include "arm_compute/graph/ITensorHandle.h" + +#include "arm_compute/runtime/GLES_COMPUTE/GCTensor.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** GLES compute tensor handle interface object **/ +class GCTensorHandle final : public ITensorHandle +{ +public: + /** Default Constructor + * + * @param[in] info Tensor metadata + */ + GCTensorHandle(const ITensorInfo &info); + /** Destructor: free the tensor's memory */ + ~GCTensorHandle() = default; + /** Allow instances of this class to be move constructed */ + GCTensorHandle(GCTensorHandle &&) = default; + /** Allow instances of this class to be moved */ + GCTensorHandle &operator=(GCTensorHandle &&) = default; + + // Inherited overridden methods + void allocate() override; + arm_compute::ITensor &tensor() override; + const arm_compute::ITensor &tensor() const override; + void map(bool blocking) override; + void unmap() override; + void release_if_unused() override; + bool is_subtensor() const override; + +private: + arm_compute::GCTensor _tensor; /**< Backend Tensor */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_GCTENSORHANDLE_H__ */ diff --git a/arm_compute/graph/CL/CLMap.h b/arm_compute/graph/backends/NEON/NEDeviceBackend.h index 732a1df77f..b23c83adea 100644 --- a/arm_compute/graph/CL/CLMap.h +++ b/arm_compute/graph/backends/NEON/NEDeviceBackend.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,46 +21,39 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_CLMAP_H__ -#define __ARM_COMPUTE_GRAPH_CLMAP_H__ +#ifndef __ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H__ +#define __ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H__ -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" +#include "arm_compute/graph/IDeviceBackend.h" + +#include "arm_compute/runtime/Allocator.h" namespace arm_compute { -class ICLTensor; - namespace graph { -class ITensorObject; -/** OpenCL map function */ -class CLMap : public arm_compute::IFunction +namespace backends +{ +/** NEON device backend */ +class NEDeviceBackend final : public IDeviceBackend { public: - /** Constructor - * - * @param[in] tensor Tensor to map - * @param[in] blocking Flag to specify if the map should be blocking or not (defaults to false) - */ - CLMap(ITensorObject *tensor, bool blocking = false); - /** Prevent instances from being copy constructed */ - CLMap(const CLMap &) = delete; - /** Prevent instances from being copy assigned */ - const CLMap &operator=(const CLMap &) = delete; - /** Allow instances to be move constructed */ - CLMap(CLMap &&) = default; - /** Allow instances to be move assigned */ - CLMap &operator=(CLMap &&) = default; + NEDeviceBackend(); - // Inherited methods overriden: - void run() override; + // Inherited overridden methods + void initialize_backend() override; + void setup_backend_context(GraphContext &ctx) override; + bool is_backend_supported() override; + std::unique_ptr<ITensorHandle> create_tensor(const Tensor &tensor) override; + std::unique_ptr<ITensorHandle> create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr<arm_compute::IFunction> configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr<arm_compute::IMemoryManager> create_memory_manager(MemoryManagerAffinity affinity) override; private: - arm_compute::ICLTensor *_tensor; /**< Tensor */ - bool _blocking; /**< Blocking flag */ + Allocator _allocator; /**< NEON backend allocator */ }; +} // namespace backends } // namespace graph } // namespace arm_compute - -#endif /* __ARM_COMPUTE_GRAPH_CLMAP_H__ */ +#endif //__ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H__ diff --git a/arm_compute/graph/backends/NEON/NEFunctionFactory.h b/arm_compute/graph/backends/NEON/NEFunctionFactory.h new file mode 100644 index 0000000000..1143c29c5b --- /dev/null +++ b/arm_compute/graph/backends/NEON/NEFunctionFactory.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_NEFUNCTIONFACTORY_H__ +#define __ARM_COMPUTE_GRAPH_NEFUNCTIONFACTORY_H__ + +#include "arm_compute/runtime/IFunction.h" + +#include <memory> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; +class GraphContext; + +namespace backends +{ +/** Factory for generating NEON backend functions **/ +class NEFunctionFactory final +{ +public: + /** Create a backend execution function depending on the node type + * + * @param[in] node Node to create the backend function for + * @param[in] ctx Context to use + * + * @return Backend function + */ + static std::unique_ptr<arm_compute::IFunction> create(INode *node, GraphContext &ctx); +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_NEFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph/backends/NEON/NENodeValidator.h b/arm_compute/graph/backends/NEON/NENodeValidator.h new file mode 100644 index 0000000000..38f58a9d91 --- /dev/null +++ b/arm_compute/graph/backends/NEON/NENodeValidator.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_NENODEVALIDATOR_H__ +#define __ARM_COMPUTE_GRAPH_NENODEVALIDATOR_H__ + +#include "arm_compute/core/Error.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; + +namespace backends +{ +class NENodeValidator final +{ +public: + /** Validate a node + * + * @param[in] node Node to validate + * + * @return An error status + */ + static Status validate(INode *node); +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_NENODEVALIDATOR_H__ diff --git a/arm_compute/graph/backends/NEON/NESubTensorHandle.h b/arm_compute/graph/backends/NEON/NESubTensorHandle.h new file mode 100644 index 0000000000..11dcec60f3 --- /dev/null +++ b/arm_compute/graph/backends/NEON/NESubTensorHandle.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_NESUBTENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_NESUBTENSORHANDLE_H__ + +#include "arm_compute/graph/ITensorHandle.h" + +#include "arm_compute/runtime/SubTensor.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** NEON Sub-Tensor handle interface object **/ +class NESubTensorHandle final : public ITensorHandle +{ +public: + /** Default constructor + * + * @param[in] parent_handle Parent tensor handle + * @param[in] shape Sub-Tensor shape + * @param[in] coords Starting coordinates + * @param[in] extend_parent Extends parent shape if true + */ + NESubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent = false); + /** Destructor: free the tensor's memory */ + ~NESubTensorHandle() = default; + /** Allow instances of this class to be move constructed */ + NESubTensorHandle(NESubTensorHandle &&) = default; + /** Allow instances of this class to be moved */ + NESubTensorHandle &operator=(NESubTensorHandle &&) = default; + + // Inherited overridden methods + void allocate() override; + arm_compute::ITensor &tensor() override; + const arm_compute::ITensor &tensor() const override; + void map(bool blocking) override; + void unmap() override; + void release_if_unused() override; + bool is_subtensor() const override; + +private: + arm_compute::SubTensor _sub_tensor; /**< Backend Sub-Tensor */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_NESUBTENSORHANDLE_H__ */ diff --git a/arm_compute/graph/NodeParameter.h b/arm_compute/graph/backends/NEON/NETensorHandle.h index 9d3823d543..06ccdd83cc 100644 --- a/arm_compute/graph/NodeParameter.h +++ b/arm_compute/graph/backends/NEON/NETensorHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,54 +21,48 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__ -#define __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__ +#ifndef __ARM_COMPUTE_GRAPH_NETENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_NETENSORHANDLE_H__ -#include <ostream> -#include <string> +#include "arm_compute/graph/ITensorHandle.h" + +#include "arm_compute/runtime/Tensor.h" namespace arm_compute { namespace graph { -/**Node Parameter Empty base class */ -class NodeParameterBase +namespace backends { -}; - -/** Template parameter implementation */ -template <typename T> -class NodeParameter : public NodeParameterBase +/** NEON Tensor handle interface object **/ +class NETensorHandle final : public ITensorHandle { public: /** Default Constructor * - * @param[in] name Paremeter name - * @param[in] val Parameter value - */ - NodeParameter(std::string name, T val) - : _name(name), _val(val) {}; - /** Returns parameter's name - * - * @return the name of the parameter - */ - std::string name() const - { - return _name; - } - /** Returns parameter's value - * - * @return the value of the parameter + * @param[in] info Tensor metadata */ - T value() - { - return _val; - } + NETensorHandle(const ITensorInfo &info); + /** Destructor: free the tensor's memory */ + ~NETensorHandle() = default; + /** Allow instances of this class to be move constructed */ + NETensorHandle(NETensorHandle &&) = default; + /** Allow instances of this class to be moved */ + NETensorHandle &operator=(NETensorHandle &&) = default; + + // Inherited overridden methods + void allocate() override; + arm_compute::ITensor &tensor() override; + const arm_compute::ITensor &tensor() const override; + void map(bool blocking) override; + void unmap() override; + void release_if_unused() override; + bool is_subtensor() const override; private: - std::string _name; - T _val; + arm_compute::Tensor _tensor; /**< Backend Tensor */ }; +} // namespace backends } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_NETENSORHANDLE_H__ */ diff --git a/arm_compute/graph/backends/Utils.h b/arm_compute/graph/backends/Utils.h new file mode 100644 index 0000000000..b902d17c0e --- /dev/null +++ b/arm_compute/graph/backends/Utils.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_BACKENDS_UTILS_H__ +#define __ARM_COMPUTE_GRAPH_BACKENDS_UTILS_H__ + +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/runtime/IMemoryManager.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** Creates and configures a named function + * + * @param[in] name Name of the function + * @param[in] args Function arguments + * + * @return A configured backend function + */ +template <typename FunctionType, typename FunctionNameType, typename... ParameterType> +std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_function(FunctionNameType name, ParameterType... args) +{ + auto f = arm_compute::support::cpp14::make_unique<FunctionType>(); + f->configure(std::forward<ParameterType>(args)...); + return std::make_pair(std::move(f), name); +} + +/** Creates and configures a named function + * + * @param[in] name Name of the function + * @param[in] mm Memory manager to use + * @param[in] args Function arguments + * + * @return A configured backend function + */ +template <typename FunctionType, typename FunctionNameType, typename MemoryManagerType, typename... ParameterType> +std::pair<std::unique_ptr<arm_compute::IFunction>, FunctionNameType> create_named_memory_managed_function(FunctionNameType name, + MemoryManagerType mm, + ParameterType... args) +{ + auto f = arm_compute::support::cpp14::make_unique<FunctionType>(mm); + f->configure(std::forward<ParameterType>(args)...); + return std::make_pair(std::move(f), name); +} + +/** Checks if an operation is in place + * + * @param[in] input Pointer to input + * @param[in] output Pointer to output + * + * @return True if output is nullptr or input is equal to the output, else false + */ +inline bool is_in_place_operation(void *input, void *output) +{ + return (output == nullptr) || (input == output); +} + +/** Returns the memory manager for a given target + * + * @param[in] ctx Graph context containing memory management metadata + * @param[in] target Target to retrieve the memory manager from + * + * @return The memory manager for the given target else false + */ +inline std::shared_ptr<IMemoryManager> get_memory_manager(GraphContext &ctx, Target target) +{ + bool enabled = ctx.config().use_function_memory_manager && (ctx.memory_management_ctx(target) != nullptr); + return enabled ? ctx.memory_management_ctx(target)->mm : nullptr; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute + +#endif /* __ARM_COMPUTE_GRAPH_BACKENDS_UTILS_H__ */ diff --git a/arm_compute/graph/backends/ValidateHelpers.h b/arm_compute/graph/backends/ValidateHelpers.h new file mode 100644 index 0000000000..ca01295d15 --- /dev/null +++ b/arm_compute/graph/backends/ValidateHelpers.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ +#define __ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ + +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/Types.h" +#include "arm_compute/graph/nodes/Nodes.h" + +#include "arm_compute/core/Error.h" +#include "arm_compute/core/ITensorInfo.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace detail +{ +/** Returns backing tensor info of a given tensor + * + * @param[in] tensor Tensor to extract the backing tensor from + * + * @return Backing tensor tensor info if present else nullptr + */ +inline arm_compute::ITensorInfo *get_backing_tensor_info(arm_compute::graph::Tensor *tensor) +{ + return ((tensor == nullptr) || (tensor->handle() == nullptr)) ? nullptr : tensor->handle()->tensor().info(); +} + +/** Validates a Convolution layer node + * + * @tparam ConvolutionLayer Default Convolution layer function type + * @tparam DirectConvolutionLayer Direct Convolution layer function type + * @tparam GEMMConvolutionLayer GEMM Convolution layer function type + * @tparam WinogradConvolutionLayer Winograd Convolution layer function type + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename ConvolutionLayer, typename DirectConvolutionLayer, typename GEMMConvolutionLayer, typename WinogradConvolutionLayer> +Status validate_convolution_layer(ConvolutionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + arm_compute::ITensorInfo *input = get_backing_tensor_info(node.input(0)); + arm_compute::ITensorInfo *weights = get_backing_tensor_info(node.input(1)); + arm_compute::ITensorInfo *biases = get_backing_tensor_info(node.input(2)); + arm_compute::ITensorInfo *output = get_backing_tensor_info(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const ConvolutionMethod conv_algorithm = node.convolution_method(); + + // Validate function + Status status{}; + switch(conv_algorithm) + { + case ConvolutionMethod::DIRECT: + status = DirectConvolutionLayer::validate(input, weights, biases, output, conv_info); + break; + case ConvolutionMethod::GEMM: + status = GEMMConvolutionLayer::validate(input, weights, biases, output, conv_info); + break; + case ConvolutionMethod::WINOGRAD: + status = WinogradConvolutionLayer::validate(input, weights, biases, output, conv_info); + break; + default: + break; + } + + // If validation fails try the Default approach + if(!bool(status) || (conv_algorithm == ConvolutionMethod::DEFAULT)) + { + std::cout << status.error_description() << std::endl; + status = ConvolutionLayer::validate(input, weights, biases, output, conv_info); + if(bool(status)) + { + ARM_COMPUTE_LOG_GRAPH_INFO("Switched ConvolutionLayer method of node with ID : " + << node.id() << " and Name: " << node.name() << std::endl); + node.set_convolution_method(ConvolutionMethod::DEFAULT); + } + } + + return status; +} + +/** Validates a Depthwise Convolution layer node + * + * @tparam DepthwiseConvolutionLayer Default Depthwise Convolution layer type + * @tparam DepthwiseConvolutionLayer3x3 Optimized 3x3 Depthwise Convolution layer type + * + * @param[in] node Node to validate + * + * @return Status + */ +template <typename DepthwiseConvolutionLayer, typename DepthwiseConvolutionLayer3x3> +Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_RETURN_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + arm_compute::ITensorInfo *weights = detail::get_backing_tensor_info(node.input(1)); + const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); + ARM_COMPUTE_ERROR_ON(weights == nullptr); + + // TODO (geopin01) : Switch when validation is implemented + // Validate function + if((dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) && (weights->tensor_shape().x() != 3)) + { + ARM_COMPUTE_LOG_GRAPH_INFO("Switched DepthwiseConvolutionLayer method of node with ID : " + << node.id() << " and Name: " << node.name() << std::endl); + node.set_depthwise_convolution_method(DepthwiseConvolutionMethod::DEFAULT); + } + + return Status{}; +} +} // namespace detail +} // namespace backends +} // namespace graph +} // namespace arm_compute + +#endif /* __ARM_COMPUTE_GRAPH_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ */ diff --git a/arm_compute/graph/detail/ExecutionHelpers.h b/arm_compute/graph/detail/ExecutionHelpers.h new file mode 100644 index 0000000000..52304d6836 --- /dev/null +++ b/arm_compute/graph/detail/ExecutionHelpers.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_DETAIL_EXECUTION_HELPERS_H__ +#define __ARM_COMPUTE_GRAPH_DETAIL_EXECUTION_HELPERS_H__ + +#include "arm_compute/graph/Types.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; +class GraphContext; +class ExecutionWorkload; +class Tensor; + +namespace detail +{ +/** Initializes the available backends **/ +void default_initialize_backends(); +/** Configures all nodes of a graph + * + * @param[in] g Graph to configure + */ +void configure_all_tensors(Graph &g); +/** Allocates all tensors of a graph + * + * @param[in] g Graph to allocate the tensors + */ +void allocate_all_tensors(Graph &g); +/** Validates all nodes + * + * @param[in] g Graph to validate + */ +void validate_all_nodes(Graph &g); +/** Configures all nodes of graph + * + * @param[in] g Graph to configure the nodes + * @param[in] ctx Graph context to use + * + * @return The execution workload + */ +ExecutionWorkload configure_all_nodes(Graph &g, GraphContext &ctx); +/** Release the memory of all unused const nodes + * + * @param[in] g Graph to release the memory from + */ +void release_unused_tensors(Graph &g); +/** Calls accessor of a given tensor + * + * @param[in] tensor The tensor of which the accessor should be called + */ +void call_tensor_accessor(Tensor *tensor); +/** Call all const node accessors + * + * @param[in] g Graph containing the const nodes + */ +void call_all_const_node_accessors(Graph &g); +/** Call all input node accessors + * + * @param[in] workload Workload to execute + */ +void call_all_input_node_accessors(ExecutionWorkload &workload); +/** Call all output node accessors + * + * @param[in] workload Workload to execute + */ +void call_all_output_node_accessors(ExecutionWorkload &workload); +/** Executes all tasks of a workload + * + * @param[in] workload Workload to execute + */ +void call_all_tasks(ExecutionWorkload &workload); +} // namespace detail +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_DETAIL_EXECUTION_HELPERS_H__ */ diff --git a/arm_compute/graph/frontend/ILayer.h b/arm_compute/graph/frontend/ILayer.h new file mode 100644 index 0000000000..5add8ab440 --- /dev/null +++ b/arm_compute/graph/frontend/ILayer.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_ILAYER_H__ +#define __ARM_COMPUTE_GRAPH_ILAYER_H__ + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +// Forward declarations +class IStream; + +/** ILayer interface */ +class ILayer +{ +public: + /** Default destructor */ + virtual ~ILayer() = default; + /** Create layer and add to the given stream. + * + * @param[in] s Stream to add layer to. + * + * @return ID of the created node. + */ + virtual NodeID create_layer(IStream &s) = 0; +}; +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_ILAYER_H__ */ diff --git a/arm_compute/graph/frontend/IStream.h b/arm_compute/graph/frontend/IStream.h new file mode 100644 index 0000000000..13995f9cf9 --- /dev/null +++ b/arm_compute/graph/frontend/IStream.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_ISTREAM_H__ +#define __ARM_COMPUTE_GRAPH_ISTREAM_H__ + +#include "arm_compute/graph/frontend/Types.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; + +namespace frontend +{ +// Forward declarations +class ILayer; + +/** Stream interface **/ +class IStream +{ +public: + virtual ~IStream() = default; + /** Adds a layer to the stream + * + * @param[in] layer Layer to add + */ + virtual void add_layer(ILayer &layer) = 0; + /** Returns the underlying graph + * + * @return Underlying graph + */ + virtual Graph &graph() = 0; + /** Returns the underlying graph + * + * @return Underlying graph + */ + virtual const Graph &graph() const = 0; + /** Returns the tail node of the Stream + * + * @return Tail Node ID + */ + NodeID tail_node() + { + return _tail_node; + } + /** Returns the stream hints that are currently used + * + * @return Stream hints + */ + StreamHints &hints() + { + return _hints; + } + /** Forwards tail of stream to a given nid + * + * @param[in] nid NodeID of the updated tail node + */ + void forward_tail(NodeID nid) + { + _tail_node = (nid != NullTensorID) ? nid : _tail_node; + } + +protected: + StreamHints _hints = {}; /**< Execution and algorithmic hints */ + NodeID _tail_node = { EmptyNodeID }; /**< NodeID pointing to the last(tail) node of the graph */ +}; +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_ISTREAM_H__ */ diff --git a/arm_compute/graph/frontend/IStreamOperators.h b/arm_compute/graph/frontend/IStreamOperators.h new file mode 100644 index 0000000000..1eb6522935 --- /dev/null +++ b/arm_compute/graph/frontend/IStreamOperators.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_ISTREAM_OPERATORS_H__ +#define __ARM_COMPUTE_GRAPH_ISTREAM_OPERATORS_H__ + +#include "arm_compute/graph/frontend/IStream.h" +#include "arm_compute/graph/frontend/Types.h" + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +// Forward declarations +class ILayer; + +/** Overloaded stream operator to add a node to the graph + * + * @param[in, out] s Stream to add the tensor + * @param[in] layer Layer to be added + * + * @return Updated stream + */ +inline IStream &operator<<(IStream &s, ILayer &&layer) +{ + s.add_layer(layer); + return s; +} +/** Overloaded stream operator to provide a target hint to the graph + * + * @param[in, out] s Stream to provide the hint to + * @param[in] target_hint Target hint to be considered + * + * @return Updated stream + */ +inline IStream &operator<<(IStream &s, Target target_hint) +{ + s.hints().target_hint = target_hint; + return s; +} +/** Overloaded stream operator to provide a convolution method hint to the graph + * + * @param[in, out] s Stream to provide the hint to + * @param[in] convolution_method_hint Convolution method hint to be considered + * + * @return Updated stream + */ +inline IStream &operator<<(IStream &s, ConvolutionMethod convolution_method_hint) +{ + s.hints().convolution_method_hint = convolution_method_hint; + return s; +} +/** Overloaded stream operator to provide a depthwise convolution method hint to the graph + * + * @param[in, out] s Stream to provide the hint to + * @param[in] depthwise_convolution_method_hint Depthwise Convolution method hint to be considered + * + * @return Updated stream + */ +inline IStream &operator<<(IStream &s, DepthwiseConvolutionMethod depthwise_convolution_method_hint) +{ + s.hints().depthwise_convolution_method_hint = depthwise_convolution_method_hint; + return s; +} +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_ISTREAM_OPERATORS_H__ */ diff --git a/arm_compute/graph/frontend/Layers.h b/arm_compute/graph/frontend/Layers.h new file mode 100644 index 0000000000..22133b8376 --- /dev/null +++ b/arm_compute/graph/frontend/Layers.h @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_LAYERS_H__ +#define __ARM_COMPUTE_GRAPH_LAYERS_H__ + +#include "arm_compute/graph/GraphBuilder.h" +#include "arm_compute/graph/Types.h" +#include "arm_compute/graph/frontend/ILayer.h" +#include "arm_compute/graph/frontend/IStream.h" +#include "arm_compute/graph/frontend/SubStream.h" + +#include "arm_compute/core/utils/misc/Utility.h" + +#include <memory> +#include <string> + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +/** Input Layer */ +class InputLayer final : public ILayer +{ +public: + /** Construct an input layer. + * + * @param[in] desc Description of input tensor. + * @param[in] accessor Accessor to get input tensor data from. + */ + InputLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor) + : _desc(desc), _accessor(std::move(accessor)) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + return GraphBuilder::add_input_node(s.graph(), common_params, _desc, std::move(_accessor)); + } + +private: + TensorDescriptor _desc; + ITensorAccessorUPtr _accessor; +}; + +/** Output Layer */ +class OutputLayer final : public ILayer +{ +public: + /** Construct an output layer. + * + * @param[in] accessor Accessor to give output tensor data to. + */ + OutputLayer(ITensorAccessorUPtr accessor) + : _accessor(std::move(accessor)) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_output_node(s.graph(), common_params, input, std::move(_accessor)); + } + +private: + ITensorAccessorUPtr _accessor; +}; + +/** Activation Layer */ +class ActivationLayer final : public ILayer +{ +public: + /** Construct an activation layer. + * + * @param[in] act_info Activation information + */ + ActivationLayer(ActivationLayerInfo act_info) + : _act_info(act_info) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_activation_node(s.graph(), common_params, input, _act_info); + } + +private: + ActivationLayerInfo _act_info; +}; + +/** Batchnormalization Layer */ +class BatchNormalizationLayer final : public ILayer +{ +public: + /** Construct a batch normalization layer. + * + * @param[in] mean Accessor to get mean tensor data from. + * @param[in] var Accessor to get var tensor data from. + * @param[in] gamma (Optional) Accessor to get gamma tensor data from. Default: nullptr. + * @param[in] beta (Optional) Accessor to get beta tensor data from. Default: nullptr. + * @param[in] epsilon (Optional) Epsilon value. Default: 0.001. + */ + BatchNormalizationLayer(ITensorAccessorUPtr mean, + ITensorAccessorUPtr var, + ITensorAccessorUPtr gamma = nullptr, + ITensorAccessorUPtr beta = nullptr, + float epsilon = 0.001f) + : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon) + { + } + + NodeID create_layer(IStream &s) override + { + ARM_COMPUTE_ERROR_ON(_mean == nullptr); + ARM_COMPUTE_ERROR_ON(_var == nullptr); + + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_batch_normalization_node(s.graph(), common_params, input, _epsilon, + std::move(_mean), std::move(_var), std::move(_beta), std::move(_gamma)); + } + +private: + ITensorAccessorUPtr _mean; + ITensorAccessorUPtr _var; + ITensorAccessorUPtr _gamma; + ITensorAccessorUPtr _beta; + float _epsilon; +}; + +/** Convolution Layer */ +class ConvolutionLayer final : public ILayer +{ +public: + /** Construct a convolution layer. + * + * @param[in] conv_width Convolution width. + * @param[in] conv_height Convolution height. + * @param[in] ofm Output feature map. + * @param[in] weights Accessor to get kernel weights from. + * @param[in] bias Accessor to get kernel bias from. + * @param[in] conv_info Padding and stride information. + * @param[in] num_groups (Optional) Number of groups. Default: 1. + */ + ConvolutionLayer(unsigned int conv_width, + unsigned int conv_height, + unsigned int ofm, + ITensorAccessorUPtr weights, + ITensorAccessorUPtr bias, + PadStrideInfo conv_info, + unsigned int num_groups = 1) + : _conv_width(conv_width), + _conv_height(conv_height), + _ofm(ofm), + _conv_info(std::move(conv_info)), + _num_groups(num_groups), + _weights(std::move(weights)), + _bias(std::move(bias)) + { + } + + NodeID create_layer(IStream &s) override + { + NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = { "", s.hints().target_hint }; + return GraphBuilder::add_convolution_node(s.graph(), common_params, input, + Size2D(_conv_width, _conv_height), _ofm, _conv_info, _num_groups, + s.hints().convolution_method_hint, + std::move(_weights), std::move(_bias)); + } + +private: + unsigned int _conv_width; + unsigned int _conv_height; + unsigned int _ofm; + const PadStrideInfo _conv_info; + unsigned int _num_groups; + ITensorAccessorUPtr _weights; + ITensorAccessorUPtr _bias; +}; + +/** Depthwise Convolution Layer */ +class DepthwiseConvolutionLayer final : public ILayer +{ +public: + /** Construct a depthwise convolution layer. + * + * @param[in] conv_width Convolution width. + * @param[in] conv_height Convolution height. + * @param[in] weights Accessor to get kernel weights from. + * @param[in] bias Accessor to get kernel bias from. + * @param[in] conv_info Padding and stride information. + */ + DepthwiseConvolutionLayer(unsigned int conv_width, + unsigned int conv_height, + ITensorAccessorUPtr weights, + ITensorAccessorUPtr bias, + PadStrideInfo conv_info) + : _conv_width(conv_width), + _conv_height(conv_height), + _conv_info(std::move(conv_info)), + _weights(std::move(weights)), + _bias(std::move(bias)) + { + } + + NodeID create_layer(IStream &s) override + { + NodeIdxPair input = { s.tail_node(), 0 }; + NodeParams common_params = { "", s.hints().target_hint }; + return GraphBuilder::add_depthwise_convolution_node(s.graph(), common_params, + input, Size2D(_conv_width, _conv_height), _conv_info, + s.hints().depthwise_convolution_method_hint, + std::move(_weights), std::move(_bias)); + } + +private: + unsigned int _conv_width; + unsigned int _conv_height; + const PadStrideInfo _conv_info; + ITensorAccessorUPtr _weights; + ITensorAccessorUPtr _bias; +}; + +/** Flatten Layer */ +class FlattenLayer final : public ILayer +{ +public: + /** Construct a flatten layer. */ + FlattenLayer() + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_flatten_node(s.graph(), common_params, input); + } +}; + +/** Fully Connected Layer */ +class FullyConnectedLayer final : public ILayer +{ +public: + /** Construct a fully connected layer. + * + * @param[in] num_outputs Number of outputs. + * @param[in] weights Accessor to get weights from. + * @param[in] bias Accessor to get bias from. + */ + FullyConnectedLayer(unsigned int num_outputs, + ITensorAccessorUPtr weights, + ITensorAccessorUPtr bias) + : _num_outputs(num_outputs), _weights(std::move(weights)), _bias(std::move(bias)) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", 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)); + } + +private: + unsigned int _num_outputs; + ITensorAccessorUPtr _weights; + ITensorAccessorUPtr _bias; +}; + +/** Normalization Layer */ +class NormalizationLayer final : public ILayer +{ +public: + /** Construct a normalization layer. + * + * @param[in] norm_info Normalization information. + */ + NormalizationLayer(NormalizationLayerInfo norm_info) + : _norm_info(norm_info) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_normalization_node(s.graph(), common_params, input, _norm_info); + } + +private: + NormalizationLayerInfo _norm_info; +}; + +/** Pooling Layer */ +class PoolingLayer final : public ILayer +{ +public: + /** Construct a pooling layer. + * + * @param[in] pool_info Pooling information. + */ + PoolingLayer(PoolingLayerInfo pool_info) + : _pool_info(pool_info) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_pooling_node(s.graph(), common_params, input, _pool_info); + } + +private: + PoolingLayerInfo _pool_info; +}; + +/** Reshape Layer */ +class ReshapeLayer final : public ILayer +{ +public: + /** Construct a reshape layer. + * + * @param[in] shape Target shape. + */ + ReshapeLayer(TensorShape shape) + : _shape(shape) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_reshape_node(s.graph(), common_params, input, _shape); + } + +private: + TensorShape _shape; +}; + +/** Softmax Layer */ +class SoftmaxLayer final : public ILayer +{ +public: + /** Construct a softmax layer. + * + * @param[in] beta (Optional) Beta value. Default 1.0. + */ + SoftmaxLayer(float beta = 1.0f) + : _beta(beta) + { + } + + NodeID create_layer(IStream &s) override + { + NodeParams common_params = { "", s.hints().target_hint }; + NodeIdxPair input = { s.tail_node(), 0 }; + return GraphBuilder::add_softmax_node(s.graph(), common_params, input, _beta); + } + +private: + float _beta; +}; + +/** Branch Layer */ +class BranchLayer final : public ILayer +{ +public: + /** Construct a branch layer + * + * @param[in] merge_method Branch merging method + * @param[in] sub_stream1 First graph branch + * @param[in] sub_stream2 Second graph branch + * @param[in] rest_sub_streams Rest sub-graph branches + */ + template <typename... Ts> + BranchLayer(BranchMergeMethod merge_method, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams) + : _branch_merge_method(merge_method), _sub_streams() + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1))); + _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2))); + + utility::for_each([&](SubStream && sub_stream) + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); + }, + std::move(rest_sub_streams)...); + } + /** Construct a branch layer + * + * @param[in] sub_stream Sub-stream + */ + template <typename... Ts> + BranchLayer(SubStream &&sub_stream) + : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_streams() + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream))); + } + NodeID create_layer(IStream &s) override + { + NodeID nid = EmptyNodeID; + NodeParams common_params = { "", s.hints().target_hint }; + if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr) + { + nid = _sub_streams[0]->tail_node(); + } + else if(_branch_merge_method == BranchMergeMethod::DEPTH_CONCATENATE) + { + // Collect tail nodes and perform DepthConcatenate + std::vector<NodeIdxPair> nodes; + for(auto &ss : _sub_streams) + { + if(ss && (ss->tail_node() != EmptyNodeID)) + { + const auto tail_node = s.graph().node(ss->tail_node()); + if(tail_node != nullptr && tail_node->type() != NodeType::Output) + { + nodes.push_back({ ss->tail_node(), 0 }); + } + } + } + nid = GraphBuilder::add_depth_concatenate_node(s.graph(), common_params, nodes); + } + else + { + ARM_COMPUTE_ERROR_ON(_sub_streams.size() != 2); + NodeIdxPair input0 = { _sub_streams[0]->tail_node(), 0 }; + NodeIdxPair input1 = { _sub_streams[1]->tail_node(), 0 }; + nid = GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, EltwiseOperation::ADD); + } + return nid; + } + +private: + BranchMergeMethod _branch_merge_method; + std::vector<std::unique_ptr<SubStream>> _sub_streams; +}; +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_LAYERS_H__ */ diff --git a/arm_compute/graph/frontend/Stream.h b/arm_compute/graph/frontend/Stream.h new file mode 100644 index 0000000000..244d18e753 --- /dev/null +++ b/arm_compute/graph/frontend/Stream.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_STREAM_H__ +#define __ARM_COMPUTE_GRAPH_STREAM_H__ + +#include "arm_compute/graph/frontend/IStream.h" +#include "arm_compute/graph/frontend/IStreamOperators.h" +#include "arm_compute/graph/frontend/Types.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/GraphManager.h" + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +// Forward Declarations +class ILayer; + +/** Stream frontend class to construct simple graphs in a stream fashion */ +class Stream final : public IStream +{ +public: + /** Constructor + * + * @param[in] id Stream id + * @param[in] name Stream name + */ + Stream(size_t id, std::string name); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + Stream(const Stream &) = delete; + /** Default move constructor */ + Stream(Stream &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + Stream &operator=(const Stream &) = delete; + /** Default move assignment operator */ + Stream &operator=(Stream &&) = default; + /** Finalizes the stream for an execution target + * + * @param[in] target Execution target + * @param[in] config (Optional) Graph configuration to use + */ + void finalize(Target target, const GraphConfig &config); + /** Executes the stream **/ + void run(); + + // Inherited overridden methods + void add_layer(ILayer &layer) override; + Graph &graph() override; + const Graph &graph() const override; + +private: + GraphManager _manager; /**< Graph manager */ + GraphContext _ctx; /**< Graph context to use */ + Graph _g; /**< Internal graph representation of the stream */ +}; +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_STREAM_H__ */
\ No newline at end of file diff --git a/arm_compute/graph/frontend/SubStream.h b/arm_compute/graph/frontend/SubStream.h new file mode 100644 index 0000000000..c084899c66 --- /dev/null +++ b/arm_compute/graph/frontend/SubStream.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_SUB_STREAM_H__ +#define __ARM_COMPUTE_GRAPH_SUB_STREAM_H__ + +#include "arm_compute/graph/frontend/IStream.h" +#include "arm_compute/graph/frontend/IStreamOperators.h" +#include "arm_compute/graph/frontend/Types.h" + +#include <memory> +#include <vector> + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; + +namespace frontend +{ +// Forward declarations +class ILayer; + +/** Sub stream class*/ +class SubStream final : public IStream +{ +public: + /** Default Constructor + * + * @param[in] s Parent stream + */ + SubStream(IStream &s); + /** Prevent instances of this class from being copied (As this class contains pointers) */ + SubStream(const SubStream &) = delete; + /** Default move constructor */ + SubStream(SubStream &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + SubStream &operator=(const SubStream &) = delete; + /** Default move assignment operator */ + SubStream &operator=(SubStream &&) = default; + + // Inherited overridden methods + void add_layer(ILayer &layer) override; + Graph &graph() override; + const Graph &graph() const override; + +private: + IStream &_s; /**< Parent stream (assume that the lifetime of the parent is longer) */ +}; +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_SUB_STREAM_H__ */ diff --git a/arm_compute/graph/frontend/Types.h b/arm_compute/graph/frontend/Types.h new file mode 100644 index 0000000000..78644e66af --- /dev/null +++ b/arm_compute/graph/frontend/Types.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_STREAM_TYPES_H__ +#define __ARM_COMPUTE_GRAPH_STREAM_TYPES_H__ + +#include "arm_compute/graph/Types.h" + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +// Import types for graph +using graph::DataType; +using graph::TensorShape; + +using graph::ActivationLayerInfo; +using graph::NormalizationLayerInfo; +using graph::NormType; +using graph::PadStrideInfo; +using graph::PoolingLayerInfo; +using graph::PoolingType; +using graph::Target; +using graph::ConvolutionMethod; +using graph::DepthwiseConvolutionMethod; +using graph::TensorDescriptor; +using graph::DimensionRoundingType; +using graph::GraphConfig; + +/** Branch layer merging method */ +enum class BranchMergeMethod +{ + DEPTH_CONCATENATE, /**< Concatenate across depth */ + ADD /**< Adds the results of each stream */ +}; + +/** Hints that can be passed to the stream to expose parameterization */ +struct StreamHints +{ + Target target_hint = { Target::UNSPECIFIED }; /**< Target execution hint */ + ConvolutionMethod convolution_method_hint = { ConvolutionMethod::DEFAULT }; /**< Convolution method hint */ + DepthwiseConvolutionMethod depthwise_convolution_method_hint = { DepthwiseConvolutionMethod::DEFAULT }; /**< Depthwise Convolution method hint */ +}; +} // namespace frontend +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_STREAM_TYPES_H__ */
\ No newline at end of file diff --git a/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h b/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h new file mode 100644 index 0000000000..0ddd3fa5e6 --- /dev/null +++ b/arm_compute/graph/mutators/DepthConcatSubTensorMutator.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ +#define __ARM_COMPUTE_GRAPH_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ + +#include "arm_compute/graph/IGraphMutator.h" + +namespace arm_compute +{ +namespace graph +{ +/** Mutation pass to optimize depth concatenation operations by using sub-tensors + * + * @warning Always run as one of the last mutation pass as optimizations might change the parent of sub-tensors. + **/ +class DepthConcatSubTensorMutator final : public IGraphMutator +{ +public: + // Inherited methods overridden + virtual void mutate(Graph &g) override; + const char *name() override; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ */ diff --git a/arm_compute/graph/mutators/GraphMutators.h b/arm_compute/graph/mutators/GraphMutators.h new file mode 100644 index 0000000000..a91bc91a12 --- /dev/null +++ b/arm_compute/graph/mutators/GraphMutators.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_GRAPH_MUTATORS_H__ +#define __ARM_COMPUTE_GRAPH_GRAPH_MUTATORS_H__ + +#include "arm_compute/graph/mutators/DepthConcatSubTensorMutator.h" +#include "arm_compute/graph/mutators/InPlaceOperationMutator.h" +#include "arm_compute/graph/mutators/NodeFusionMutator.h" +#include "arm_compute/graph/mutators/SplitLayerSubTensorMutator.h" + +#endif /* __ARM_COMPUTE_GRAPH_GRAPH_MUTATORS_H__ */ diff --git a/arm_compute/graph/mutators/InPlaceOperationMutator.h b/arm_compute/graph/mutators/InPlaceOperationMutator.h new file mode 100644 index 0000000000..69de2f10b1 --- /dev/null +++ b/arm_compute/graph/mutators/InPlaceOperationMutator.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_INPLACE_OPERATION_MUTATOR_H__ +#define __ARM_COMPUTE_GRAPH_INPLACE_OPERATION_MUTATOR_H__ + +#include "arm_compute/graph/IGraphMutator.h" + +namespace arm_compute +{ +namespace graph +{ +/** Mutation pass to optimize operations that can be performed in-place */ +class InPlaceOperationMutator final : public IGraphMutator +{ +public: + // Inherited methods overridden + virtual void mutate(Graph &g) override; + const char *name() override; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_INPLACE_OPERATION_MUTATOR_H__ */ diff --git a/arm_compute/graph/mutators/NodeFusionMutator.h b/arm_compute/graph/mutators/NodeFusionMutator.h new file mode 100644 index 0000000000..8f16c65dfa --- /dev/null +++ b/arm_compute/graph/mutators/NodeFusionMutator.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_NODE_FUSION_MUTATOR_H__ +#define __ARM_COMPUTE_GRAPH_NODE_FUSION_MUTATOR_H__ + +#include "arm_compute/graph/IGraphMutator.h" + +namespace arm_compute +{ +namespace graph +{ +namespace detail +{ +/** Fused batch normalization with activation + * + * @param[in] g Graph to perform operation fusion on + */ +void fuse_batch_norm_with_activation(Graph &g); +} // namespace detail + +/** Mutation pass to fuss nodes */ +class NodeFusionMutator final : public IGraphMutator +{ +public: + // Inherited methods overridden + virtual void mutate(Graph &g) override; + const char *name() override; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_NODE_FUSION_MUTATOR_H__ */ diff --git a/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h b/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h new file mode 100644 index 0000000000..f349bb9a8c --- /dev/null +++ b/arm_compute/graph/mutators/SplitLayerSubTensorMutator.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ +#define __ARM_COMPUTE_GRAPH_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ + +#include "arm_compute/graph/IGraphMutator.h" + +namespace arm_compute +{ +namespace graph +{ +/** Mutation pass to optimize split operations by using sub-tensors + * + * @warning This is compulsory to run in case Split layers are present in the model + **/ +class SplitLayerSubTensorMutator final : public IGraphMutator +{ +public: + // Inherited methods overridden + virtual void mutate(Graph &g) override; + const char *name() override; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ */ diff --git a/arm_compute/graph/nodes/L2NormalizeLayer.h b/arm_compute/graph/nodes/ActivationLayerNode.h index a423306bd2..985e10a8d8 100644 --- a/arm_compute/graph/nodes/L2NormalizeLayer.h +++ b/arm_compute/graph/nodes/ActivationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,36 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_L2NORMALIZE_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_L2NORMALIZE_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** L2NormalizeLayer layer node */ -class L2NormalizeLayer final : public INode +/** Activation Layer node */ +class ActivationLayerNode final : public INode { public: - /** Default Constructor + /** Constructor * - * @param[in] axis Dimension along which to reduce. - * @param[in] epsilon Lower bound value for the normalization. + * @param[in] info Activation Layer information */ - explicit L2NormalizeLayer(unsigned int axis, float epsilon); + ActivationLayerNode(ActivationLayerInfo info); + /** Activation metadata accessor + * + * @return The activation info of the layer + */ + ActivationLayerInfo activation_info() const; - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; private: - unsigned int _axis; - float _epsilon; + ActivationLayerInfo _info; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_L2NORMALIZE_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/BatchNormalizationLayer.h b/arm_compute/graph/nodes/BatchNormalizationLayer.h deleted file mode 100644 index abbf09a54e..0000000000 --- a/arm_compute/graph/nodes/BatchNormalizationLayer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_BATCHNORMALIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_BATCHNORMALIZATION_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" - -namespace arm_compute -{ -namespace graph -{ -/** BatchNormalization layer node */ -class BatchNormalizationLayer final : public INode -{ -public: - /** Default constructor - * - * @param[in] mean Mean values tensor - * @param[in] var Var values tensor - * @param[in] gamma Gamma values tensor - * @param[in] beta Beta values tensor - * @param[in] epsilon Epsilon value - * @param[in] act_info (Optional) Activation layer information in case of a fused activation. Only RELU, BOUNDED_RELU and LU_BOUNDED_RELU supported. - */ - template <typename AccessorType> - BatchNormalizationLayer(AccessorType &&mean, AccessorType &&var, AccessorType &&gamma, AccessorType &&beta, float epsilon, ActivationLayerInfo act_info = ActivationLayerInfo()) - : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon), _act_info(act_info) - { - set_supports_in_place(true); - } - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - Tensor _mean; - Tensor _var; - Tensor _gamma; - Tensor _beta; - float _epsilon; - ActivationLayerInfo _act_info; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_BATCHNORMALIZATION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/BatchNormalizationLayerNode.h b/arm_compute/graph/nodes/BatchNormalizationLayerNode.h new file mode 100644 index 0000000000..b36d66993b --- /dev/null +++ b/arm_compute/graph/nodes/BatchNormalizationLayerNode.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_BATCH_NORMALIZATION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_BATCH_NORMALIZATION_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Batch Normalization Layer node */ +class BatchNormalizationLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] epsilon (Optional) Epsilon parameter. Defaults to 1.f + * @param[in] fused_activation (Optional) Fused activation layer. Disabled if not specified + */ + BatchNormalizationLayerNode(float epsilon = 1.f, ActivationLayerInfo fused_activation = ActivationLayerInfo()); + /** Epsilon parameter accessor + * + * @return Epsilon parameter + */ + float epsilon() const; + /** Returns fused activation + * + * @return Fused activation + */ + ActivationLayerInfo fused_activation() const; + /** Sets fused activation + * + * @param[in] fused_activation Fused activation to set + */ + void set_fused_activation(ActivationLayerInfo fused_activation); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + float _epsilon; + ActivationLayerInfo _fused_activation; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_BATCH_NORMALIZATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/BranchLayer.h b/arm_compute/graph/nodes/BranchLayer.h deleted file mode 100644 index cbc016d043..0000000000 --- a/arm_compute/graph/nodes/BranchLayer.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_BRANCH_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_BRANCH_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/SubGraph.h" -#include "arm_compute/graph/SubTensor.h" -#include "arm_compute/graph/Types.h" - -#include "arm_compute/core/utils/misc/Utility.h" - -#include <vector> - -namespace arm_compute -{ -namespace graph -{ -/** Branch Layer node */ -class BranchLayer final : public INode -{ -public: - /** Default Constructor - * - * @param[in] merge_method Branch merging method - * @param[in] sub_graph1 First graph branch - * @param[in] sub_graph2 Second graph branch - * @param[in] rest_sub_graphs Rest sub-graph branches - */ - template <typename... Ts> - BranchLayer(BranchMergeMethod merge_method, SubGraph &&sub_graph1, SubGraph &&sub_graph2, Ts &&... rest_sub_graphs) - : _branch_merge_method(merge_method), _sub_graphs() - { - /* TODO:(geopin01) Use traits to make sure variadic arguments are of SubGraph type */ - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph1))); - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph2))); - - utility::for_each([&](SubGraph && sub_graph) - { - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph))); - }, - std::move(rest_sub_graphs)...); - } - /** Default Constructor - * - * @param[in] sub_graph Sub graph - */ - template <typename... Ts> - BranchLayer(SubGraph &&sub_graph) - : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_graphs() - { - /* TODO:(geopin01) Use traits to make sure variadic arguments are of SubGraph type */ - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph))); - } - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - BranchMergeMethod _branch_merge_method; - std::vector<std::unique_ptr<SubGraph>> _sub_graphs; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_BRANCH_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/ConstNode.h b/arm_compute/graph/nodes/ConstNode.h new file mode 100644 index 0000000000..346a3c82e7 --- /dev/null +++ b/arm_compute/graph/nodes/ConstNode.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_CONST_NODE_H__ +#define __ARM_COMPUTE_GRAPH_CONST_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Const node */ +class ConstNode final : public INode +{ +public: + /** Constructor + * + * @param[in] desc Tensor descriptor + */ + ConstNode(TensorDescriptor desc); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + TensorDescriptor _desc; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_CONST_NODE_H__ */ diff --git a/arm_compute/graph/nodes/ConvolutionLayer.h b/arm_compute/graph/nodes/ConvolutionLayer.h deleted file mode 100644 index 1806190971..0000000000 --- a/arm_compute/graph/nodes/ConvolutionLayer.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/SubTensor.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" - -#include <memory> - -namespace arm_compute -{ -namespace graph -{ -/** Convolution layer node */ -class ConvolutionLayer final : public INode -{ -public: - /** Default Constructor - * - * @param[in] conv_width Convolution width - * @param[in] conv_height Convolution height - * @param[in] ofm Output feature map - * @param[in] weights Weights of the convolution layer - * @param[in] biases Bias of the convolution layer - * @param[in] conv_info Convolution information - * @param[in] num_groups (Optional) Number of groups, default = 1 - * @param[in] weights_info (Optional) Weights information - * @param[in] weights_quant_info (Optional) Weights quantization information - * @param[in] out_quant_info (Optional) Output quantization info - */ - template <typename AccessorTypeWeights, typename AccessorTypeBiases> - ConvolutionLayer(unsigned int conv_width, - unsigned int conv_height, - unsigned int ofm, - AccessorTypeWeights &&weights, - AccessorTypeBiases &&biases, - const PadStrideInfo conv_info, - unsigned int num_groups = 1, - const WeightsInfo weights_info = WeightsInfo(), - const QuantizationInfo weights_quant_info = QuantizationInfo(), - const QuantizationInfo out_quant_info = QuantizationInfo()) - : _conv_width(conv_width), - _conv_height(conv_height), - _ofm(ofm), - _weights(std::move(weights)), - _biases(std::move(biases)), - _conv_info(std::move(conv_info)), - _num_groups(num_groups), - _weights_info(std::move(weights_info)), - _weights_quant_info(std::move(weights_quant_info)), - _out_quant_info(std::move(out_quant_info)), - _is(nullptr), - _os(nullptr), - _ws(nullptr), - _bs(nullptr) - { - } - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - /** Instantiates a non-grouped convolution - * - * @param[in] input Input tensor - * @param[in] output Output tensor - * @param[in] conv_method_hint Hint that specifies which convolution layer method to use - * - * @return Convolution function - */ - std::unique_ptr<arm_compute::IFunction> instantiate_convolution(ITensor *input, ITensor *output, ConvolutionMethodHint conv_method_hint); - /** Instantiates a grouped convolution - * - * @param[in] input Input tensor - * @param[in] output Output tensor - * @param[in] conv_method_hint Hint that specifies which convolution layer method to use - * - * @return Grouped Convolution function - */ - std::unique_ptr<arm_compute::IFunction> instantiate_grouped_convolution(ITensor *input, ITensor *output, ConvolutionMethodHint conv_method_hint); - -private: - unsigned int _conv_width; /**< Convolution width */ - unsigned int _conv_height; /**< Convolution height */ - unsigned int _ofm; /**< Output feature maps */ - Tensor _weights; /**< Weights tensor */ - Tensor _biases; /**< Biases tensor */ - const PadStrideInfo _conv_info; /**< Convolution layer information */ - unsigned int _num_groups; /**< Number of groups */ - const WeightsInfo _weights_info; /**< Convolution layer weights information */ - const QuantizationInfo _weights_quant_info; /**< Output quantization information */ - const QuantizationInfo _out_quant_info; /**< Output quantization information */ - - std::unique_ptr<SubTensor[]> _is; /**< Input tensor sub-tensors used for grouped convolution */ - std::unique_ptr<SubTensor[]> _os; /**< Output tensor sub-tensors used for grouped convolution */ - std::unique_ptr<SubTensor[]> _ws; /**< Weights tensor sub-tensors used for grouped convolution */ - std::unique_ptr<SubTensor[]> _bs; /**< Biases tensor sub-tensors used for grouped convolution */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/ConvolutionLayerNode.h b/arm_compute/graph/nodes/ConvolutionLayerNode.h new file mode 100644 index 0000000000..70fefbeeab --- /dev/null +++ b/arm_compute/graph/nodes/ConvolutionLayerNode.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Convolution Layer node */ +class ConvolutionLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] info Convolution layer attributes + * @param[in] method (Optional) Convolution method to use + */ + ConvolutionLayerNode(PadStrideInfo info, ConvolutionMethod method = ConvolutionMethod::DEFAULT); + /** Sets the convolution layer method to use + * + * @param[in] method Method to use for convolution + */ + void set_convolution_method(ConvolutionMethod method); + /** Convolution layer method accessor + * + * @note This is an indication on which convolution layer implementation to use, + * if it fails to be created the library's heuristic approach will be used + * + * @return Convolution layer method do be used by the node + */ + ConvolutionMethod convolution_method() const; + /** Convolution metadata accessor + * + * @return Convolution information + */ + PadStrideInfo convolution_info() const; + /** Computes convolution output shape + * + * @param[in] input_shape Input shape + * @param[in] weights_shape Weights shape + * @param[in] info Convolution operation attributes + * + * @return Output shape + */ + static TensorShape compute_output_shape(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo info); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + PadStrideInfo _info; + ConvolutionMethod _method; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_CONVOLUTION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/DepthConcatenateLayerNode.h b/arm_compute/graph/nodes/DepthConcatenateLayerNode.h new file mode 100644 index 0000000000..cb309f38c1 --- /dev/null +++ b/arm_compute/graph/nodes/DepthConcatenateLayerNode.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_DEPTH_CONCATENATE_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_DEPTH_CONCATENATE_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Depth Concatenation Layer node */ +class DepthConcatenateLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] total_nodes Number of nodes that will get concatenated + */ + DepthConcatenateLayerNode(unsigned int total_nodes); + /** Computes depth concatenations output shape + * + * @param input_shapes Shapes of the inputs + * + * @return Expected output shape + */ + static TensorShape compute_output_shape(const std::vector<TensorShape> &input_shapes); + /** Disables or not the depth concatenate node + * + * @warning This is used when depth concatenate is performed with sub-tensors, + * where this node is used as a placeholder. + * + * @param[in] is_enabled If true a backend function is created to perform the depth concatenation (involves copying), + * while if false, no function is created and we assume that subtensors are properly set to simulate + * a no copy operation. + */ + void set_enabled(bool is_enabled); + /** Enabled parameter accessor + * + * @return True if a backend function is to be created else false + */ + bool is_enabled() const; + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + unsigned int _total_nodes; + bool _is_enabled; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_DEPTH_CONCATENATE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/DepthwiseConvolutionLayer.h b/arm_compute/graph/nodes/DepthwiseConvolutionLayer.h deleted file mode 100644 index 2d4bd1e0c2..0000000000 --- a/arm_compute/graph/nodes/DepthwiseConvolutionLayer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/SubTensor.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" - -#include <memory> - -namespace arm_compute -{ -namespace graph -{ -/** Convolution layer node */ -class DepthwiseConvolutionLayer final : public INode -{ -public: - /** Default constructor - * - * @param[in] conv_width Convolution width - * @param[in] conv_height Convolution height - * @param[in] weights Weights values tensor - * @param[in] biases Biases values tensor - * @param[in] conv_info Convolution info - * @param[in] opt3x3 (Optional) If true executes DepthwiseConvolutionLayer3x3 - * @param[in] quant_info (Optional) Quantization info used for weights - */ - template <typename AccessorType> - DepthwiseConvolutionLayer(unsigned int conv_width, unsigned int conv_height, AccessorType &&weights, AccessorType &&biases, const PadStrideInfo conv_info, bool opt3x3 = true, - const QuantizationInfo quant_info = QuantizationInfo()) - : _conv_width(conv_width), _conv_height(conv_height), _weights(std::move(weights)), _biases(std::move(biases)), _conv_info(conv_info), _opt3x3(opt3x3), _quant_info(std::move(quant_info)) - { - } - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - unsigned int _conv_width; - unsigned int _conv_height; - Tensor _weights; - Tensor _biases; - const PadStrideInfo _conv_info; - bool _opt3x3; - const QuantizationInfo _quant_info; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h b/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h new file mode 100644 index 0000000000..b4cf9b4d03 --- /dev/null +++ b/arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Depthwise Convolution Layer node */ +class DepthwiseConvolutionLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] info Convolution layer attributes + * @param[in] method Depthwise convolution method to use + */ + DepthwiseConvolutionLayerNode(PadStrideInfo info, DepthwiseConvolutionMethod method = DepthwiseConvolutionMethod::DEFAULT); + /** Sets the depthwise convolution method to use + * + * @param[in] method Depthwise convolution method to use + */ + void set_depthwise_convolution_method(DepthwiseConvolutionMethod method); + /** Depthwise convolution layer method accessor + * + * @note This is an indication on which depthwise implementation to use, + * if it fails to be created the generic approach will be used + * + * @return Depthwise convolution layer method do be used by the node + */ + DepthwiseConvolutionMethod depthwise_convolution_method() const; + /** Convolution metadata accessor + * + * @return Convolution information + */ + PadStrideInfo convolution_info() const; + /** Computes depthwise convolution output shape + * + * @param[in] input_shape Input shape + * @param[in] weights_shape Weights shape + * @param[in] info Convolution operation attributes + * + * @return Output shape + */ + static TensorShape compute_output_shape(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo info); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + PadStrideInfo _info; + DepthwiseConvolutionMethod _method; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/DequantizationLayer.h b/arm_compute/graph/nodes/EltwiseLayerNode.h index f9b7e8af87..9da88d75b5 100644 --- a/arm_compute/graph/nodes/DequantizationLayer.h +++ b/arm_compute/graph/nodes/EltwiseLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,39 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_DEQUANTIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_DEQUANTIZATION_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** DequantizationLayer layer node */ -class DequantizationLayer final : public INode +/** Eltwise Layer node */ +class EltwiseLayerNode final : public INode { public: - /** Default constructor + /** Constructor * - * @param[in] min_max Min max value tensor + * @param[in] op Element-wise operation to perform */ - template <typename AccessorType> - DequantizationLayer(AccessorType &&min_max) - : _min_max(std::move(min_max)) - { - } + EltwiseLayerNode(EltwiseOperation op); + /** Eltwise operation accessor + * + * @return Eltwise operation that is to be performed by the node + */ + EltwiseOperation eltwise_operation() const; - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; private: - Tensor _min_max; + EltwiseOperation _op; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_DEQUANTIZATION_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/FlattenLayerNode.h b/arm_compute/graph/nodes/FlattenLayerNode.h new file mode 100644 index 0000000000..f0dde1fab1 --- /dev/null +++ b/arm_compute/graph/nodes/FlattenLayerNode.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Flatten Layer node */ +class FlattenLayerNode final : public INode +{ +public: + /** Default Constructor */ + FlattenLayerNode(); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/FullyConnectedLayer.h b/arm_compute/graph/nodes/FullyConnectedLayer.h deleted file mode 100644 index 270676a6b5..0000000000 --- a/arm_compute/graph/nodes/FullyConnectedLayer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/graph/Types.h" - -namespace arm_compute -{ -namespace graph -{ -/** Fully connected layer node */ -class FullyConnectedLayer final : public INode -{ -public: - /** Default constructor - * - * @param[in] num_neurons Number of neurons - * @param[in] weights Weights of the fully connected layer - * @param[in] biases Biases of the fully connected layer - */ - template <typename AccessorTypeWeights, typename AccessorTypeBiases> - FullyConnectedLayer(unsigned int num_neurons, AccessorTypeWeights &&weights, AccessorTypeBiases &&biases) - : _num_neurons(num_neurons), _weights(std::move(weights)), _biases(std::move(biases)) - { - } - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - - // Inherited methods overriden: -private: - unsigned int _num_neurons; /**< Number of neurons */ - Tensor _weights; /**< Weights tensor */ - Tensor _biases; /**< Biases tensor */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/FullyConnectedLayerNode.h b/arm_compute/graph/nodes/FullyConnectedLayerNode.h new file mode 100644 index 0000000000..166751b8fa --- /dev/null +++ b/arm_compute/graph/nodes/FullyConnectedLayerNode.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Fully Connected Layer node */ +class FullyConnectedLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] num_outputs Number of neurons in the layer + */ + FullyConnectedLayerNode(unsigned int num_outputs); + /** Computes weights shape + * + * @warning Works for inputs with 1D batch space + * + * @param[in] input_shape Input shape + * @param[in] num_outputs Number of output neurons + * + * @return Weights shape + */ + static TensorShape compute_weights_shape(TensorShape input_shape, unsigned int num_outputs); + /** Computes fully connected layer output shape + * + * @warning Works for inputs with 1D batch space + * + * @param[in] input_shape Input shape + * @param[in] num_outputs Number of output neurons + * + * @return Output shape + */ + static TensorShape compute_output_shape(TensorShape input_shape, unsigned int num_outputs); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + unsigned int _num_outputs; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_FULLY_CONNECTED_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/InputNode.h b/arm_compute/graph/nodes/InputNode.h new file mode 100644 index 0000000000..cacea95ab8 --- /dev/null +++ b/arm_compute/graph/nodes/InputNode.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_INPUT_NODE_H__ +#define __ARM_COMPUTE_GRAPH_INPUT_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Input Layer node */ +class InputNode final : public INode +{ +public: + /** Constructor + * + * @param[in] desc Tensor descriptor + */ + InputNode(TensorDescriptor desc); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + TensorDescriptor _desc; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_INPUT_NODE_H__ */ diff --git a/arm_compute/graph/Nodes.h b/arm_compute/graph/nodes/Nodes.h index 3009a24fcb..c39546c6bd 100644 --- a/arm_compute/graph/Nodes.h +++ b/arm_compute/graph/nodes/Nodes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -24,22 +24,21 @@ #ifndef __ARM_COMPUTE_GRAPH_NODES_H__ #define __ARM_COMPUTE_GRAPH_NODES_H__ -#include "arm_compute/graph/nodes/ActivationLayer.h" -#include "arm_compute/graph/nodes/BatchNormalizationLayer.h" -#include "arm_compute/graph/nodes/BranchLayer.h" -#include "arm_compute/graph/nodes/ConvolutionLayer.h" -#include "arm_compute/graph/nodes/DepthConvertLayer.h" -#include "arm_compute/graph/nodes/DepthwiseConvolutionLayer.h" -#include "arm_compute/graph/nodes/DequantizationLayer.h" -#include "arm_compute/graph/nodes/FlattenLayer.h" -#include "arm_compute/graph/nodes/FloorLayer.h" -#include "arm_compute/graph/nodes/FullyConnectedLayer.h" -#include "arm_compute/graph/nodes/L2NormalizeLayer.h" -#include "arm_compute/graph/nodes/NormalizationLayer.h" -#include "arm_compute/graph/nodes/PoolingLayer.h" -#include "arm_compute/graph/nodes/QuantizationLayer.h" -#include "arm_compute/graph/nodes/ReshapeLayer.h" -#include "arm_compute/graph/nodes/ResidualLayer.h" -#include "arm_compute/graph/nodes/SoftmaxLayer.h" +#include "arm_compute/graph/nodes/ActivationLayerNode.h" +#include "arm_compute/graph/nodes/BatchNormalizationLayerNode.h" +#include "arm_compute/graph/nodes/ConstNode.h" +#include "arm_compute/graph/nodes/ConvolutionLayerNode.h" +#include "arm_compute/graph/nodes/DepthConcatenateLayerNode.h" +#include "arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h" +#include "arm_compute/graph/nodes/EltwiseLayerNode.h" +#include "arm_compute/graph/nodes/FlattenLayerNode.h" +#include "arm_compute/graph/nodes/FullyConnectedLayerNode.h" +#include "arm_compute/graph/nodes/InputNode.h" +#include "arm_compute/graph/nodes/NormalizationLayerNode.h" +#include "arm_compute/graph/nodes/OutputNode.h" +#include "arm_compute/graph/nodes/PoolingLayerNode.h" +#include "arm_compute/graph/nodes/ReshapeLayerNode.h" +#include "arm_compute/graph/nodes/SoftmaxLayerNode.h" +#include "arm_compute/graph/nodes/SplitLayerNode.h" #endif /* __ARM_COMPUTE_GRAPH_NODES_H__ */ diff --git a/arm_compute/graph/nodes/NodesFwd.h b/arm_compute/graph/nodes/NodesFwd.h new file mode 100644 index 0000000000..b90cb5c308 --- /dev/null +++ b/arm_compute/graph/nodes/NodesFwd.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_NODES_FWD_H__ +#define __ARM_COMPUTE_GRAPH_NODES_FWD_H__ + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; +class ActivationLayerNode; +class BatchNormalizationLayerNode; +class ConstNode; +class ConvolutionLayerNode; +class DepthConcatenateLayerNode; +class DepthwiseConvolutionLayerNode; +class EltwiseLayerNode; +class FlattenLayerNode; +class FullyConnectedLayerNode; +class InputNode; +class NormalizationLayerNode; +class OutputNode; +class PoolingLayerNode; +class ReshapeLayerNode; +class SoftmaxLayerNode; +class SplitLayerNode; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_NODES_FWD_H__ */ diff --git a/arm_compute/graph/nodes/NormalizationLayer.h b/arm_compute/graph/nodes/NormalizationLayerNode.h index e1c45094d8..34dc3ccf8f 100644 --- a/arm_compute/graph/nodes/NormalizationLayer.h +++ b/arm_compute/graph/nodes/NormalizationLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,34 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** Normalization layer node */ -class NormalizationLayer final : public INode +/** Normalization Layer node */ +class NormalizationLayerNode final : public INode { public: - /** Default Constructor + /** Constructor * - * @param[in] norm_info Normalization layer information + * @param[in] norm_info Normalization Layer information */ - explicit NormalizationLayer(const NormalizationLayerInfo norm_info); + NormalizationLayerNode(NormalizationLayerInfo norm_info); + /** Normalization info accessor + * + * @return Normalization layer info + */ + NormalizationLayerInfo normalization_info() const; - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; private: - const NormalizationLayerInfo _norm_info; /**< Normalization layer information */ + NormalizationLayerInfo _info; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/QuantizationLayer.h b/arm_compute/graph/nodes/OutputNode.h index a3ef02530e..46988cf969 100644 --- a/arm_compute/graph/nodes/QuantizationLayer.h +++ b/arm_compute/graph/nodes/OutputNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,25 +21,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_QUANTIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_QUANTIZATION_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__ +#define __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** Quantization layer node */ -class QuantizationLayer final : public INode +/** Output Layer node */ +class OutputNode final : public INode { public: - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + /** Default Constructor */ + OutputNode(); + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_QUANTIZATION_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__ */ diff --git a/arm_compute/graph/nodes/PoolingLayer.h b/arm_compute/graph/nodes/PoolingLayer.h deleted file mode 100644 index 5c45bc04ed..0000000000 --- a/arm_compute/graph/nodes/PoolingLayer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2017 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" - -namespace arm_compute -{ -namespace graph -{ -/** Pooling layer node */ -class PoolingLayer final : public INode -{ -public: - /** Default Constructor - * - * @param pool_info Pooling layer information - */ - PoolingLayer(const PoolingLayerInfo pool_info); - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - const PoolingLayerInfo _pool_info; /**< Pooling layer information */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_POOLING_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/DepthConvertLayer.h b/arm_compute/graph/nodes/PoolingLayerNode.h index 03bf9b7ed5..e250eb247a 100644 --- a/arm_compute/graph/nodes/DepthConvertLayer.h +++ b/arm_compute/graph/nodes/PoolingLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,38 +21,48 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_DEPTHCONVERT_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_DEPTHCONVERT_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** DepthConvertLayer layer node */ -class DepthConvertLayer final : public INode +/** Pooling Layer node */ +class PoolingLayerNode final : public INode { public: - /** Default constructor + /** Constructor * - * @param[in] policy Convertion policy - * @param[in] shift Shift value - * @param[in] output_datatype Output datatype + * @param[in] pool_info Pooling Layer information */ - DepthConvertLayer(const ConvertPolicy policy, uint32_t shift, DataType output_datatype); + PoolingLayerNode(PoolingLayerInfo pool_info); + /** Pooling metadata accessor + * + * @return Pooling Layer info + */ + PoolingLayerInfo pooling_info() const; + /** Computes pooling output shape + * + * @param[in] input_shape Input shape + * @param[in] info Pooling operation attributes + * + * @return Output shape + */ + static TensorShape compute_output_shape(TensorShape input_shape, PoolingLayerInfo info); - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; private: - const ConvertPolicy _policy; - uint32_t _shift; - DataType _output_datatype; + PoolingLayerInfo _info; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_DEPTHCONVERT_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/ReshapeLayer.h b/arm_compute/graph/nodes/ReshapeLayerNode.h index b727d33a2c..ded344e041 100644 --- a/arm_compute/graph/nodes/ReshapeLayer.h +++ b/arm_compute/graph/nodes/ReshapeLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,34 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** Reshape layer node */ -class ReshapeLayer final : public INode +/** Reshape Layer node */ +class ReshapeLayerNode final : public INode { public: - /** Default constructor + /** Constructor * - * @param[in] shape Output shape + * @param[in] shape Reshaped tensor shape */ - ReshapeLayer(const TensorShape shape); + ReshapeLayerNode(TensorShape shape); - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; private: TensorShape _shape; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/ResidualLayer.h b/arm_compute/graph/nodes/ResidualLayer.h deleted file mode 100644 index 27e0501739..0000000000 --- a/arm_compute/graph/nodes/ResidualLayer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2017-2018 ARM Limited. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef __ARM_COMPUTE_GRAPH_RESIDUAL_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_RESIDUAL_LAYER_H__ - -#include "arm_compute/graph/GraphContext.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/SubGraph.h" -#include "arm_compute/graph/Types.h" - -#include "arm_compute/core/utils/misc/Utility.h" - -#include <vector> - -namespace arm_compute -{ -namespace graph -{ -/** Branch Layer node */ -class ResidualLayer final : public INode -{ -public: - /** Default Constructor - * - * @param[in] sub_graph1 First graph branch - * @param[in] sub_graph2 Second graph branch - */ - template <typename... Ts> - ResidualLayer(SubGraph &&sub_graph1, SubGraph &&sub_graph2) - : _sub_graphs() - { - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph1))); - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph2))); - } - /** Default Constructor - * - * @param[in] sub_graph Sub graph - */ - template <typename... Ts> - ResidualLayer(SubGraph &&sub_graph) - : _sub_graphs() - { - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique<SubGraph>(std::move(sub_graph))); - } - - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - std::vector<std::unique_ptr<SubGraph>> _sub_graphs; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_RESIDUAL_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/ActivationLayer.h b/arm_compute/graph/nodes/SoftmaxLayerNode.h index bc619a8df9..8b716047ff 100644 --- a/arm_compute/graph/nodes/ActivationLayer.h +++ b/arm_compute/graph/nodes/SoftmaxLayerNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,34 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__ +#ifndef __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__ -#include "arm_compute/graph/GraphContext.h" #include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Types.h" namespace arm_compute { namespace graph { -/** Activation Layer node */ -class ActivationLayer final : public INode +/** Softmax Layer node */ +class SoftmaxLayerNode final : public INode { public: - /** Default Constructor + /** Constructor * - * @param[in] activation_info Activation layer info + * @param[in] beta (Optional) Beta parameter. Defaults to 1 */ - ActivationLayer(const ActivationLayerInfo activation_info); + SoftmaxLayerNode(float beta = 1.f); + /** Beta parameter accessor + * + * @return Beta parameter + */ + float beta() const; - // Inherited methods overriden: - std::unique_ptr<arm_compute::IFunction> instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; private: - const ActivationLayerInfo _activation_info; /**< Activation layer info */ + float _beta; }; } // namespace graph } // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__ */ +#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/SplitLayerNode.h b/arm_compute/graph/nodes/SplitLayerNode.h new file mode 100644 index 0000000000..923b3d1fa6 --- /dev/null +++ b/arm_compute/graph/nodes/SplitLayerNode.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_SPLIT_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_SPLIT_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +#include <tuple> + +namespace arm_compute +{ +namespace graph +{ +/** Split Layer node */ +class SplitLayerNode final : public INode +{ +public: + /** Default Constructor + * + * @param[in] num_splits Number of splits + * @param[in] axis (Optional) Axis to split on. Supported axis >= 2. Defaults to 0 + */ + SplitLayerNode(unsigned int num_splits, unsigned int axis = 0); + /** Computes split layer output shape + * + * @param[in] input_shape Shape of the input + * @param[in] num_splits Number of splits + * @param[in] axis Axis to perform the split on + * @param[in] idx Index of the split + * + * @return A pair with the shape of the split and the starting coordinates + */ + static std::pair<TensorShape, Coordinates> compute_output_shape(TensorShape input_shape, unsigned int num_splits, unsigned int axis, unsigned int idx); + /** Number of splits accessor + * + * @return Number of splits + */ + unsigned int num_splits() const; + /** Split axis accessor + * + * @return Split axis + */ + unsigned int axis() const; + + // Inherited overridden methods: + Status validate() override; + NodeType type() const override; + bool forward_descriptors() override; + TensorDescriptor configure_output(size_t idx) const override; + void accept(INodeVisitor &v) override; + +private: + unsigned int _num_splits; + unsigned int _axis; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_SPLIT_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/printers/DotGraphPrinter.h b/arm_compute/graph/printers/DotGraphPrinter.h new file mode 100644 index 0000000000..1d355a52ee --- /dev/null +++ b/arm_compute/graph/printers/DotGraphPrinter.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H__ +#define __ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H__ + +#include "arm_compute/graph/IGraphPrinter.h" + +#include "arm_compute/graph/INodeVisitor.h" + +#include <string> + +namespace arm_compute +{ +namespace graph +{ +/** Graph printer visitor. */ +class DotGraphVisitor final : public DefaultNodeVisitor +{ +public: + /** Default Constructor **/ + DotGraphVisitor() = default; + /** Returns the output information of the last visited node + * + * @return Information of the last visited node + */ + const std::string &info() const; + + // Reveal parent method + using DefaultNodeVisitor::visit; + + // Inherited methods overridden + void visit(ActivationLayerNode &n) override; + void visit(BatchNormalizationLayerNode &n) override; + void visit(ConvolutionLayerNode &n) override; + void visit(DepthConcatenateLayerNode &n) override; + void visit(DepthwiseConvolutionLayerNode &n) override; + void visit(EltwiseLayerNode &n) override; + void visit(NormalizationLayerNode &n) override; + void visit(PoolingLayerNode &n) override; + void default_visit() override; + +private: + std::string _info{}; +}; + +/** Graph printer interface */ +class DotGraphPrinter final : public IGraphPrinter +{ +public: + // Inherited methods overridden + void print(const Graph &g, std::ostream &os) override; + +private: + /** Print dot graph header + * + * @param[in] g Graph + * @param[out] os Output stream to use + */ + void print_header(const Graph &g, std::ostream &os); + /** Print dot graph footer + * + * @param[in] g Graph + * @param[out] os Output stream to use + */ + void print_footer(const Graph &g, std::ostream &os); + /** Prints nodes in dot format + * + * @param[in] g Graph + * @param[out] os Output stream to use + */ + void print_nodes(const Graph &g, std::ostream &os); + /** Prints edges in dot format + * + * @param[in] g Graph + * @param[out] os Output stream to use + */ + void print_edges(const Graph &g, std::ostream &os); + +private: + DotGraphVisitor _dot_node_visitor = {}; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_DOTGRAPHPRINTER_H__ */ diff --git a/arm_compute/graph/printers/Printers.h b/arm_compute/graph/printers/Printers.h new file mode 100644 index 0000000000..935e2bbbb0 --- /dev/null +++ b/arm_compute/graph/printers/Printers.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __ARM_COMPUTE_GRAPH_PRINTERS_H__ +#define __ARM_COMPUTE_GRAPH_PRINTERS_H__ + +#include "arm_compute/graph/printers/DotGraphPrinter.h" + +#endif /* __ARM_COMPUTE_GRAPH_PRINTERS_H__ */ |