From d9eb27597eabe5b7c17520f4f9b3f8a282d72573 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Tue, 3 Apr 2018 13:44:29 +0100 Subject: COMPMID-797: Switch to new graph. - Cleaned up build system Change-Id: If2faa27ee5b31fa8b972836960ab3ef671059c8d Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/126435 Tested-by: Jenkins Reviewed-by: Pablo Tello --- SConscript | 41 +- SConstruct | 1 - arm_compute/core/CL/OpenCL.h | 2 + arm_compute/core/Error.h | 2 +- arm_compute/graph.h | 55 ++ arm_compute/graph/CL/CLMap.h | 66 --- arm_compute/graph/CL/CLUnmap.h | 63 --- arm_compute/graph/Edge.h | 152 ++++++ arm_compute/graph/Error.h | 64 --- arm_compute/graph/Graph.h | 294 ++++++---- arm_compute/graph/GraphBuilder.h | 232 ++++++++ arm_compute/graph/GraphContext.h | 90 ++-- arm_compute/graph/GraphManager.h | 86 +++ arm_compute/graph/IDeviceBackend.h | 109 ++++ arm_compute/graph/IGraphMutator.h | 53 ++ arm_compute/graph/IGraphPrinter.h | 51 ++ arm_compute/graph/INode.h | 227 ++++++-- arm_compute/graph/INodeVisitor.h | 216 ++++++++ arm_compute/graph/IOperation.h | 72 --- arm_compute/graph/ITensorAccessor.h | 14 +- arm_compute/graph/ITensorHandle.h | 69 +++ arm_compute/graph/ITensorObject.h | 80 --- arm_compute/graph/Logger.h | 62 +++ arm_compute/graph/NodeContext.h | 142 ----- arm_compute/graph/NodeParameter.h | 74 --- arm_compute/graph/Nodes.h | 45 -- arm_compute/graph/OperationRegistrar.h | 59 --- arm_compute/graph/OperationRegistry.h | 86 --- arm_compute/graph/PassManager.h | 92 ++++ arm_compute/graph/SubGraph.h | 94 ---- arm_compute/graph/SubTensor.h | 96 ---- arm_compute/graph/Tensor.h | 124 ++--- arm_compute/graph/TensorDescriptor.h | 55 ++ arm_compute/graph/TypePrinter.h | 313 +++++++++++ arm_compute/graph/Types.h | 166 ++++-- arm_compute/graph/Utils.h | 99 ++++ arm_compute/graph/Workload.h | 66 +++ arm_compute/graph/algorithms/Algorithms.h | 29 + arm_compute/graph/algorithms/BFS.h | 123 +++++ arm_compute/graph/backends/BackendRegistrar.h | 61 +++ arm_compute/graph/backends/BackendRegistry.h | 91 ++++ arm_compute/graph/backends/CL/CLDeviceBackend.h | 71 +++ arm_compute/graph/backends/CL/CLFunctionFactory.h | 57 ++ arm_compute/graph/backends/CL/CLNodeValidator.h | 52 ++ arm_compute/graph/backends/CL/CLSubTensorHandle.h | 71 +++ arm_compute/graph/backends/CL/CLTensorHandle.h | 68 +++ arm_compute/graph/backends/GLES/GCDeviceBackend.h | 60 +++ .../graph/backends/GLES/GCFunctionFactory.h | 57 ++ arm_compute/graph/backends/GLES/GCNodeValidator.h | 52 ++ arm_compute/graph/backends/GLES/GCTensorHandle.h | 68 +++ arm_compute/graph/backends/NEON/NEDeviceBackend.h | 59 +++ .../graph/backends/NEON/NEFunctionFactory.h | 57 ++ arm_compute/graph/backends/NEON/NENodeValidator.h | 52 ++ .../graph/backends/NEON/NESubTensorHandle.h | 71 +++ arm_compute/graph/backends/NEON/NETensorHandle.h | 68 +++ arm_compute/graph/backends/Utils.h | 97 ++++ arm_compute/graph/backends/ValidateHelpers.h | 150 ++++++ arm_compute/graph/detail/ExecutionHelpers.h | 99 ++++ arm_compute/graph/frontend/ILayer.h | 53 ++ arm_compute/graph/frontend/IStream.h | 93 ++++ arm_compute/graph/frontend/IStreamOperators.h | 90 ++++ arm_compute/graph/frontend/Layers.h | 471 ++++++++++++++++ arm_compute/graph/frontend/Stream.h | 84 +++ arm_compute/graph/frontend/SubStream.h | 75 +++ arm_compute/graph/frontend/Types.h | 69 +++ .../graph/mutators/DepthConcatSubTensorMutator.h | 46 ++ arm_compute/graph/mutators/GraphMutators.h | 32 ++ .../graph/mutators/InPlaceOperationMutator.h | 43 ++ arm_compute/graph/mutators/NodeFusionMutator.h | 52 ++ .../graph/mutators/SplitLayerSubTensorMutator.h | 46 ++ arm_compute/graph/nodes/ActivationLayer.h | 54 -- arm_compute/graph/nodes/ActivationLayerNode.h | 60 +++ arm_compute/graph/nodes/BatchNormalizationLayer.h | 70 --- .../graph/nodes/BatchNormalizationLayerNode.h | 72 +++ arm_compute/graph/nodes/BranchLayer.h | 88 --- arm_compute/graph/nodes/ConstNode.h | 55 ++ arm_compute/graph/nodes/ConvolutionLayer.h | 128 ----- arm_compute/graph/nodes/ConvolutionLayerNode.h | 84 +++ .../graph/nodes/DepthConcatenateLayerNode.h | 78 +++ arm_compute/graph/nodes/DepthConvertLayer.h | 58 -- .../graph/nodes/DepthwiseConvolutionLayer.h | 76 --- .../graph/nodes/DepthwiseConvolutionLayerNode.h | 84 +++ arm_compute/graph/nodes/DequantizationLayer.h | 59 --- arm_compute/graph/nodes/EltwiseLayerNode.h | 60 +++ arm_compute/graph/nodes/FlattenLayer.h | 45 -- arm_compute/graph/nodes/FlattenLayerNode.h | 49 ++ arm_compute/graph/nodes/FloorLayer.h | 45 -- arm_compute/graph/nodes/FullyConnectedLayer.h | 64 --- arm_compute/graph/nodes/FullyConnectedLayerNode.h | 75 +++ arm_compute/graph/nodes/InputNode.h | 55 ++ arm_compute/graph/nodes/L2NormalizeLayer.h | 56 -- arm_compute/graph/nodes/Nodes.h | 44 ++ arm_compute/graph/nodes/NodesFwd.h | 51 ++ arm_compute/graph/nodes/NormalizationLayer.h | 54 -- arm_compute/graph/nodes/NormalizationLayerNode.h | 60 +++ arm_compute/graph/nodes/OutputNode.h | 49 ++ arm_compute/graph/nodes/PoolingLayer.h | 54 -- arm_compute/graph/nodes/PoolingLayerNode.h | 68 +++ arm_compute/graph/nodes/QuantizationLayer.h | 45 -- arm_compute/graph/nodes/ReshapeLayer.h | 54 -- arm_compute/graph/nodes/ReshapeLayerNode.h | 55 ++ arm_compute/graph/nodes/ResidualLayer.h | 76 --- arm_compute/graph/nodes/SoftmaxLayer.h | 44 -- arm_compute/graph/nodes/SoftmaxLayerNode.h | 60 +++ arm_compute/graph/nodes/SplitLayerNode.h | 79 +++ arm_compute/graph/printers/DotGraphPrinter.h | 105 ++++ arm_compute/graph/printers/Printers.h | 29 + arm_compute/graph2.h | 55 -- arm_compute/graph2/Edge.h | 152 ------ arm_compute/graph2/Graph.h | 262 --------- arm_compute/graph2/GraphBuilder.h | 232 -------- arm_compute/graph2/GraphContext.h | 94 ---- arm_compute/graph2/GraphManager.h | 86 --- arm_compute/graph2/IDeviceBackend.h | 104 ---- arm_compute/graph2/IGraphMutator.h | 53 -- arm_compute/graph2/IGraphPrinter.h | 51 -- arm_compute/graph2/INode.h | 252 --------- arm_compute/graph2/INodeVisitor.h | 216 -------- arm_compute/graph2/ITensorAccessor.h | 41 -- arm_compute/graph2/ITensorHandle.h | 69 --- arm_compute/graph2/Logger.h | 62 --- arm_compute/graph2/PassManager.h | 92 ---- arm_compute/graph2/Tensor.h | 114 ---- arm_compute/graph2/TensorDescriptor.h | 55 -- arm_compute/graph2/TypePrinter.h | 313 ----------- arm_compute/graph2/Types.h | 171 ------ arm_compute/graph2/Utils.h | 99 ---- arm_compute/graph2/Workload.h | 66 --- arm_compute/graph2/algorithms/Algorithms.h | 29 - arm_compute/graph2/algorithms/BFS.h | 123 ----- arm_compute/graph2/backends/BackendRegistrar.h | 61 --- arm_compute/graph2/backends/BackendRegistry.h | 91 ---- arm_compute/graph2/backends/CL/CLDeviceBackend.h | 70 --- arm_compute/graph2/backends/CL/CLFunctionFactory.h | 57 -- arm_compute/graph2/backends/CL/CLNodeValidator.h | 52 -- arm_compute/graph2/backends/CL/CLSubTensorHandle.h | 71 --- arm_compute/graph2/backends/CL/CLTensorHandle.h | 68 --- arm_compute/graph2/backends/GLES/GCDeviceBackend.h | 59 --- .../graph2/backends/GLES/GCFunctionFactory.h | 57 -- arm_compute/graph2/backends/GLES/GCNodeValidator.h | 52 -- arm_compute/graph2/backends/GLES/GCTensorHandle.h | 68 --- arm_compute/graph2/backends/NEON/NEDeviceBackend.h | 58 -- .../graph2/backends/NEON/NEFunctionFactory.h | 57 -- arm_compute/graph2/backends/NEON/NENodeValidator.h | 52 -- .../graph2/backends/NEON/NESubTensorHandle.h | 71 --- arm_compute/graph2/backends/NEON/NETensorHandle.h | 68 --- arm_compute/graph2/backends/Utils.h | 97 ---- arm_compute/graph2/backends/ValidateHelpers.h | 149 ------ arm_compute/graph2/detail/ExecutionHelpers.h | 99 ---- arm_compute/graph2/frontend/ILayer.h | 53 -- arm_compute/graph2/frontend/IStream.h | 93 ---- arm_compute/graph2/frontend/IStreamOperators.h | 90 ---- arm_compute/graph2/frontend/Layers.h | 471 ---------------- arm_compute/graph2/frontend/Stream.h | 84 --- arm_compute/graph2/frontend/SubStream.h | 75 --- arm_compute/graph2/frontend/Types.h | 69 --- .../graph2/mutators/DepthConcatSubTensorMutator.h | 46 -- arm_compute/graph2/mutators/GraphMutators.h | 32 -- .../graph2/mutators/InPlaceOperationMutator.h | 43 -- arm_compute/graph2/mutators/NodeFusionMutator.h | 52 -- .../graph2/mutators/SplitLayerSubTensorMutator.h | 46 -- arm_compute/graph2/nodes/ActivationLayerNode.h | 60 --- .../graph2/nodes/BatchNormalizationLayerNode.h | 72 --- arm_compute/graph2/nodes/ConstNode.h | 55 -- arm_compute/graph2/nodes/ConvolutionLayerNode.h | 84 --- .../graph2/nodes/DepthConcatenateLayerNode.h | 78 --- .../graph2/nodes/DepthwiseConvolutionLayerNode.h | 84 --- arm_compute/graph2/nodes/EltwiseLayerNode.h | 60 --- arm_compute/graph2/nodes/FlattenLayerNode.h | 49 -- arm_compute/graph2/nodes/FullyConnectedLayerNode.h | 75 --- arm_compute/graph2/nodes/InputNode.h | 55 -- arm_compute/graph2/nodes/Nodes.h | 44 -- arm_compute/graph2/nodes/NodesFwd.h | 51 -- arm_compute/graph2/nodes/NormalizationLayerNode.h | 60 --- arm_compute/graph2/nodes/OutputNode.h | 49 -- arm_compute/graph2/nodes/PoolingLayerNode.h | 68 --- arm_compute/graph2/nodes/ReshapeLayerNode.h | 55 -- arm_compute/graph2/nodes/SoftmaxLayerNode.h | 60 --- arm_compute/graph2/nodes/SplitLayerNode.h | 79 --- arm_compute/graph2/printers/DotGraphPrinter.h | 105 ---- arm_compute/graph2/printers/Printers.h | 29 - docs/00_introduction.dox | 37 +- examples/SConscript | 71 +-- examples/graph_alexnet.cpp | 6 +- examples/graph_googlenet.cpp | 6 +- examples/graph_inception_v3.cpp | 6 +- examples/graph_inception_v4.cpp | 7 +- examples/graph_lenet.cpp | 6 +- examples/graph_mobilenet.cpp | 6 +- examples/graph_mobilenet_qasymm8.cpp | 17 +- examples/graph_resnet50.cpp | 6 +- examples/graph_squeezenet.cpp | 6 +- examples/graph_squeezenet_v1_1.cpp | 6 +- examples/graph_vgg16.cpp | 6 +- examples/graph_vgg19.cpp | 6 +- opencl-1.2-stubs/SConscript | 2 - opengles-3.1-stubs/SConscript | 2 - src/core/CL/OpenCL.cpp | 32 ++ src/graph/CL/CLMap.cpp | 43 -- src/graph/CL/CLUnmap.cpp | 43 -- src/graph/Graph.cpp | 344 +++++------- src/graph/GraphBuilder.cpp | 394 ++++++++++++++ src/graph/GraphContext.cpp | 56 +- src/graph/GraphManager.cpp | 117 ++++ src/graph/INode.cpp | 176 +++++- src/graph/NodeContext.cpp | 75 --- src/graph/OperationRegistry.cpp | 61 --- src/graph/PassManager.cpp | 88 +++ src/graph/SubGraph.cpp | 110 ---- src/graph/SubTensor.cpp | 119 ----- src/graph/Tensor.cpp | 141 ++--- src/graph/Utils.cpp | 104 ++++ src/graph/Workload.cpp | 41 ++ src/graph/backends/BackendRegistry.cpp | 63 +++ src/graph/backends/CL/CLDeviceBackend.cpp | 180 +++++++ src/graph/backends/CL/CLFunctionsFactory.cpp | 590 +++++++++++++++++++++ src/graph/backends/CL/CLNodeValidator.cpp | 64 +++ src/graph/backends/CL/CLSubTensorHandle.cpp | 78 +++ src/graph/backends/CL/CLTensorHandle.cpp | 78 +++ src/graph/backends/GLES/GCDeviceBackend.cpp | 138 +++++ src/graph/backends/GLES/GCFunctionsFactory.cpp | 507 ++++++++++++++++++ src/graph/backends/GLES/GCNodeValidator.cpp | 122 +++++ src/graph/backends/GLES/GCTensorHandle.cpp | 78 +++ src/graph/backends/NEON/NEDeviceBackend.cpp | 146 +++++ src/graph/backends/NEON/NEFunctionFactory.cpp | 563 ++++++++++++++++++++ src/graph/backends/NEON/NENodeValidator.cpp | 65 +++ src/graph/backends/NEON/NESubTensorHandle.cpp | 75 +++ src/graph/backends/NEON/NETensorHandle.cpp | 77 +++ src/graph/detail/ExecutionHelpers.cpp | 199 +++++++ src/graph/frontend/Stream.cpp | 69 +++ src/graph/frontend/SubStream.cpp | 59 +++ src/graph/mutators/DepthConcatSubTensorMutator.cpp | 86 +++ src/graph/mutators/InPlaceOperationMutator.cpp | 63 +++ src/graph/mutators/NodeFusionMutator.cpp | 96 ++++ src/graph/mutators/SplitLayerSubTensorMutator.cpp | 89 ++++ src/graph/nodes/ActivationLayer.cpp | 56 -- src/graph/nodes/ActivationLayerNode.cpp | 83 +++ src/graph/nodes/BatchNormalizationLayer.cpp | 105 ---- src/graph/nodes/BatchNormalizationLayerNode.cpp | 94 ++++ src/graph/nodes/BranchLayer.cpp | 130 ----- src/graph/nodes/ConstNode.cpp | 72 +++ src/graph/nodes/ConvolutionLayer.cpp | 363 ------------- src/graph/nodes/ConvolutionLayerNode.cpp | 111 ++++ src/graph/nodes/DeQuantizationLayer.cpp | 68 --- src/graph/nodes/DepthConcatenateLayerNode.cpp | 133 +++++ src/graph/nodes/DepthConvertLayer.cpp | 58 -- src/graph/nodes/DepthwiseConvolutionLayer.cpp | 91 ---- src/graph/nodes/DepthwiseConvolutionLayerNode.cpp | 110 ++++ src/graph/nodes/EltwiseLayerNode.cpp | 83 +++ src/graph/nodes/FlattenLayer.cpp | 54 -- src/graph/nodes/FlattenLayerNode.cpp | 80 +++ src/graph/nodes/FloorLayer.cpp | 49 -- src/graph/nodes/FullyConnectedLayer.cpp | 125 ++--- src/graph/nodes/InputNode.cpp | 72 +++ src/graph/nodes/L2NormalizeLayer.cpp | 56 -- src/graph/nodes/NormalizationLayer.cpp | 55 -- src/graph/nodes/NormalizationLayerNode.cpp | 84 +++ src/graph/nodes/OutputNode.cpp | 66 +++ src/graph/nodes/PoolingLayer.cpp | 55 -- src/graph/nodes/PoolingLayerNode.cpp | 103 ++++ src/graph/nodes/QuantizationLayer.cpp | 48 -- src/graph/nodes/ReshapeLayer.cpp | 70 ++- src/graph/nodes/ResidualLayer.cpp | 199 ------- src/graph/nodes/SoftmaxLayer.cpp | 49 -- src/graph/nodes/SoftmaxLayerNode.cpp | 84 +++ src/graph/nodes/SplitLayerNode.cpp | 117 ++++ src/graph/operations/CLSimpleOperations.cpp | 495 ----------------- src/graph/operations/NESimpleOperations.cpp | 495 ----------------- src/graph/printers/DotGraphPrinter.cpp | 173 ++++++ src/graph2/Graph.cpp | 227 -------- src/graph2/GraphBuilder.cpp | 394 -------------- src/graph2/GraphContext.cpp | 74 --- src/graph2/GraphManager.cpp | 117 ---- src/graph2/INode.cpp | 193 ------- src/graph2/PassManager.cpp | 88 --- src/graph2/Tensor.cpp | 111 ---- src/graph2/Utils.cpp | 104 ---- src/graph2/Workload.cpp | 41 -- src/graph2/backends/BackendRegistry.cpp | 63 --- src/graph2/backends/CL/CLDeviceBackend.cpp | 175 ------ src/graph2/backends/CL/CLFunctionsFactory.cpp | 590 --------------------- src/graph2/backends/CL/CLNodeValidator.cpp | 64 --- src/graph2/backends/CL/CLSubTensorHandle.cpp | 78 --- src/graph2/backends/CL/CLTensorHandle.cpp | 78 --- src/graph2/backends/GLES/GCDeviceBackend.cpp | 133 ----- src/graph2/backends/GLES/GCFunctionsFactory.cpp | 507 ------------------ src/graph2/backends/GLES/GCNodeValidator.cpp | 122 ----- src/graph2/backends/GLES/GCTensorHandle.cpp | 78 --- src/graph2/backends/NEON/NEDeviceBackend.cpp | 141 ----- src/graph2/backends/NEON/NEFunctionFactory.cpp | 563 -------------------- src/graph2/backends/NEON/NENodeValidator.cpp | 65 --- src/graph2/backends/NEON/NESubTensorHandle.cpp | 75 --- src/graph2/backends/NEON/NETensorHandle.cpp | 77 --- src/graph2/detail/ExecutionHelpers.cpp | 199 ------- src/graph2/frontend/Stream.cpp | 69 --- src/graph2/frontend/SubStream.cpp | 59 --- .../mutators/DepthConcatSubTensorMutator.cpp | 86 --- src/graph2/mutators/InPlaceOperationMutator.cpp | 63 --- src/graph2/mutators/NodeFusionMutator.cpp | 96 ---- src/graph2/mutators/SplitLayerSubTensorMutator.cpp | 89 ---- src/graph2/nodes/ActivationLayerNode.cpp | 83 --- src/graph2/nodes/BatchNormalizationLayerNode.cpp | 94 ---- src/graph2/nodes/ConstNode.cpp | 72 --- src/graph2/nodes/ConvolutionLayerNode.cpp | 111 ---- src/graph2/nodes/DepthConcatenateLayerNode.cpp | 133 ----- src/graph2/nodes/DepthwiseConvolutionLayerNode.cpp | 110 ---- src/graph2/nodes/EltwiseLayerNode.cpp | 83 --- src/graph2/nodes/FlattenLayerNode.cpp | 80 --- src/graph2/nodes/FullyConnectedLayer.cpp | 107 ---- src/graph2/nodes/InputNode.cpp | 72 --- src/graph2/nodes/NormalizationLayerNode.cpp | 84 --- src/graph2/nodes/OutputNode.cpp | 66 --- src/graph2/nodes/PoolingLayerNode.cpp | 103 ---- src/graph2/nodes/ReshapeLayer.cpp | 81 --- src/graph2/nodes/SoftmaxLayerNode.cpp | 84 --- src/graph2/nodes/SplitLayerNode.cpp | 117 ---- src/graph2/printers/DotGraphPrinter.cpp | 173 ------ src/runtime/NEON/functions/NEWinogradLayer.cpp | 2 +- tests/SConscript | 87 +-- utils/GraphTypePrinter.h | 88 --- utils/GraphUtils.cpp | 5 - utils/GraphUtils.h | 35 +- 322 files changed, 12601 insertions(+), 18994 deletions(-) create mode 100644 arm_compute/graph.h delete mode 100644 arm_compute/graph/CL/CLMap.h delete mode 100644 arm_compute/graph/CL/CLUnmap.h create mode 100644 arm_compute/graph/Edge.h delete mode 100644 arm_compute/graph/Error.h create mode 100644 arm_compute/graph/GraphBuilder.h create mode 100644 arm_compute/graph/GraphManager.h create mode 100644 arm_compute/graph/IDeviceBackend.h create mode 100644 arm_compute/graph/IGraphMutator.h create mode 100644 arm_compute/graph/IGraphPrinter.h create mode 100644 arm_compute/graph/INodeVisitor.h delete mode 100644 arm_compute/graph/IOperation.h create mode 100644 arm_compute/graph/ITensorHandle.h delete mode 100644 arm_compute/graph/ITensorObject.h create mode 100644 arm_compute/graph/Logger.h delete mode 100644 arm_compute/graph/NodeContext.h delete mode 100644 arm_compute/graph/NodeParameter.h delete mode 100644 arm_compute/graph/Nodes.h delete mode 100644 arm_compute/graph/OperationRegistrar.h delete mode 100644 arm_compute/graph/OperationRegistry.h create mode 100644 arm_compute/graph/PassManager.h delete mode 100644 arm_compute/graph/SubGraph.h delete mode 100644 arm_compute/graph/SubTensor.h create mode 100644 arm_compute/graph/TensorDescriptor.h create mode 100644 arm_compute/graph/TypePrinter.h create mode 100644 arm_compute/graph/Utils.h create mode 100644 arm_compute/graph/Workload.h create mode 100644 arm_compute/graph/algorithms/Algorithms.h create mode 100644 arm_compute/graph/algorithms/BFS.h create mode 100644 arm_compute/graph/backends/BackendRegistrar.h create mode 100644 arm_compute/graph/backends/BackendRegistry.h create mode 100644 arm_compute/graph/backends/CL/CLDeviceBackend.h create mode 100644 arm_compute/graph/backends/CL/CLFunctionFactory.h create mode 100644 arm_compute/graph/backends/CL/CLNodeValidator.h create mode 100644 arm_compute/graph/backends/CL/CLSubTensorHandle.h create mode 100644 arm_compute/graph/backends/CL/CLTensorHandle.h create mode 100644 arm_compute/graph/backends/GLES/GCDeviceBackend.h create mode 100644 arm_compute/graph/backends/GLES/GCFunctionFactory.h create mode 100644 arm_compute/graph/backends/GLES/GCNodeValidator.h create mode 100644 arm_compute/graph/backends/GLES/GCTensorHandle.h create mode 100644 arm_compute/graph/backends/NEON/NEDeviceBackend.h create mode 100644 arm_compute/graph/backends/NEON/NEFunctionFactory.h create mode 100644 arm_compute/graph/backends/NEON/NENodeValidator.h create mode 100644 arm_compute/graph/backends/NEON/NESubTensorHandle.h create mode 100644 arm_compute/graph/backends/NEON/NETensorHandle.h create mode 100644 arm_compute/graph/backends/Utils.h create mode 100644 arm_compute/graph/backends/ValidateHelpers.h create mode 100644 arm_compute/graph/detail/ExecutionHelpers.h create mode 100644 arm_compute/graph/frontend/ILayer.h create mode 100644 arm_compute/graph/frontend/IStream.h create mode 100644 arm_compute/graph/frontend/IStreamOperators.h create mode 100644 arm_compute/graph/frontend/Layers.h create mode 100644 arm_compute/graph/frontend/Stream.h create mode 100644 arm_compute/graph/frontend/SubStream.h create mode 100644 arm_compute/graph/frontend/Types.h create mode 100644 arm_compute/graph/mutators/DepthConcatSubTensorMutator.h create mode 100644 arm_compute/graph/mutators/GraphMutators.h create mode 100644 arm_compute/graph/mutators/InPlaceOperationMutator.h create mode 100644 arm_compute/graph/mutators/NodeFusionMutator.h create mode 100644 arm_compute/graph/mutators/SplitLayerSubTensorMutator.h delete mode 100644 arm_compute/graph/nodes/ActivationLayer.h create mode 100644 arm_compute/graph/nodes/ActivationLayerNode.h delete mode 100644 arm_compute/graph/nodes/BatchNormalizationLayer.h create mode 100644 arm_compute/graph/nodes/BatchNormalizationLayerNode.h delete mode 100644 arm_compute/graph/nodes/BranchLayer.h create mode 100644 arm_compute/graph/nodes/ConstNode.h delete mode 100644 arm_compute/graph/nodes/ConvolutionLayer.h create mode 100644 arm_compute/graph/nodes/ConvolutionLayerNode.h create mode 100644 arm_compute/graph/nodes/DepthConcatenateLayerNode.h delete mode 100644 arm_compute/graph/nodes/DepthConvertLayer.h delete mode 100644 arm_compute/graph/nodes/DepthwiseConvolutionLayer.h create mode 100644 arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h delete mode 100644 arm_compute/graph/nodes/DequantizationLayer.h create mode 100644 arm_compute/graph/nodes/EltwiseLayerNode.h delete mode 100644 arm_compute/graph/nodes/FlattenLayer.h create mode 100644 arm_compute/graph/nodes/FlattenLayerNode.h delete mode 100644 arm_compute/graph/nodes/FloorLayer.h delete mode 100644 arm_compute/graph/nodes/FullyConnectedLayer.h create mode 100644 arm_compute/graph/nodes/FullyConnectedLayerNode.h create mode 100644 arm_compute/graph/nodes/InputNode.h delete mode 100644 arm_compute/graph/nodes/L2NormalizeLayer.h create mode 100644 arm_compute/graph/nodes/Nodes.h create mode 100644 arm_compute/graph/nodes/NodesFwd.h delete mode 100644 arm_compute/graph/nodes/NormalizationLayer.h create mode 100644 arm_compute/graph/nodes/NormalizationLayerNode.h create mode 100644 arm_compute/graph/nodes/OutputNode.h delete mode 100644 arm_compute/graph/nodes/PoolingLayer.h create mode 100644 arm_compute/graph/nodes/PoolingLayerNode.h delete mode 100644 arm_compute/graph/nodes/QuantizationLayer.h delete mode 100644 arm_compute/graph/nodes/ReshapeLayer.h create mode 100644 arm_compute/graph/nodes/ReshapeLayerNode.h delete mode 100644 arm_compute/graph/nodes/ResidualLayer.h delete mode 100644 arm_compute/graph/nodes/SoftmaxLayer.h create mode 100644 arm_compute/graph/nodes/SoftmaxLayerNode.h create mode 100644 arm_compute/graph/nodes/SplitLayerNode.h create mode 100644 arm_compute/graph/printers/DotGraphPrinter.h create mode 100644 arm_compute/graph/printers/Printers.h delete mode 100644 arm_compute/graph2.h delete mode 100644 arm_compute/graph2/Edge.h delete mode 100644 arm_compute/graph2/Graph.h delete mode 100644 arm_compute/graph2/GraphBuilder.h delete mode 100644 arm_compute/graph2/GraphContext.h delete mode 100644 arm_compute/graph2/GraphManager.h delete mode 100644 arm_compute/graph2/IDeviceBackend.h delete mode 100644 arm_compute/graph2/IGraphMutator.h delete mode 100644 arm_compute/graph2/IGraphPrinter.h delete mode 100644 arm_compute/graph2/INode.h delete mode 100644 arm_compute/graph2/INodeVisitor.h delete mode 100644 arm_compute/graph2/ITensorAccessor.h delete mode 100644 arm_compute/graph2/ITensorHandle.h delete mode 100644 arm_compute/graph2/Logger.h delete mode 100644 arm_compute/graph2/PassManager.h delete mode 100644 arm_compute/graph2/Tensor.h delete mode 100644 arm_compute/graph2/TensorDescriptor.h delete mode 100644 arm_compute/graph2/TypePrinter.h delete mode 100644 arm_compute/graph2/Types.h delete mode 100644 arm_compute/graph2/Utils.h delete mode 100644 arm_compute/graph2/Workload.h delete mode 100644 arm_compute/graph2/algorithms/Algorithms.h delete mode 100644 arm_compute/graph2/algorithms/BFS.h delete mode 100644 arm_compute/graph2/backends/BackendRegistrar.h delete mode 100644 arm_compute/graph2/backends/BackendRegistry.h delete mode 100644 arm_compute/graph2/backends/CL/CLDeviceBackend.h delete mode 100644 arm_compute/graph2/backends/CL/CLFunctionFactory.h delete mode 100644 arm_compute/graph2/backends/CL/CLNodeValidator.h delete mode 100644 arm_compute/graph2/backends/CL/CLSubTensorHandle.h delete mode 100644 arm_compute/graph2/backends/CL/CLTensorHandle.h delete mode 100644 arm_compute/graph2/backends/GLES/GCDeviceBackend.h delete mode 100644 arm_compute/graph2/backends/GLES/GCFunctionFactory.h delete mode 100644 arm_compute/graph2/backends/GLES/GCNodeValidator.h delete mode 100644 arm_compute/graph2/backends/GLES/GCTensorHandle.h delete mode 100644 arm_compute/graph2/backends/NEON/NEDeviceBackend.h delete mode 100644 arm_compute/graph2/backends/NEON/NEFunctionFactory.h delete mode 100644 arm_compute/graph2/backends/NEON/NENodeValidator.h delete mode 100644 arm_compute/graph2/backends/NEON/NESubTensorHandle.h delete mode 100644 arm_compute/graph2/backends/NEON/NETensorHandle.h delete mode 100644 arm_compute/graph2/backends/Utils.h delete mode 100644 arm_compute/graph2/backends/ValidateHelpers.h delete mode 100644 arm_compute/graph2/detail/ExecutionHelpers.h delete mode 100644 arm_compute/graph2/frontend/ILayer.h delete mode 100644 arm_compute/graph2/frontend/IStream.h delete mode 100644 arm_compute/graph2/frontend/IStreamOperators.h delete mode 100644 arm_compute/graph2/frontend/Layers.h delete mode 100644 arm_compute/graph2/frontend/Stream.h delete mode 100644 arm_compute/graph2/frontend/SubStream.h delete mode 100644 arm_compute/graph2/frontend/Types.h delete mode 100644 arm_compute/graph2/mutators/DepthConcatSubTensorMutator.h delete mode 100644 arm_compute/graph2/mutators/GraphMutators.h delete mode 100644 arm_compute/graph2/mutators/InPlaceOperationMutator.h delete mode 100644 arm_compute/graph2/mutators/NodeFusionMutator.h delete mode 100644 arm_compute/graph2/mutators/SplitLayerSubTensorMutator.h delete mode 100644 arm_compute/graph2/nodes/ActivationLayerNode.h delete mode 100644 arm_compute/graph2/nodes/BatchNormalizationLayerNode.h delete mode 100644 arm_compute/graph2/nodes/ConstNode.h delete mode 100644 arm_compute/graph2/nodes/ConvolutionLayerNode.h delete mode 100644 arm_compute/graph2/nodes/DepthConcatenateLayerNode.h delete mode 100644 arm_compute/graph2/nodes/DepthwiseConvolutionLayerNode.h delete mode 100644 arm_compute/graph2/nodes/EltwiseLayerNode.h delete mode 100644 arm_compute/graph2/nodes/FlattenLayerNode.h delete mode 100644 arm_compute/graph2/nodes/FullyConnectedLayerNode.h delete mode 100644 arm_compute/graph2/nodes/InputNode.h delete mode 100644 arm_compute/graph2/nodes/Nodes.h delete mode 100644 arm_compute/graph2/nodes/NodesFwd.h delete mode 100644 arm_compute/graph2/nodes/NormalizationLayerNode.h delete mode 100644 arm_compute/graph2/nodes/OutputNode.h delete mode 100644 arm_compute/graph2/nodes/PoolingLayerNode.h delete mode 100644 arm_compute/graph2/nodes/ReshapeLayerNode.h delete mode 100644 arm_compute/graph2/nodes/SoftmaxLayerNode.h delete mode 100644 arm_compute/graph2/nodes/SplitLayerNode.h delete mode 100644 arm_compute/graph2/printers/DotGraphPrinter.h delete mode 100644 arm_compute/graph2/printers/Printers.h delete mode 100644 src/graph/CL/CLMap.cpp delete mode 100644 src/graph/CL/CLUnmap.cpp create mode 100644 src/graph/GraphBuilder.cpp create mode 100644 src/graph/GraphManager.cpp delete mode 100644 src/graph/NodeContext.cpp delete mode 100644 src/graph/OperationRegistry.cpp create mode 100644 src/graph/PassManager.cpp delete mode 100644 src/graph/SubGraph.cpp delete mode 100644 src/graph/SubTensor.cpp create mode 100644 src/graph/Utils.cpp create mode 100644 src/graph/Workload.cpp create mode 100644 src/graph/backends/BackendRegistry.cpp create mode 100644 src/graph/backends/CL/CLDeviceBackend.cpp create mode 100644 src/graph/backends/CL/CLFunctionsFactory.cpp create mode 100644 src/graph/backends/CL/CLNodeValidator.cpp create mode 100644 src/graph/backends/CL/CLSubTensorHandle.cpp create mode 100644 src/graph/backends/CL/CLTensorHandle.cpp create mode 100644 src/graph/backends/GLES/GCDeviceBackend.cpp create mode 100644 src/graph/backends/GLES/GCFunctionsFactory.cpp create mode 100644 src/graph/backends/GLES/GCNodeValidator.cpp create mode 100644 src/graph/backends/GLES/GCTensorHandle.cpp create mode 100644 src/graph/backends/NEON/NEDeviceBackend.cpp create mode 100644 src/graph/backends/NEON/NEFunctionFactory.cpp create mode 100644 src/graph/backends/NEON/NENodeValidator.cpp create mode 100644 src/graph/backends/NEON/NESubTensorHandle.cpp create mode 100644 src/graph/backends/NEON/NETensorHandle.cpp create mode 100644 src/graph/detail/ExecutionHelpers.cpp create mode 100644 src/graph/frontend/Stream.cpp create mode 100644 src/graph/frontend/SubStream.cpp create mode 100644 src/graph/mutators/DepthConcatSubTensorMutator.cpp create mode 100644 src/graph/mutators/InPlaceOperationMutator.cpp create mode 100644 src/graph/mutators/NodeFusionMutator.cpp create mode 100644 src/graph/mutators/SplitLayerSubTensorMutator.cpp delete mode 100644 src/graph/nodes/ActivationLayer.cpp create mode 100644 src/graph/nodes/ActivationLayerNode.cpp delete mode 100644 src/graph/nodes/BatchNormalizationLayer.cpp create mode 100644 src/graph/nodes/BatchNormalizationLayerNode.cpp delete mode 100644 src/graph/nodes/BranchLayer.cpp create mode 100644 src/graph/nodes/ConstNode.cpp delete mode 100644 src/graph/nodes/ConvolutionLayer.cpp create mode 100644 src/graph/nodes/ConvolutionLayerNode.cpp delete mode 100644 src/graph/nodes/DeQuantizationLayer.cpp create mode 100644 src/graph/nodes/DepthConcatenateLayerNode.cpp delete mode 100644 src/graph/nodes/DepthConvertLayer.cpp delete mode 100644 src/graph/nodes/DepthwiseConvolutionLayer.cpp create mode 100644 src/graph/nodes/DepthwiseConvolutionLayerNode.cpp create mode 100644 src/graph/nodes/EltwiseLayerNode.cpp delete mode 100644 src/graph/nodes/FlattenLayer.cpp create mode 100644 src/graph/nodes/FlattenLayerNode.cpp delete mode 100644 src/graph/nodes/FloorLayer.cpp create mode 100644 src/graph/nodes/InputNode.cpp delete mode 100644 src/graph/nodes/L2NormalizeLayer.cpp delete mode 100644 src/graph/nodes/NormalizationLayer.cpp create mode 100644 src/graph/nodes/NormalizationLayerNode.cpp create mode 100644 src/graph/nodes/OutputNode.cpp delete mode 100644 src/graph/nodes/PoolingLayer.cpp create mode 100644 src/graph/nodes/PoolingLayerNode.cpp delete mode 100644 src/graph/nodes/QuantizationLayer.cpp delete mode 100644 src/graph/nodes/ResidualLayer.cpp delete mode 100644 src/graph/nodes/SoftmaxLayer.cpp create mode 100644 src/graph/nodes/SoftmaxLayerNode.cpp create mode 100644 src/graph/nodes/SplitLayerNode.cpp delete mode 100644 src/graph/operations/CLSimpleOperations.cpp delete mode 100644 src/graph/operations/NESimpleOperations.cpp create mode 100644 src/graph/printers/DotGraphPrinter.cpp delete mode 100644 src/graph2/Graph.cpp delete mode 100644 src/graph2/GraphBuilder.cpp delete mode 100644 src/graph2/GraphContext.cpp delete mode 100644 src/graph2/GraphManager.cpp delete mode 100644 src/graph2/INode.cpp delete mode 100644 src/graph2/PassManager.cpp delete mode 100644 src/graph2/Tensor.cpp delete mode 100644 src/graph2/Utils.cpp delete mode 100644 src/graph2/Workload.cpp delete mode 100644 src/graph2/backends/BackendRegistry.cpp delete mode 100644 src/graph2/backends/CL/CLDeviceBackend.cpp delete mode 100644 src/graph2/backends/CL/CLFunctionsFactory.cpp delete mode 100644 src/graph2/backends/CL/CLNodeValidator.cpp delete mode 100644 src/graph2/backends/CL/CLSubTensorHandle.cpp delete mode 100644 src/graph2/backends/CL/CLTensorHandle.cpp delete mode 100644 src/graph2/backends/GLES/GCDeviceBackend.cpp delete mode 100644 src/graph2/backends/GLES/GCFunctionsFactory.cpp delete mode 100644 src/graph2/backends/GLES/GCNodeValidator.cpp delete mode 100644 src/graph2/backends/GLES/GCTensorHandle.cpp delete mode 100644 src/graph2/backends/NEON/NEDeviceBackend.cpp delete mode 100644 src/graph2/backends/NEON/NEFunctionFactory.cpp delete mode 100644 src/graph2/backends/NEON/NENodeValidator.cpp delete mode 100644 src/graph2/backends/NEON/NESubTensorHandle.cpp delete mode 100644 src/graph2/backends/NEON/NETensorHandle.cpp delete mode 100644 src/graph2/detail/ExecutionHelpers.cpp delete mode 100644 src/graph2/frontend/Stream.cpp delete mode 100644 src/graph2/frontend/SubStream.cpp delete mode 100644 src/graph2/mutators/DepthConcatSubTensorMutator.cpp delete mode 100644 src/graph2/mutators/InPlaceOperationMutator.cpp delete mode 100644 src/graph2/mutators/NodeFusionMutator.cpp delete mode 100644 src/graph2/mutators/SplitLayerSubTensorMutator.cpp delete mode 100644 src/graph2/nodes/ActivationLayerNode.cpp delete mode 100644 src/graph2/nodes/BatchNormalizationLayerNode.cpp delete mode 100644 src/graph2/nodes/ConstNode.cpp delete mode 100644 src/graph2/nodes/ConvolutionLayerNode.cpp delete mode 100644 src/graph2/nodes/DepthConcatenateLayerNode.cpp delete mode 100644 src/graph2/nodes/DepthwiseConvolutionLayerNode.cpp delete mode 100644 src/graph2/nodes/EltwiseLayerNode.cpp delete mode 100644 src/graph2/nodes/FlattenLayerNode.cpp delete mode 100644 src/graph2/nodes/FullyConnectedLayer.cpp delete mode 100644 src/graph2/nodes/InputNode.cpp delete mode 100644 src/graph2/nodes/NormalizationLayerNode.cpp delete mode 100644 src/graph2/nodes/OutputNode.cpp delete mode 100644 src/graph2/nodes/PoolingLayerNode.cpp delete mode 100644 src/graph2/nodes/ReshapeLayer.cpp delete mode 100644 src/graph2/nodes/SoftmaxLayerNode.cpp delete mode 100644 src/graph2/nodes/SplitLayerNode.cpp delete mode 100644 src/graph2/printers/DotGraphPrinter.cpp delete mode 100644 utils/GraphTypePrinter.h diff --git a/SConscript b/SConscript index 5a4b6ce5ed..936fde0f1f 100644 --- a/SConscript +++ b/SConscript @@ -170,9 +170,8 @@ runtime_files += Glob('src/runtime/CPP/functions/*.cpp') # CLHarrisCorners uses the Scheduler to run CPP kernels runtime_files += Glob('src/runtime/CPP/SingleThreadScheduler.cpp') -# FIXME : Rename graph2 -> graph -graph2_files = Glob('src/graph2/*.cpp') -graph2_files += Glob('src/graph2/*/*.cpp') +graph_files = Glob('src/graph/*.cpp') +graph_files += Glob('src/graph/*/*.cpp') if env['cppthreads']: runtime_files += Glob('src/runtime/CPP/CPPScheduler.cpp') @@ -188,7 +187,7 @@ if env['opencl']: runtime_files += Glob('src/runtime/CL/functions/*.cpp') runtime_files += Glob('src/runtime/CL/tuners/*.cpp') - graph2_files += Glob('src/graph2/backends/CL/*.cpp') + graph_files += Glob('src/graph/backends/CL/*.cpp') if env['neon']: @@ -202,7 +201,7 @@ if env['neon']: core_files += Glob('src/core/NEON/kernels/convolution/winograd/*/*.cpp') arm_compute_env.Append(CPPPATH = ["arm_compute/core/NEON/kernels/winograd/", "arm_compute/core/NEON/kernels/assembly/"]) - graph2_files += Glob('src/graph2/backends/NEON/*.cpp') + graph_files += Glob('src/graph/backends/NEON/*.cpp') if env['arch'] == "armv7a": core_files += Glob('src/core/NEON/kernels/arm_gemm/kernels/a32_*/*.cpp') @@ -224,7 +223,7 @@ if env['gles_compute']: runtime_files += Glob('src/runtime/GLES_COMPUTE/*.cpp') runtime_files += Glob('src/runtime/GLES_COMPUTE/functions/*.cpp') - graph2_files += Glob('src/graph2/backends/GLES/*.cpp') + graph_files += Glob('src/graph/backends/GLES/*.cpp') arm_compute_core_a = build_library('arm_compute_core-static', core_files, static=True) Export('arm_compute_core_a') @@ -241,38 +240,14 @@ if env['os'] != 'bare_metal' and not env['standalone']: Depends(arm_compute_so, arm_compute_core_so) Export('arm_compute_so') -arm_compute_graph2_a = build_library('arm_compute_graph2-static', graph2_files, static=True, libs = [ arm_compute_a]) -Export('arm_compute_graph2_a') +arm_compute_graph_a = build_library('arm_compute_graph-static', graph_files, static=True, libs = [ arm_compute_a]) +Export('arm_compute_graph_a') if env['os'] != 'bare_metal' and not env['standalone']: - arm_compute_graph2_so = build_library('arm_compute_graph2', graph2_files, static=False, libs = [ "arm_compute" , "arm_compute_core"]) - Depends(arm_compute_graph2_so, arm_compute_so) - Export('arm_compute_graph2_so') - -if env['neon'] and env['opencl']: - Import('opencl') - graph_files = Glob('src/graph/*.cpp') - graph_files += Glob('src/graph/nodes/*.cpp') - graph_files += Glob('src/graph/operations/*.cpp') - - graph_files += Glob('src/graph/CL/*.cpp') - graph_files += Glob('src/graph/NEON/*.cpp') - - shared_graph_objects = [arm_compute_env.SharedObject(f) for f in graph_files] - static_graph_objects = [arm_compute_env.StaticObject(f) for f in graph_files] - - arm_compute_graph_a = build_library('arm_compute_graph-static', static_graph_objects, static=True, libs = [ arm_compute_a ]) - Export('arm_compute_graph_a') - - arm_compute_env.Append(LIBPATH = ["#build/%s/opencl-1.2-stubs" % env['build_dir']]) - arm_compute_graph_so = build_library('arm_compute_graph', shared_graph_objects, static=False, libs = [ "arm_compute", "arm_compute_core"]) + arm_compute_graph_so = build_library('arm_compute_graph', graph_files, static=False, libs = [ "arm_compute" , "arm_compute_core"]) Depends(arm_compute_graph_so, arm_compute_so) - Depends(arm_compute_graph_so, opencl) Export('arm_compute_graph_so') - graph_alias = arm_compute_env.Alias("arm_compute_graph", [arm_compute_graph_a, arm_compute_graph_so]) - Default(graph_alias) - if env['standalone']: alias = arm_compute_env.Alias("arm_compute", [arm_compute_a]) else: diff --git a/SConstruct b/SConstruct index b55075ed4a..a0acb7bf5f 100644 --- a/SConstruct +++ b/SConstruct @@ -246,7 +246,6 @@ if env['opencl']: if env['gles_compute'] and env['os'] != 'android': env.Append(CPPPATH = ['#/include/linux']) - env.Append(LIBPATH = ["#build/%s/opengles-3.1-stubs" % env['build_dir']]) SConscript("./opengles-3.1-stubs/SConscript", variant_dir="build/%s/opengles-3.1-stubs" % env['build_dir'], duplicate=0) SConscript('./SConscript', variant_dir='#build/%s' % env['build_dir'], duplicate=0) diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h index f83c73f371..44e886564a 100644 --- a/arm_compute/core/CL/OpenCL.h +++ b/arm_compute/core/CL/OpenCL.h @@ -119,6 +119,8 @@ public: DECLARE_FUNCTION_PTR(clSVMFree); DECLARE_FUNCTION_PTR(clEnqueueSVMMap); DECLARE_FUNCTION_PTR(clEnqueueSVMUnmap); + DECLARE_FUNCTION_PTR(clEnqueueMarker); + DECLARE_FUNCTION_PTR(clWaitForEvents); #undef DECLARE_FUNCTION_PTR diff --git a/arm_compute/core/Error.h b/arm_compute/core/Error.h index ce395ccfae..590da9b58e 100644 --- a/arm_compute/core/Error.h +++ b/arm_compute/core/Error.h @@ -156,7 +156,7 @@ Status create_error(ErrorCode error_code, const char *function, const char *file * * @param[in] ... Variables which are unused. */ -#define ARM_COMPUTE_UNUSED(...) ignore_unused(__VA_ARGS__) // NOLINT +#define ARM_COMPUTE_UNUSED(...) arm_compute::ignore_unused(__VA_ARGS__) // NOLINT /** Creates an error with a given message * diff --git a/arm_compute/graph.h b/arm_compute/graph.h new file mode 100644 index 0000000000..823a20f677 --- /dev/null +++ b/arm_compute/graph.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_H__ +#define __ARM_COMPUTE_GRAPH_H__ + +// IR +#include "arm_compute/graph/Edge.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphBuilder.h" +#include "arm_compute/graph/IDeviceBackend.h" +#include "arm_compute/graph/IGraphMutator.h" +#include "arm_compute/graph/IGraphPrinter.h" +#include "arm_compute/graph/INode.h" +#include "arm_compute/graph/INodeVisitor.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/TensorDescriptor.h" +#include "arm_compute/graph/TypePrinter.h" +#include "arm_compute/graph/Types.h" + +// Algorithms +#include "arm_compute/graph/algorithms/Algorithms.h" +#include "arm_compute/graph/mutators/GraphMutators.h" +#include "arm_compute/graph/nodes/Nodes.h" +#include "arm_compute/graph/printers/Printers.h" + +// Frontend +#include "arm_compute/graph/frontend/IStreamOperators.h" +#include "arm_compute/graph/frontend/Layers.h" +#include "arm_compute/graph/frontend/Stream.h" +#include "arm_compute/graph/frontend/SubStream.h" +#include "arm_compute/graph/frontend/Types.h" + +#endif /* __ARM_COMPUTE_GRAPH_H__ */ diff --git a/arm_compute/graph/CL/CLMap.h b/arm_compute/graph/CL/CLMap.h deleted file mode 100644 index 732a1df77f..0000000000 --- a/arm_compute/graph/CL/CLMap.h +++ /dev/null @@ -1,66 +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_CLMAP_H__ -#define __ARM_COMPUTE_GRAPH_CLMAP_H__ - -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/IFunction.h" - -namespace arm_compute -{ -class ICLTensor; - -namespace graph -{ -class ITensorObject; -/** OpenCL map function */ -class CLMap : public arm_compute::IFunction -{ -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; - - // Inherited methods overriden: - void run() override; - -private: - arm_compute::ICLTensor *_tensor; /**< Tensor */ - bool _blocking; /**< Blocking flag */ -}; -} // namespace graph -} // namespace arm_compute - -#endif /* __ARM_COMPUTE_GRAPH_CLMAP_H__ */ diff --git a/arm_compute/graph/CL/CLUnmap.h b/arm_compute/graph/CL/CLUnmap.h deleted file mode 100644 index 17745c436b..0000000000 --- a/arm_compute/graph/CL/CLUnmap.h +++ /dev/null @@ -1,63 +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_CLUNMAP_H__ -#define __ARM_COMPUTE_GRAPH_CLUNMAP_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 -{ -public: - /** Constructor - * - * @param[in] tensor Tensor to un-map - */ - 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; - -private: - arm_compute::ICLTensor *_tensor; /**< Tensor */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_CLUNMAP_H__ */ 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 -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 tensor_objects_array{ { std::forward(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 #include +#include +#include +#include +#include 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 + 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 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 tensor); - /** Check if the OpenCL target is available + const std::vector &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> &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> &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> &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> &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> &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 _pimpl; /**< Internal implementation class */ + GraphID _id = GraphID(0); /**< Graph id */ + std::string _name = {}; /**< Graph name */ + std::vector> _nodes = {}; /**< Graph nodes */ + std::vector> _edges = {}; /**< Graph edges */ + std::vector> _tensors = {}; /**< Graph tensors */ + std::map> _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 -Graph &operator<<(Graph &graph, Node node) +template +inline NodeID Graph::add_node(Ts &&... args) { - graph.add_node(arm_compute::support::cpp14::make_unique(std::move(node))); - return graph; + std::lock_guard lock(_mtx); + + // Create node + NodeID nid = _nodes.size(); + auto node = support::cpp14::make_unique(std::forward(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 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 +#include + 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 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 _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 + +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 _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 + +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 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 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 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 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/IGraphPrinter.h b/arm_compute/graph/IGraphPrinter.h new file mode 100644 index 0000000000..aba52b1f74 --- /dev/null +++ b/arm_compute/graph/IGraphPrinter.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_IGRAPHPRINTER_H__ +#define __ARM_COMPUTE_GRAPH_IGRAPHPRINTER_H__ + +#include + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class Graph; + +/** Graph printer interface */ +class IGraphPrinter +{ +public: + /** 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_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 +#include 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 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 &inputs() const; + /** Returns outputs of the node + * + * @return Outputs of the node + */ + const std::vector &outputs() const; + /** Returns input edge set + * + * @return Set of input edges + */ + const std::vector &input_edges() const; + /** Returns output edge set + * + * @return Set of output edges + */ + const std::set &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 _outputs; /**< Output of the node */ + std::vector _input_edges; /**< Inputs edge set */ + std::set _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 - -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 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 configure(NodeContext &ctx) final; \ - TargetHint target() const final \ - { \ - return TargetHint::TARGET; \ - } \ - }; \ - static detail::OperationRegistrar NAME##_registrar(OP); \ - std::unique_ptr 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 namespace arm_compute { @@ -44,6 +46,8 @@ public: */ virtual bool access_tensor(ITensor &tensor) = 0; }; + +using ITensorAccessorUPtr = std::unique_ptr; } // 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 - -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 -#include -#include - -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 - 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 - 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 _inputs; - std::vector _outputs; - std::map> _parameters; -}; - -template -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>(name, parameter); -} - -template -inline T NodeContext::parameter(std::string name) const -{ - auto it = _parameters.find(name); - ARM_COMPUTE_ERROR_ON(it == _parameters.end()); - return static_cast *>(it->second.get())->value(); -} -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_NODE_CONTEXT_H__ */ diff --git a/arm_compute/graph/NodeParameter.h b/arm_compute/graph/NodeParameter.h deleted file mode 100644 index 9d3823d543..0000000000 --- a/arm_compute/graph/NodeParameter.h +++ /dev/null @@ -1,74 +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_NODE_PARAMETER_H__ -#define __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__ - -#include -#include - -namespace arm_compute -{ -namespace graph -{ -/**Node Parameter Empty base class */ -class NodeParameterBase -{ -}; - -/** Template parameter implementation */ -template -class NodeParameter : public NodeParameterBase -{ -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 - */ - T value() - { - return _val; - } - -private: - std::string _name; - T _val; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_NODE_PARAMETER_H__ */ diff --git a/arm_compute/graph/Nodes.h b/arm_compute/graph/Nodes.h deleted file mode 100644 index 3009a24fcb..0000000000 --- a/arm_compute/graph/Nodes.h +++ /dev/null @@ -1,45 +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_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" - -#endif /* __ARM_COMPUTE_GRAPH_NODES_H__ */ diff --git a/arm_compute/graph/OperationRegistrar.h b/arm_compute/graph/OperationRegistrar.h deleted file mode 100644 index ee171c3510..0000000000 --- a/arm_compute/graph/OperationRegistrar.h +++ /dev/null @@ -1,59 +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_OPERATION_REGISTRAR -#define ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR - -#include "arm_compute/graph/OperationRegistry.h" -#include "arm_compute/graph/Types.h" - -#include -#include - -namespace arm_compute -{ -namespace graph -{ -namespace detail -{ -/** Helper class to statically register an operation */ -template -class OperationRegistrar final -{ -public: - /** Add a new test case with the given name to the framework. - * - * @param[in] operation Operation type - */ - OperationRegistrar(OperationType operation); -}; - -template -inline OperationRegistrar::OperationRegistrar(OperationType operation) -{ - OperationRegistry::get().add_operation(std::move(operation)); -} -} // namespace detail -} // namespace graph -} // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH_OPERATION_REGISTRAR */ \ No newline at end of file diff --git a/arm_compute/graph/OperationRegistry.h b/arm_compute/graph/OperationRegistry.h deleted file mode 100644 index ae68bf45a2..0000000000 --- a/arm_compute/graph/OperationRegistry.h +++ /dev/null @@ -1,86 +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_OPERATION_REGISTRY_H__ -#define __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_H__ - -#include "arm_compute/graph/IOperation.h" -#include "arm_compute/graph/Types.h" -#include "support/ToolchainSupport.h" - -#include -#include -#include - -namespace arm_compute -{ -namespace graph -{ -/** Registry holding all the supported operations */ -class OperationRegistry -{ -public: - /** Gets operation registry instance - * - * @return Operation registry instance - */ - static OperationRegistry &get(); - /** Finds an operation in the registry - * - * @param[in] operation Type of the operation to find - * @param[in] target Target of the operation - * - * @return Pointer to the operation functor if found, else nullptr - */ - IOperation *find_operation(OperationType operation, TargetHint target); - /** Checks if an operation for a given target exists - * - * @param[in] operation Operation type - * @param[in] target Execution target - * - * @return True if exists else false - */ - bool contains(OperationType operation, TargetHint target) const; - /** Registers an operation to the registry - * - * @param operation Operation to register - */ - template - void add_operation(OperationType operation); - -private: - /** Default Constructor */ - OperationRegistry(); - -private: - std::map>> _registered_ops; -}; - -template -inline void OperationRegistry::add_operation(OperationType operation) -{ - _registered_ops[operation].emplace_back(support::cpp14::make_unique()); -} -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_OPERATION_REGISTRY_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 +#include + +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> &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 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> _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 - -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 node); - /** Adds a tensor to the graph - * - * @param[in] tensor Tensor to add - */ - void add_tensor_object(std::unique_ptr 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 construct(const GraphContext &ctx, std::unique_ptr input, std::unique_ptr 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> _nodes; - std::unique_ptr _input; - std::unique_ptr _output; -}; - -SubGraph &operator<<(SubGraph &graph, Tensor &&tensor); -SubGraph &operator<<(SubGraph &graph, SubTensor &&sub_tensor); - -template -SubGraph &operator<<(SubGraph &sub_graph, Node node) -{ - sub_graph.add_node(arm_compute::support::cpp14::make_unique(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 - -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 _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 +#include 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 - Tensor(std::unique_ptr 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 - Tensor(AccessorType &&accessor) - : _target(TargetHint::DONT_CARE), _info(), _accessor(arm_compute::support::cpp14::make_unique(std::forward(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 - Tensor(TensorInfo &&info, std::unique_ptr &&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 - Tensor(TensorInfo &&info, AccessorType &&accessor) - : _target(TargetHint::DONT_CARE), _info(info), _accessor(arm_compute::support::cpp14::make_unique(std::forward(accessor))), _tensor(nullptr) - { - } - /** Default Destructor */ - ~Tensor() = default; - /** Move Constructor + void set_handle(std::unique_ptr 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 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 bound_edges() const; private: - TargetHint _target; /**< Target that this tensor is pinned on */ - TensorInfo _info; /**< Tensor metadata */ - std::unique_ptr _accessor; /**< Tensor Accessor */ - std::unique_ptr _tensor; /**< Tensor */ + TensorID _id; /**< Tensor id */ + TensorDescriptor _desc; /**< Tensor metadata */ + std::unique_ptr _handle; /**< Tensor Handle */ + std::unique_ptr _accessor; /**< Tensor Accessor */ + std::set _bound_edges; /**< Edges bound to this tensor */ }; } // namespace graph } // namespace arm_compute diff --git a/arm_compute/graph/TensorDescriptor.h b/arm_compute/graph/TensorDescriptor.h new file mode 100644 index 0000000000..fc0095e3b9 --- /dev/null +++ b/arm_compute/graph/TensorDescriptor.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_TENSOR_DESCRIPTOR_H__ +#define __ARM_COMPUTE_GRAPH_TENSOR_DESCRIPTOR_H__ + +#include "arm_compute/graph/Types.h" + +namespace arm_compute +{ +namespace graph +{ +/** Tensor metadata class */ +struct TensorDescriptor final +{ + /** Default Constructor **/ + TensorDescriptor() = default; + /** Constructor + * + * @param[in] tensor_shape Tensor shape + * @param[in] tensor_data_type Tensor data type + * @param[in] tensor_target Target to allocate the tensor for + */ + TensorDescriptor(TensorShape tensor_shape, DataType tensor_data_type, Target tensor_target = Target::UNSPECIFIED) + : shape(tensor_shape), data_type(tensor_data_type), target(tensor_target) + { + } + + 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_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 +inline ::std::ostream &operator<<(::std::ostream &os, const arm_compute::Dimensions &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 +#include 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; +/* TODO (geopin01): Strong types for NodeID */ + +/**< Constant TensorID specifying an equivalent of null tensor */ +constexpr TensorID NullTensorID = std::numeric_limits::max(); +/**< Constant NodeID specifying an equivalent of null node */ +constexpr NodeID EmptyNodeID = std::numeric_limits::max(); +/**< Constant EdgeID specifying an equivalent of null edge */ +constexpr EdgeID EmptyEdgeID = std::numeric_limits::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 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 +#include + +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 task = {}; /**< Task to execute */ + INode *node = {}; /**< Node bound to this workload */ + std::vector commit_handles = {}; /**< Handles needs to sync for this task to execute */ + std::vector release_handles = {}; /**< Handles that can be released after this node execution */ + + /** Function operator */ + void operator()(); +}; + +/** Execution workload */ +struct ExecutionWorkload +{ + std::vector inputs = {}; /**< Input handles */ + std::vector outputs = {}; /**< Output handles */ + std::vector 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 +#include + +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 &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 bfs(Graph &g) +{ + std::vector bfs_order_vector; + + // Created visited vector + std::vector visited(g.nodes().size(), false); + + // Create BFS queue + std::list 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/backends/BackendRegistrar.h b/arm_compute/graph/backends/BackendRegistrar.h new file mode 100644 index 0000000000..f7f2f7f9d2 --- /dev/null +++ b/arm_compute/graph/backends/BackendRegistrar.h @@ -0,0 +1,61 @@ +/* + * 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_BACKEND_REGISTRAR_H__ +#define ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__ + +#include "arm_compute/graph/Types.h" +#include "arm_compute/graph/backends/BackendRegistry.h" + +#include + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace detail +{ +/** Helper class to statically register a backend */ +template +class BackendRegistrar final +{ +public: + /** Add a new backend to the backend registry + * + * @param[in] target Execution target + */ + BackendRegistrar(Target target); +}; + +template +inline BackendRegistrar::BackendRegistrar(Target target) +{ + BackendRegistry::get().add_backend(target); +} +} // namespace detail +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif /* ARM_COMPUTE_GRAPH_BACKEND_REGISTRAR_H__ */ \ No newline at end of file diff --git a/arm_compute/graph/backends/BackendRegistry.h b/arm_compute/graph/backends/BackendRegistry.h new file mode 100644 index 0000000000..69114ed26d --- /dev/null +++ b/arm_compute/graph/backends/BackendRegistry.h @@ -0,0 +1,91 @@ +/* + * 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_BACKEND_REGISTRY_H__ +#define __ARM_COMPUTE_GRAPH_BACKEND_REGISTRY_H__ + +#include "arm_compute/graph/IDeviceBackend.h" +#include "arm_compute/graph/Types.h" +#include "support/ToolchainSupport.h" + +#include +#include + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** Registry holding all the supported backends */ +class BackendRegistry final +{ +public: + /** Gets backend registry instance + * + * @return Backend registry instance + */ + static BackendRegistry &get(); + /** Finds a backend in the registry + * + * @param[in] target Backend target + * + * @return Pointer to the backend interface if found, else nullptr + */ + IDeviceBackend *find_backend(Target target); + /** Checks if a backend for a given target exists + * + * @param[in] target Execution target + * + * @return True if exists else false + */ + bool contains(Target target) const; + /** Backends accessor + * + * @return Map containing the registered backends + */ + const std::map> &backends() const; + /** Registers a backend to the registry + * + * @param[in] target Execution target to register for + */ + template + void add_backend(Target target); + +private: + /** Default Constructor */ + BackendRegistry(); + +private: + std::map> _registered_backends; +}; + +template +inline void BackendRegistry::add_backend(Target target) +{ + _registered_backends[target] = support::cpp14::make_unique(); +} +} // namespace backends +} // namespace graph +} // namespace arm_compute +#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 create_tensor(const Tensor &tensor) override; + std::unique_ptr create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr 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 + +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 create(INode *node, GraphContext &ctx); +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_CLFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph/backends/CL/CLNodeValidator.h b/arm_compute/graph/backends/CL/CLNodeValidator.h new file mode 100644 index 0000000000..9bd4842cf7 --- /dev/null +++ b/arm_compute/graph/backends/CL/CLNodeValidator.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_CLNODEVALIDATOR_H__ +#define __ARM_COMPUTE_GRAPH_CLNODEVALIDATOR_H__ + +#include "arm_compute/core/Error.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; + +namespace backends +{ +class CLNodeValidator 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_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 create_tensor(const Tensor &tensor) override; + std::unique_ptr create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr 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 + +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 create(INode *node, GraphContext &ctx); +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#endif //__ARM_COMPUTE_GRAPH_GCFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph/backends/GLES/GCNodeValidator.h b/arm_compute/graph/backends/GLES/GCNodeValidator.h new file mode 100644 index 0000000000..6fdfbdd894 --- /dev/null +++ b/arm_compute/graph/backends/GLES/GCNodeValidator.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_GCNODEVALIDATOR_H__ +#define __ARM_COMPUTE_GRAPH_GCNODEVALIDATOR_H__ + +#include "arm_compute/core/Error.h" + +namespace arm_compute +{ +namespace graph +{ +// Forward declarations +class INode; + +namespace backends +{ +class GCNodeValidator 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_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/backends/NEON/NEDeviceBackend.h b/arm_compute/graph/backends/NEON/NEDeviceBackend.h new file mode 100644 index 0000000000..b23c83adea --- /dev/null +++ b/arm_compute/graph/backends/NEON/NEDeviceBackend.h @@ -0,0 +1,59 @@ +/* + * 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_NEDEVICEBACKEND_H__ +#define __ARM_COMPUTE_GRAPH_NEDEVICEBACKEND_H__ + +#include "arm_compute/graph/IDeviceBackend.h" + +#include "arm_compute/runtime/Allocator.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** NEON device backend */ +class NEDeviceBackend final : public IDeviceBackend +{ +public: + NEDeviceBackend(); + + // Inherited overridden methods + void initialize_backend() override; + void setup_backend_context(GraphContext &ctx) override; + bool is_backend_supported() override; + std::unique_ptr create_tensor(const Tensor &tensor) override; + std::unique_ptr create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; + std::unique_ptr configure_node(INode &node, GraphContext &ctx) override; + Status validate_node(INode &node) override; + std::shared_ptr create_memory_manager(MemoryManagerAffinity affinity) override; + +private: + Allocator _allocator; /**< NEON backend allocator */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#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 + +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 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/backends/NEON/NETensorHandle.h b/arm_compute/graph/backends/NEON/NETensorHandle.h new file mode 100644 index 0000000000..06ccdd83cc --- /dev/null +++ b/arm_compute/graph/backends/NEON/NETensorHandle.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_NETENSORHANDLE_H__ +#define __ARM_COMPUTE_GRAPH_NETENSORHANDLE_H__ + +#include "arm_compute/graph/ITensorHandle.h" + +#include "arm_compute/runtime/Tensor.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** NEON Tensor handle interface object **/ +class NETensorHandle final : public ITensorHandle +{ +public: + /** Default Constructor + * + * @param[in] info Tensor metadata + */ + 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: + arm_compute::Tensor _tensor; /**< Backend Tensor */ +}; +} // namespace backends +} // namespace graph +} // namespace arm_compute +#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 +std::pair, FunctionNameType> create_named_function(FunctionNameType name, ParameterType... args) +{ + auto f = arm_compute::support::cpp14::make_unique(); + f->configure(std::forward(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 +std::pair, FunctionNameType> create_named_memory_managed_function(FunctionNameType name, + MemoryManagerType mm, + ParameterType... args) +{ + auto f = arm_compute::support::cpp14::make_unique(mm); + f->configure(std::forward(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 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 +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 +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 +#include + +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 + 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(std::move(sub_stream1))); + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream2))); + + utility::for_each([&](SubStream && sub_stream) + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream))); + }, + std::move(rest_sub_streams)...); + } + /** Construct a branch layer + * + * @param[in] sub_stream Sub-stream + */ + template + BranchLayer(SubStream &&sub_stream) + : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_streams() + { + _sub_streams.push_back(arm_compute::support::cpp14::make_unique(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 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> _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 +#include + +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/ActivationLayer.h b/arm_compute/graph/nodes/ActivationLayer.h deleted file mode 100644 index bc619a8df9..0000000000 --- a/arm_compute/graph/nodes/ActivationLayer.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_ACTIVATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_ACTIVATION_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 -{ -/** Activation Layer node */ -class ActivationLayer final : public INode -{ -public: - /** Default Constructor - * - * @param[in] activation_info Activation layer info - */ - ActivationLayer(const ActivationLayerInfo activation_info); - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - const ActivationLayerInfo _activation_info; /**< Activation layer info */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/ActivationLayerNode.h b/arm_compute/graph/nodes/ActivationLayerNode.h new file mode 100644 index 0000000000..985e10a8d8 --- /dev/null +++ b/arm_compute/graph/nodes/ActivationLayerNode.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_ACTIVATION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_ACTIVATION_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Activation Layer node */ +class ActivationLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] info Activation Layer information + */ + ActivationLayerNode(ActivationLayerInfo info); + /** Activation metadata accessor + * + * @return The activation info of the layer + */ + ActivationLayerInfo activation_info() 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: + ActivationLayerInfo _info; +}; +} // namespace graph +} // namespace arm_compute +#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 - 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 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 - -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 - 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(std::move(sub_graph1))); - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_graph2))); - - utility::for_each([&](SubGraph && sub_graph) - { - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_graph))); - }, - std::move(rest_sub_graphs)...); - } - /** Default Constructor - * - * @param[in] sub_graph Sub graph - */ - template - 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(std::move(sub_graph))); - } - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - BranchMergeMethod _branch_merge_method; - std::vector> _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 - -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 - 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 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 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 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 _is; /**< Input tensor sub-tensors used for grouped convolution */ - std::unique_ptr _os; /**< Output tensor sub-tensors used for grouped convolution */ - std::unique_ptr _ws; /**< Weights tensor sub-tensors used for grouped convolution */ - std::unique_ptr _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 &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/DepthConvertLayer.h b/arm_compute/graph/nodes/DepthConvertLayer.h deleted file mode 100644 index 03bf9b7ed5..0000000000 --- a/arm_compute/graph/nodes/DepthConvertLayer.h +++ /dev/null @@ -1,58 +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_DEPTHCONVERT_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_DEPTHCONVERT_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 -{ -/** DepthConvertLayer layer node */ -class DepthConvertLayer final : public INode -{ -public: - /** Default constructor - * - * @param[in] policy Convertion policy - * @param[in] shift Shift value - * @param[in] output_datatype Output datatype - */ - DepthConvertLayer(const ConvertPolicy policy, uint32_t shift, DataType output_datatype); - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - const ConvertPolicy _policy; - uint32_t _shift; - DataType _output_datatype; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_DEPTHCONVERT_LAYER_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 - -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 - 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 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/DequantizationLayer.h deleted file mode 100644 index f9b7e8af87..0000000000 --- a/arm_compute/graph/nodes/DequantizationLayer.h +++ /dev/null @@ -1,59 +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_DEQUANTIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_DEQUANTIZATION_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 -{ -/** DequantizationLayer layer node */ -class DequantizationLayer final : public INode -{ -public: - /** Default constructor - * - * @param[in] min_max Min max value tensor - */ - template - DequantizationLayer(AccessorType &&min_max) - : _min_max(std::move(min_max)) - { - } - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - Tensor _min_max; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_DEQUANTIZATION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/EltwiseLayerNode.h b/arm_compute/graph/nodes/EltwiseLayerNode.h new file mode 100644 index 0000000000..9da88d75b5 --- /dev/null +++ b/arm_compute/graph/nodes/EltwiseLayerNode.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_ELTWISE_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Eltwise Layer node */ +class EltwiseLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] op Element-wise operation to perform + */ + EltwiseLayerNode(EltwiseOperation op); + /** Eltwise operation accessor + * + * @return Eltwise operation that is to be performed by the node + */ + EltwiseOperation eltwise_operation() 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: + EltwiseOperation _op; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_ELTWISE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/FlattenLayer.h b/arm_compute/graph/nodes/FlattenLayer.h deleted file mode 100644 index c5f51a2b3e..0000000000 --- a/arm_compute/graph/nodes/FlattenLayer.h +++ /dev/null @@ -1,45 +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_FLATTEN_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_FLATTEN_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 -{ -/** Flatten layer node */ -class FlattenLayer final : public INode -{ -public: - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_FLATTEN_LAYER_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/FloorLayer.h b/arm_compute/graph/nodes/FloorLayer.h deleted file mode 100644 index 146e2c16dd..0000000000 --- a/arm_compute/graph/nodes/FloorLayer.h +++ /dev/null @@ -1,45 +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_FLOOR_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_FLOOR_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 -{ -/** Floor layer node */ -class FloorLayer final : public INode -{ -public: - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; -}; - -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_FLOOR_LAYER_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 - 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 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/L2NormalizeLayer.h b/arm_compute/graph/nodes/L2NormalizeLayer.h deleted file mode 100644 index a423306bd2..0000000000 --- a/arm_compute/graph/nodes/L2NormalizeLayer.h +++ /dev/null @@ -1,56 +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_L2NORMALIZE_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_L2NORMALIZE_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 -{ -/** L2NormalizeLayer layer node */ -class L2NormalizeLayer final : public INode -{ -public: - /** Default Constructor - * - * @param[in] axis Dimension along which to reduce. - * @param[in] epsilon Lower bound value for the normalization. - */ - explicit L2NormalizeLayer(unsigned int axis, float epsilon); - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - unsigned int _axis; - float _epsilon; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_L2NORMALIZE_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/Nodes.h b/arm_compute/graph/nodes/Nodes.h new file mode 100644 index 0000000000..c39546c6bd --- /dev/null +++ b/arm_compute/graph/nodes/Nodes.h @@ -0,0 +1,44 @@ +/* + * 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_H__ +#define __ARM_COMPUTE_GRAPH_NODES_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/NormalizationLayer.h deleted file mode 100644 index e1c45094d8..0000000000 --- a/arm_compute/graph/nodes/NormalizationLayer.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_NORMALIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_NORMALIZATION_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 -{ -/** Normalization layer node */ -class NormalizationLayer final : public INode -{ -public: - /** Default Constructor - * - * @param[in] norm_info Normalization layer information - */ - explicit NormalizationLayer(const NormalizationLayerInfo norm_info); - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - const NormalizationLayerInfo _norm_info; /**< Normalization layer information */ -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/NormalizationLayerNode.h b/arm_compute/graph/nodes/NormalizationLayerNode.h new file mode 100644 index 0000000000..34dc3ccf8f --- /dev/null +++ b/arm_compute/graph/nodes/NormalizationLayerNode.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_NORMALIZATION_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Normalization Layer node */ +class NormalizationLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] norm_info Normalization Layer information + */ + NormalizationLayerNode(NormalizationLayerInfo norm_info); + /** Normalization info accessor + * + * @return Normalization layer info + */ + NormalizationLayerInfo normalization_info() 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: + NormalizationLayerInfo _info; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_NORMALIZATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/OutputNode.h b/arm_compute/graph/nodes/OutputNode.h new file mode 100644 index 0000000000..46988cf969 --- /dev/null +++ b/arm_compute/graph/nodes/OutputNode.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_OUTPUT_NODE_H__ +#define __ARM_COMPUTE_GRAPH_OUTPUT_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Output Layer node */ +class OutputNode final : public INode +{ +public: + /** 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_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 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/PoolingLayerNode.h b/arm_compute/graph/nodes/PoolingLayerNode.h new file mode 100644 index 0000000000..e250eb247a --- /dev/null +++ b/arm_compute/graph/nodes/PoolingLayerNode.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_POOLING_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Pooling Layer node */ +class PoolingLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] pool_info Pooling Layer information + */ + 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 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: + PoolingLayerInfo _info; +}; +} // namespace graph +} // namespace arm_compute +#endif /* __ARM_COMPUTE_GRAPH_POOLING_LAYER_NODE_H__ */ diff --git a/arm_compute/graph/nodes/QuantizationLayer.h b/arm_compute/graph/nodes/QuantizationLayer.h deleted file mode 100644 index a3ef02530e..0000000000 --- a/arm_compute/graph/nodes/QuantizationLayer.h +++ /dev/null @@ -1,45 +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_QUANTIZATION_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_QUANTIZATION_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 -{ -/** Quantization layer node */ -class QuantizationLayer final : public INode -{ -public: - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_QUANTIZATION_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/ReshapeLayer.h b/arm_compute/graph/nodes/ReshapeLayer.h deleted file mode 100644 index b727d33a2c..0000000000 --- a/arm_compute/graph/nodes/ReshapeLayer.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_RESHAPE_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_RESHAPE_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 -{ -/** Reshape layer node */ -class ReshapeLayer final : public INode -{ -public: - /** Default constructor - * - * @param[in] shape Output shape - */ - ReshapeLayer(const TensorShape shape); - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - TensorShape _shape; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/ReshapeLayerNode.h b/arm_compute/graph/nodes/ReshapeLayerNode.h new file mode 100644 index 0000000000..ded344e041 --- /dev/null +++ b/arm_compute/graph/nodes/ReshapeLayerNode.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_RESHAPE_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_RESHAPE_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Reshape Layer node */ +class ReshapeLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] shape Reshaped tensor shape + */ + ReshapeLayerNode(TensorShape shape); + + // 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_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 - -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 - ResidualLayer(SubGraph &&sub_graph1, SubGraph &&sub_graph2) - : _sub_graphs() - { - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_graph1))); - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_graph2))); - } - /** Default Constructor - * - * @param[in] sub_graph Sub graph - */ - template - ResidualLayer(SubGraph &&sub_graph) - : _sub_graphs() - { - _sub_graphs.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_graph))); - } - - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; - -private: - std::vector> _sub_graphs; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_RESIDUAL_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/SoftmaxLayer.h b/arm_compute/graph/nodes/SoftmaxLayer.h deleted file mode 100644 index b5d1bc53fd..0000000000 --- a/arm_compute/graph/nodes/SoftmaxLayer.h +++ /dev/null @@ -1,44 +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_SOFTMAX_LAYER_H__ -#define __ARM_COMPUTE_GRAPH_SOFTMAX_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 -{ -/** Softmax layer node */ -class SoftmaxLayer final : public INode -{ -public: - // Inherited methods overriden: - std::unique_ptr instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) override; -}; -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_H__ */ diff --git a/arm_compute/graph/nodes/SoftmaxLayerNode.h b/arm_compute/graph/nodes/SoftmaxLayerNode.h new file mode 100644 index 0000000000..8b716047ff --- /dev/null +++ b/arm_compute/graph/nodes/SoftmaxLayerNode.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_SOFTMAX_LAYER_NODE_H__ +#define __ARM_COMPUTE_GRAPH_SOFTMAX_LAYER_NODE_H__ + +#include "arm_compute/graph/INode.h" + +namespace arm_compute +{ +namespace graph +{ +/** Softmax Layer node */ +class SoftmaxLayerNode final : public INode +{ +public: + /** Constructor + * + * @param[in] beta (Optional) Beta parameter. Defaults to 1 + */ + SoftmaxLayerNode(float beta = 1.f); + /** Beta parameter accessor + * + * @return Beta parameter + */ + float beta() 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: + float _beta; +}; +} // namespace graph +} // namespace arm_compute +#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 + +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 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 + +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__ */ diff --git a/arm_compute/graph2.h b/arm_compute/graph2.h deleted file mode 100644 index 5f54990ba8..0000000000 --- a/arm_compute/graph2.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_GRAPH2_H__ -#define __ARM_COMPUTE_GRAPH2_H__ - -// IR -#include "arm_compute/graph2/Edge.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphBuilder.h" -#include "arm_compute/graph2/IDeviceBackend.h" -#include "arm_compute/graph2/IGraphMutator.h" -#include "arm_compute/graph2/IGraphPrinter.h" -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/INodeVisitor.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/TensorDescriptor.h" -#include "arm_compute/graph2/TypePrinter.h" -#include "arm_compute/graph2/Types.h" - -// Algorithms -#include "arm_compute/graph2/algorithms/Algorithms.h" -#include "arm_compute/graph2/mutators/GraphMutators.h" -#include "arm_compute/graph2/nodes/Nodes.h" -#include "arm_compute/graph2/printers/Printers.h" - -// Frontend -#include "arm_compute/graph2/frontend/IStreamOperators.h" -#include "arm_compute/graph2/frontend/Layers.h" -#include "arm_compute/graph2/frontend/Stream.h" -#include "arm_compute/graph2/frontend/SubStream.h" -#include "arm_compute/graph2/frontend/Types.h" - -#endif /* __ARM_COMPUTE_GRAPH2_H__ */ diff --git a/arm_compute/graph2/Edge.h b/arm_compute/graph2/Edge.h deleted file mode 100644 index e82bcb295a..0000000000 --- a/arm_compute/graph2/Edge.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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_GRAPH2_EDGE_H__ -#define __ARM_COMPUTE_GRAPH2_EDGE_H__ - -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_EDGE_H__ */ diff --git a/arm_compute/graph2/Graph.h b/arm_compute/graph2/Graph.h deleted file mode 100644 index a601598e97..0000000000 --- a/arm_compute/graph2/Graph.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * 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_GRAPH2_GRAPH_H__ -#define __ARM_COMPUTE_GRAPH2_GRAPH_H__ - -#include "arm_compute/graph2/Edge.h" -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/Types.h" - -#include "support/Mutex.h" -#include "support/ToolchainSupport.h" - -#include -#include -#include -#include -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -/** Graph class - * - * Represents a multiple source - multiple sink directed graph - */ -class Graph final -{ -public: - 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 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 - * - * @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 - 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 - */ - GraphID id() const; - /** Returns graph input nodes - * - * @return vector containing the graph inputs - */ - const std::vector &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 - */ - std::vector> &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 - */ - const std::vector> &nodes() const; - /** Returns edges of graph - * - * @warning Edges can be nullptr if they have been removed during the mutation steps of the graph - * - * @return Edges of graph - */ - const std::vector> &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> &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> &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); - -private: - /** Creates a tensor object - * - * @param[in] desc Tensor descriptor - * - * @return Tensor ID - */ - TensorID create_tensor(TensorDescriptor desc = TensorDescriptor()); - -private: - GraphID _id = GraphID(0); /**< Graph id */ - std::string _name = {}; /**< Graph name */ - std::vector> _nodes = {}; /**< Graph nodes */ - std::vector> _edges = {}; /**< Graph edges */ - std::vector> _tensors = {}; /**< Graph tensors */ - std::map> _tagged_nodes = {}; /**< Graph nodes map with the node type as key */ - arm_compute::Mutex _mtx = {}; /**< Mutex used for graph construction */ -}; - -template -inline NodeID Graph::add_node(Ts &&... args) -{ - std::lock_guard lock(_mtx); - - // Create node - NodeID nid = _nodes.size(); - auto node = support::cpp14::make_unique(std::forward(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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_GRAPH_H__ */ diff --git a/arm_compute/graph2/GraphBuilder.h b/arm_compute/graph2/GraphBuilder.h deleted file mode 100644 index f9fb251fc5..0000000000 --- a/arm_compute/graph2/GraphBuilder.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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_GRAPH2_GRAPH_BUILDER_H__ -#define __ARM_COMPUTE_GRAPH2_GRAPH_BUILDER_H__ - -#include "arm_compute/graph2/ITensorAccessor.h" -#include "arm_compute/graph2/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -// 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 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_GRAPH_BUILDER_H__ */ diff --git a/arm_compute/graph2/GraphContext.h b/arm_compute/graph2/GraphContext.h deleted file mode 100644 index f38e25dd61..0000000000 --- a/arm_compute/graph2/GraphContext.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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_GRAPH2_GRAPH_CONTEXT_H__ -#define __ARM_COMPUTE_GRAPH2_GRAPH_CONTEXT_H__ - -#include "arm_compute/graph2/Types.h" - -#include "arm_compute/runtime/IMemoryManager.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -/** Contains structs required for memory management */ -struct MemoryManagerContext -{ - Target target = { Target::UNSPECIFIED }; /**< Target */ - std::shared_ptr mm = { nullptr }; /**< Memory manager */ -}; - -/** Graph context **/ -class GraphContext final -{ -public: - /** 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 - * - * @note Every alteration has to be done before graph finalization - * - * @return The graph configuration - */ - const GraphConfig &config() const; - /** Sets graph configuration - * - * @param[in] config Configuration to use - */ - void set_config(const GraphConfig &config); - /** Inserts a memory manager context - * - * @param[in] memory_ctx Memory manage context - * - * @return If the insertion succeeded else false - */ - 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 Management context for the target if exists else nullptr - */ - MemoryManagerContext *memory_management_ctx(Target target); - /** Finalizes memory managers in graph context */ - void finalize(); - -private: - GraphConfig _config; /**< Graph configuration */ - std::map _memory_managers; /**< Memory managers for each target */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_GRAPH_CONTEXT_H__ */ diff --git a/arm_compute/graph2/GraphManager.h b/arm_compute/graph2/GraphManager.h deleted file mode 100644 index 0d5835f6a4..0000000000 --- a/arm_compute/graph2/GraphManager.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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_GRAPH2_GRAPH_MANAGER_H__ -#define __ARM_COMPUTE_GRAPH2_GRAPH_MANAGER_H__ - -#include "arm_compute/graph2/Types.h" -#include "arm_compute/graph2/Workload.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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 _workloads = {}; /**< Graph workloads */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_GRAPH_MANAGER_H__ */ diff --git a/arm_compute/graph2/IDeviceBackend.h b/arm_compute/graph2/IDeviceBackend.h deleted file mode 100644 index f0d6297b7b..0000000000 --- a/arm_compute/graph2/IDeviceBackend.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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_GRAPH2_IDEVICEBACKEND_H__ -#define __ARM_COMPUTE_GRAPH2_IDEVICEBACKEND_H__ - -#include "arm_compute/graph2/ITensorHandle.h" -#include "arm_compute/graph2/Types.h" -#include "arm_compute/runtime/IFunction.h" -#include "arm_compute/runtime/IMemoryManager.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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; - /** 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 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 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 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 create_memory_manager(MemoryManagerAffinity affinity) = 0; -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_IDEVICEBACKEND_H__ diff --git a/arm_compute/graph2/IGraphMutator.h b/arm_compute/graph2/IGraphMutator.h deleted file mode 100644 index 50151c87ce..0000000000 --- a/arm_compute/graph2/IGraphMutator.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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_GRAPH2_IGRAPHMUTATOR_H__ -#define __ARM_COMPUTE_GRAPH2_IGRAPHMUTATOR_H__ - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_IGRAPHMUTATOR_H__ */ diff --git a/arm_compute/graph2/IGraphPrinter.h b/arm_compute/graph2/IGraphPrinter.h deleted file mode 100644 index eb85f97a5b..0000000000 --- a/arm_compute/graph2/IGraphPrinter.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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_GRAPH2_IGRAPHPRINTER_H__ -#define __ARM_COMPUTE_GRAPH2_IGRAPHPRINTER_H__ - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// Forward declarations -class Graph; - -/** Graph printer interface */ -class IGraphPrinter -{ -public: - /** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_IGRAPHPRINTER_H__ */ diff --git a/arm_compute/graph2/INode.h b/arm_compute/graph2/INode.h deleted file mode 100644 index ba5620ba0e..0000000000 --- a/arm_compute/graph2/INode.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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_GRAPH2_INODE_H__ -#define __ARM_COMPUTE_GRAPH2_INODE_H__ - -#include "arm_compute/core/Error.h" -#include "arm_compute/graph2/TensorDescriptor.h" -#include "arm_compute/graph2/Types.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// Forward declarations -class Graph; -class Edge; -class INodeVisitor; -class Tensor; - -/** Node interface */ -class INode -{ -public: - /** Constructor */ - INode(); - /** Destructor **/ - virtual ~INode() = default; - /** 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 - * - * @return Status containing any errors - */ - virtual Status validate() = 0; - /** Returns node's type - * - * @return Node's type - */ - virtual NodeType type() const = 0; - /** Accepts a node visitor - * - * @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] idx Output index to configure - * - * @return Output descriptor configuration - */ - virtual TensorDescriptor configure_output(size_t idx) const = 0; - /** Returns node's name - * - * @return Node name - */ - std::string name() const; - /** Returns node's ID - * - * @return Node's ID - */ - 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 - * - * @note This is not the target that the graph executor might choose, its just an indication - * - * @param[in] target Target preference - */ - 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 &inputs() const; - /** Returns outputs of the node - * - * @return Outputs of the node - */ - const std::vector &outputs() const; - /** Returns input edge set - * - * @return Set of input edges - */ - const std::vector &input_edges() const; - /** Returns output edge set - * - * @return Set of output edges - */ - const std::set &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: - Graph *_graph; /**< Backward reference to graph owning the node */ - NodeID _id; /**< Node ID */ - NodeParams _common_params; /**< Node common params */ - std::vector _outputs; /**< Output of the node */ - std::vector _input_edges; /**< Inputs edge set */ - std::set _output_edges; /**< Output edge set */ - Target _assigned_target; /**< Assigned target by the Graph executor */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH_INODE_H__ */ diff --git a/arm_compute/graph2/INodeVisitor.h b/arm_compute/graph2/INodeVisitor.h deleted file mode 100644 index 024d83c835..0000000000 --- a/arm_compute/graph2/INodeVisitor.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * 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_GRAPH2_INODEVISITOR_H__ -#define __ARM_COMPUTE_GRAPH2_INODEVISITOR_H__ - -#include "arm_compute/graph2/nodes/NodesFwd.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_INODEVISITOR_H__ */ diff --git a/arm_compute/graph2/ITensorAccessor.h b/arm_compute/graph2/ITensorAccessor.h deleted file mode 100644 index 1a7277344d..0000000000 --- a/arm_compute/graph2/ITensorAccessor.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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_GRAPH2_ITENSOR_ACCESSOR_H__ -#define __ARM_COMPUTE_GRAPH2_ITENSOR_ACCESSOR_H__ - -#include "arm_compute/graph/ITensorAccessor.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// Forward Declarations -class ITensorHandle; -using ITensorAccessor = graph::ITensorAccessor; -using ITensorAccessorUPtr = std::unique_ptr; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_SUB_STREAM_H__ */ \ No newline at end of file diff --git a/arm_compute/graph2/ITensorHandle.h b/arm_compute/graph2/ITensorHandle.h deleted file mode 100644 index c92a213121..0000000000 --- a/arm_compute/graph2/ITensorHandle.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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_GRAPH2_ITENSORHANDLE_H__ -#define __ARM_COMPUTE_GRAPH2_ITENSORHANDLE_H__ - -#include "arm_compute/core/ITensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ITENSORHANDLE_H__ */ diff --git a/arm_compute/graph2/Logger.h b/arm_compute/graph2/Logger.h deleted file mode 100644 index f3c263cd3f..0000000000 --- a/arm_compute/graph2/Logger.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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_GRAPH2_LOGGER_H__ -#define __ARM_COMPUTE_GRAPH2_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_GRAPH2_LOGGER_H__ */ diff --git a/arm_compute/graph2/PassManager.h b/arm_compute/graph2/PassManager.h deleted file mode 100644 index b1db18b4ad..0000000000 --- a/arm_compute/graph2/PassManager.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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_GRAPH2_PASSMANAGER_H__ -#define __ARM_COMPUTE_GRAPH2_PASSMANAGER_H__ - -#include "arm_compute/graph2/IGraphMutator.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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> &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 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> _passes; /**< Vector of graph passes */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_PASSMANAGER_H__ */ diff --git a/arm_compute/graph2/Tensor.h b/arm_compute/graph2/Tensor.h deleted file mode 100644 index fcba854a3e..0000000000 --- a/arm_compute/graph2/Tensor.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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_GRAPH2_TENSOR_H__ -#define __ARM_COMPUTE_GRAPH2_TENSOR_H__ - -#include "arm_compute/graph2/Types.h" - -#include "arm_compute/graph2/ITensorAccessor.h" -#include "arm_compute/graph2/ITensorHandle.h" -#include "arm_compute/graph2/TensorDescriptor.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -/** Tensor object **/ -class Tensor final -{ -public: - /** Default constructor - * - * @param[in] id Tensor ID - * @param[in] desc Tensor information - */ - Tensor(TensorID id, TensorDescriptor desc); - /** Tensor ID accessor - * - * @return Tensor ID - */ - TensorID id() const; - /** TensorInfo metadata accessor - * - * @return Tensor descriptor metadata - */ - TensorDescriptor &desc(); - /** TensorInfo metadata accessor - * - * @return Tensor descriptor metadata - */ - const TensorDescriptor &desc() const; - /** Sets the backend tensor - * - * @param[in] backend_tensor Backend tensor to set - */ - void set_handle(std::unique_ptr backend_tensor); - /** Backend tensor handle accessor - * - * @return Backend tensor handle - */ - ITensorHandle *handle(); - /** Sets the backend tensor accessor - * - * @param[in] accessor Accessor to set - */ - void set_accessor(std::unique_ptr accessor); - /** Backend tensor accessor - * - * @return Backend tensor accessor - */ - 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 bound_edges() const; - -private: - TensorID _id; /**< Tensor id */ - TensorDescriptor _desc; /**< Tensor metadata */ - std::unique_ptr _handle; /**< Tensor Handle */ - std::unique_ptr _accessor; /**< Tensor Accessor */ - std::set _bound_edges; /**< Edges bound to this tensor */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_TENSOR_H__ */ diff --git a/arm_compute/graph2/TensorDescriptor.h b/arm_compute/graph2/TensorDescriptor.h deleted file mode 100644 index 1a69dc10e8..0000000000 --- a/arm_compute/graph2/TensorDescriptor.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_GRAPH2_TENSOR_DESCRIPTOR_H__ -#define __ARM_COMPUTE_GRAPH2_TENSOR_DESCRIPTOR_H__ - -#include "arm_compute/graph2/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Tensor metadata class */ -struct TensorDescriptor final -{ - /** Default Constructor **/ - TensorDescriptor() = default; - /** Constructor - * - * @param[in] tensor_shape Tensor shape - * @param[in] tensor_data_type Tensor data type - * @param[in] tensor_target Target to allocate the tensor for - */ - TensorDescriptor(TensorShape tensor_shape, DataType tensor_data_type, Target tensor_target = Target::UNSPECIFIED) - : shape(tensor_shape), data_type(tensor_data_type), target(tensor_target) - { - } - - TensorShape shape{}; /**< Tensor shape */ - DataType data_type{ DataType::UNKNOWN }; /**< Data type */ - Target target{ Target::UNSPECIFIED }; /**< Target */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_TENSOR_DESCRIPTOR_H__ */ diff --git a/arm_compute/graph2/TypePrinter.h b/arm_compute/graph2/TypePrinter.h deleted file mode 100644 index de675c4633..0000000000 --- a/arm_compute/graph2/TypePrinter.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * 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_GRAPH2_TYPE_PRINTER_H__ -#define __ARM_COMPUTE_GRAPH2_TYPE_PRINTER_H__ - -#include "arm_compute/core/Error.h" -#include "arm_compute/core/Types.h" -#include "arm_compute/graph2/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Formatted output of the Dimensions type. */ -template -inline ::std::ostream &operator<<(::std::ostream &os, const arm_compute::Dimensions &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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_TYPE_PRINTER_H__ */ diff --git a/arm_compute/graph2/Types.h b/arm_compute/graph2/Types.h deleted file mode 100644 index 2625657393..0000000000 --- a/arm_compute/graph2/Types.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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_GRAPH2_TYPES_H__ -#define __ARM_COMPUTE_GRAPH2_TYPES_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" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -using arm_compute::Status; - -using arm_compute::Coordinates; -using arm_compute::DataType; -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::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; -/* TODO (geopin01): Strong types for NodeID */ - -/**< Constant TensorID specifying an equivalent of null tensor */ -constexpr TensorID NullTensorID = std::numeric_limits::max(); -/**< Constant NodeID specifying an equivalent of null node */ -constexpr NodeID EmptyNodeID = std::numeric_limits::max(); -/**< Constant EdgeID specifying an equivalent of null edge */ -constexpr EdgeID EmptyEdgeID = std::numeric_limits::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 */ -}; - -/**< 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 */ -}; - -/** Supported Element-wise operations */ -enum class EltwiseOperation -{ - ADD, /**< Arithmetic addition */ - SUB, /**< Arithmetic subtraction */ - MUL /**< Arithmetic multiplication */ -}; - -/** Supported Convolution layer methods */ -enum class ConvolutionMethod -{ - DEFAULT, /**< Default approach using internal heuristics */ - GEMM, /**< GEMM based convolution */ - DIRECT, /**< Deep direct convolution */ - WINOGRAD /**< Winograd based convolution */ -}; - -/** 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, - BatchNormalizationLayer, - ConvolutionLayer, - DepthConcatenateLayer, - DepthwiseConvolutionLayer, - EltwiseLayer, - FlattenLayer, - FullyConnectedLayer, - NormalizationLayer, - PoolingLayer, - ReshapeLayer, - 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 */ -}; - -/** Common node parameters */ -struct NodeParams -{ - std::string name; /**< Node name */ - Target target; /**< Node target */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_TYPES_H__ */ diff --git a/arm_compute/graph2/Utils.h b/arm_compute/graph2/Utils.h deleted file mode 100644 index 0295bcb9af..0000000000 --- a/arm_compute/graph2/Utils.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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_GRAPH2_UTILS_H__ -#define __ARM_COMPUTE_GRAPH2_UTILS_H__ - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/PassManager.h" - -namespace arm_compute -{ -namespace graph2 -{ -// 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 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_UTILS_H__ */ diff --git a/arm_compute/graph2/Workload.h b/arm_compute/graph2/Workload.h deleted file mode 100644 index 85506e350e..0000000000 --- a/arm_compute/graph2/Workload.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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_GRAPH2_WORKLOAD_H__ -#define __ARM_COMPUTE_GRAPH2_WORKLOAD_H__ - -#include "arm_compute/runtime/IFunction.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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 task = {}; /**< Task to execute */ - INode *node = {}; /**< Node bound to this workload */ - std::vector commit_handles = {}; /**< Handles needs to sync for this task to execute */ - std::vector release_handles = {}; /**< Handles that can be released after this node execution */ - - /** Function operator */ - void operator()(); -}; - -/** Execution workload */ -struct ExecutionWorkload -{ - std::vector inputs = {}; /**< Input handles */ - std::vector outputs = {}; /**< Output handles */ - std::vector tasks = {}; /**< Execution workload */ -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_WORKLOAD_H__ */ diff --git a/arm_compute/graph2/algorithms/Algorithms.h b/arm_compute/graph2/algorithms/Algorithms.h deleted file mode 100644 index dfc36febe2..0000000000 --- a/arm_compute/graph2/algorithms/Algorithms.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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_GRAPH2_ALGORITHMS_H__ -#define __ARM_COMPUTE_GRAPH2_ALGORITHMS_H__ - -#include "arm_compute/graph2/algorithms/BFS.h" - -#endif /* __ARM_COMPUTE_GRAPH2_ALGORITHMS_H__ */ diff --git a/arm_compute/graph2/algorithms/BFS.h b/arm_compute/graph2/algorithms/BFS.h deleted file mode 100644 index d590658074..0000000000 --- a/arm_compute/graph2/algorithms/BFS.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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_GRAPH2_ALGORITHM_BFS_H__ -#define __ARM_COMPUTE_GRAPH2_ALGORITHM_BFS_H__ - -#include "arm_compute/graph2/Graph.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -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 &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 bfs(Graph &g) -{ - std::vector bfs_order_vector; - - // Created visited vector - std::vector visited(g.nodes().size(), false); - - // Create BFS queue - std::list 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ALGORITHM_BFS_H__ */ diff --git a/arm_compute/graph2/backends/BackendRegistrar.h b/arm_compute/graph2/backends/BackendRegistrar.h deleted file mode 100644 index f9905a7f8f..0000000000 --- a/arm_compute/graph2/backends/BackendRegistrar.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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_GRAPH2_BACKEND_REGISTRAR_H__ -#define ARM_COMPUTE_GRAPH2_BACKEND_REGISTRAR_H__ - -#include "arm_compute/graph2/Types.h" -#include "arm_compute/graph2/backends/BackendRegistry.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -namespace detail -{ -/** Helper class to statically register a backend */ -template -class BackendRegistrar final -{ -public: - /** Add a new backend to the backend registry - * - * @param[in] target Execution target - */ - BackendRegistrar(Target target); -}; - -template -inline BackendRegistrar::BackendRegistrar(Target target) -{ - BackendRegistry::get().add_backend(target); -} -} // namespace detail -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif /* ARM_COMPUTE_GRAPH2_BACKEND_REGISTRAR_H__ */ \ No newline at end of file diff --git a/arm_compute/graph2/backends/BackendRegistry.h b/arm_compute/graph2/backends/BackendRegistry.h deleted file mode 100644 index 9481115009..0000000000 --- a/arm_compute/graph2/backends/BackendRegistry.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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_GRAPH2_BACKEND_REGISTRY_H__ -#define __ARM_COMPUTE_GRAPH2_BACKEND_REGISTRY_H__ - -#include "arm_compute/graph2/IDeviceBackend.h" -#include "arm_compute/graph2/Types.h" -#include "support/ToolchainSupport.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -/** Registry holding all the supported backends */ -class BackendRegistry final -{ -public: - /** Gets backend registry instance - * - * @return Backend registry instance - */ - static BackendRegistry &get(); - /** Finds a backend in the registry - * - * @param[in] target Backend target - * - * @return Pointer to the backend interface if found, else nullptr - */ - IDeviceBackend *find_backend(Target target); - /** Checks if a backend for a given target exists - * - * @param[in] target Execution target - * - * @return True if exists else false - */ - bool contains(Target target) const; - /** Backends accessor - * - * @return Map containing the registered backends - */ - const std::map> &backends() const; - /** Registers a backend to the registry - * - * @param[in] target Execution target to register for - */ - template - void add_backend(Target target); - -private: - /** Default Constructor */ - BackendRegistry(); - -private: - std::map> _registered_backends; -}; - -template -inline void BackendRegistry::add_backend(Target target) -{ - _registered_backends[target] = support::cpp14::make_unique(); -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_BACKEND_REGISTRY_H__ */ diff --git a/arm_compute/graph2/backends/CL/CLDeviceBackend.h b/arm_compute/graph2/backends/CL/CLDeviceBackend.h deleted file mode 100644 index 3a70f0b112..0000000000 --- a/arm_compute/graph2/backends/CL/CLDeviceBackend.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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_GRAPH2_CLDEVICEBACKEND_H__ -#define __ARM_COMPUTE_GRAPH2_CLDEVICEBACKEND_H__ - -#include "arm_compute/graph2/IDeviceBackend.h" - -#include "arm_compute/runtime/CL/CLBufferAllocator.h" -#include "arm_compute/runtime/CL/CLTuner.h" - -namespace arm_compute -{ -namespace graph2 -{ -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; - std::unique_ptr create_tensor(const Tensor &tensor) override; - std::unique_ptr create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; - std::unique_ptr configure_node(INode &node, GraphContext &ctx) override; - Status validate_node(INode &node) override; - std::shared_ptr create_memory_manager(MemoryManagerAffinity affinity) override; - -private: - CLTuner _tuner; /**< CL kernel tuner */ - CLBufferAllocator _allocator; /**< CL buffer affinity allocator */ -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_CLDEVICEBACKEND_H__ diff --git a/arm_compute/graph2/backends/CL/CLFunctionFactory.h b/arm_compute/graph2/backends/CL/CLFunctionFactory.h deleted file mode 100644 index 94fd2b8be1..0000000000 --- a/arm_compute/graph2/backends/CL/CLFunctionFactory.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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_GRAPH2_CLFUNCTIONFACTORY_H__ -#define __ARM_COMPUTE_GRAPH2_CLFUNCTIONFACTORY_H__ - -#include "arm_compute/runtime/IFunction.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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 create(INode *node, GraphContext &ctx); -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_CLFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph2/backends/CL/CLNodeValidator.h b/arm_compute/graph2/backends/CL/CLNodeValidator.h deleted file mode 100644 index 251f705eee..0000000000 --- a/arm_compute/graph2/backends/CL/CLNodeValidator.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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_GRAPH2_CLNODEVALIDATOR_H__ -#define __ARM_COMPUTE_GRAPH2_CLNODEVALIDATOR_H__ - -#include "arm_compute/core/Error.h" - -namespace arm_compute -{ -namespace graph2 -{ -// Forward declarations -class INode; - -namespace backends -{ -class CLNodeValidator final -{ -public: - /** Validate a node - * - * @param[in] node Node to validate - * - * @return An error status - */ - static Status validate(INode *node); -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_CLNODEVALIDATOR_H__ diff --git a/arm_compute/graph2/backends/CL/CLSubTensorHandle.h b/arm_compute/graph2/backends/CL/CLSubTensorHandle.h deleted file mode 100644 index 6f3c00c041..0000000000 --- a/arm_compute/graph2/backends/CL/CLSubTensorHandle.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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_GRAPH2_CLSUBTENSORHANDLE_H__ -#define __ARM_COMPUTE_GRAPH2_CLSUBTENSORHANDLE_H__ - -#include "arm_compute/graph2/ITensorHandle.h" - -#include "arm_compute/runtime/CL/CLSubTensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_CLSUBTENSORHANDLE_H__ */ diff --git a/arm_compute/graph2/backends/CL/CLTensorHandle.h b/arm_compute/graph2/backends/CL/CLTensorHandle.h deleted file mode 100644 index 0b20d1d8fc..0000000000 --- a/arm_compute/graph2/backends/CL/CLTensorHandle.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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_GRAPH2_CLTENSORHANDLE_H__ -#define __ARM_COMPUTE_GRAPH2_CLTENSORHANDLE_H__ - -#include "arm_compute/graph2/ITensorHandle.h" - -#include "arm_compute/runtime/CL/CLTensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_CLTENSORHANDLE_H__ */ diff --git a/arm_compute/graph2/backends/GLES/GCDeviceBackend.h b/arm_compute/graph2/backends/GLES/GCDeviceBackend.h deleted file mode 100644 index 22ba91496b..0000000000 --- a/arm_compute/graph2/backends/GLES/GCDeviceBackend.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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_GRAPH2_GCDEVICEBACKEND_H__ -#define __ARM_COMPUTE_GRAPH2_GCDEVICEBACKEND_H__ - -#include "arm_compute/graph2/IDeviceBackend.h" - -#include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h" - -namespace arm_compute -{ -namespace graph2 -{ -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; - std::unique_ptr create_tensor(const Tensor &tensor) override; - std::unique_ptr create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; - std::unique_ptr configure_node(INode &node, GraphContext &ctx) override; - Status validate_node(INode &node) override; - std::shared_ptr create_memory_manager(MemoryManagerAffinity affinity) override; - -private: - GCBufferAllocator _allocator; /**< GLES buffer affinity allocator */ -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_GCDEVICEBACKEND_H__ diff --git a/arm_compute/graph2/backends/GLES/GCFunctionFactory.h b/arm_compute/graph2/backends/GLES/GCFunctionFactory.h deleted file mode 100644 index 4f7b2f451a..0000000000 --- a/arm_compute/graph2/backends/GLES/GCFunctionFactory.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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_GRAPH2_GCFUNCTIONFACTORY_H__ -#define __ARM_COMPUTE_GRAPH2_GCFUNCTIONFACTORY_H__ - -#include "arm_compute/runtime/IFunction.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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 create(INode *node, GraphContext &ctx); -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_GCFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph2/backends/GLES/GCNodeValidator.h b/arm_compute/graph2/backends/GLES/GCNodeValidator.h deleted file mode 100644 index 16b225b282..0000000000 --- a/arm_compute/graph2/backends/GLES/GCNodeValidator.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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_GRAPH2_GCNODEVALIDATOR_H__ -#define __ARM_COMPUTE_GRAPH2_GCNODEVALIDATOR_H__ - -#include "arm_compute/core/Error.h" - -namespace arm_compute -{ -namespace graph2 -{ -// Forward declarations -class INode; - -namespace backends -{ -class GCNodeValidator final -{ -public: - /** Validate a node - * - * @param[in] node Node to validate - * - * @return An error status - */ - static Status validate(INode *node); -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_GCNODEVALIDATOR_H__ diff --git a/arm_compute/graph2/backends/GLES/GCTensorHandle.h b/arm_compute/graph2/backends/GLES/GCTensorHandle.h deleted file mode 100644 index 281adee428..0000000000 --- a/arm_compute/graph2/backends/GLES/GCTensorHandle.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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_GRAPH2_GCTENSORHANDLE_H__ -#define __ARM_COMPUTE_GRAPH2_GCTENSORHANDLE_H__ - -#include "arm_compute/graph2/ITensorHandle.h" - -#include "arm_compute/runtime/GLES_COMPUTE/GCTensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_GCTENSORHANDLE_H__ */ diff --git a/arm_compute/graph2/backends/NEON/NEDeviceBackend.h b/arm_compute/graph2/backends/NEON/NEDeviceBackend.h deleted file mode 100644 index e81e9d921e..0000000000 --- a/arm_compute/graph2/backends/NEON/NEDeviceBackend.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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_GRAPH2_NEDEVICEBACKEND_H__ -#define __ARM_COMPUTE_GRAPH2_NEDEVICEBACKEND_H__ - -#include "arm_compute/graph2/IDeviceBackend.h" - -#include "arm_compute/runtime/Allocator.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -/** NEON device backend */ -class NEDeviceBackend final : public IDeviceBackend -{ -public: - NEDeviceBackend(); - - // Inherited overridden methods - void initialize_backend() override; - void setup_backend_context(GraphContext &ctx) override; - std::unique_ptr create_tensor(const Tensor &tensor) override; - std::unique_ptr create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override; - std::unique_ptr configure_node(INode &node, GraphContext &ctx) override; - Status validate_node(INode &node) override; - std::shared_ptr create_memory_manager(MemoryManagerAffinity affinity) override; - -private: - Allocator _allocator; /**< NEON backend allocator */ -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_NEDEVICEBACKEND_H__ diff --git a/arm_compute/graph2/backends/NEON/NEFunctionFactory.h b/arm_compute/graph2/backends/NEON/NEFunctionFactory.h deleted file mode 100644 index 09ca49ae6c..0000000000 --- a/arm_compute/graph2/backends/NEON/NEFunctionFactory.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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_GRAPH2_NEFUNCTIONFACTORY_H__ -#define __ARM_COMPUTE_GRAPH2_NEFUNCTIONFACTORY_H__ - -#include "arm_compute/runtime/IFunction.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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 create(INode *node, GraphContext &ctx); -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_NEFUNCTIONFACTORY_H__ diff --git a/arm_compute/graph2/backends/NEON/NENodeValidator.h b/arm_compute/graph2/backends/NEON/NENodeValidator.h deleted file mode 100644 index d39ab15a27..0000000000 --- a/arm_compute/graph2/backends/NEON/NENodeValidator.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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_GRAPH2_NENODEVALIDATOR_H__ -#define __ARM_COMPUTE_GRAPH2_NENODEVALIDATOR_H__ - -#include "arm_compute/core/Error.h" - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif //__ARM_COMPUTE_GRAPH2_NENODEVALIDATOR_H__ diff --git a/arm_compute/graph2/backends/NEON/NESubTensorHandle.h b/arm_compute/graph2/backends/NEON/NESubTensorHandle.h deleted file mode 100644 index d62b66f343..0000000000 --- a/arm_compute/graph2/backends/NEON/NESubTensorHandle.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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_GRAPH2_NESUBTENSORHANDLE_H__ -#define __ARM_COMPUTE_GRAPH2_NESUBTENSORHANDLE_H__ - -#include "arm_compute/graph2/ITensorHandle.h" - -#include "arm_compute/runtime/SubTensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_NESUBTENSORHANDLE_H__ */ diff --git a/arm_compute/graph2/backends/NEON/NETensorHandle.h b/arm_compute/graph2/backends/NEON/NETensorHandle.h deleted file mode 100644 index 23fd7ccc69..0000000000 --- a/arm_compute/graph2/backends/NEON/NETensorHandle.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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_GRAPH2_NETENSORHANDLE_H__ -#define __ARM_COMPUTE_GRAPH2_NETENSORHANDLE_H__ - -#include "arm_compute/graph2/ITensorHandle.h" - -#include "arm_compute/runtime/Tensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -/** NEON Tensor handle interface object **/ -class NETensorHandle final : public ITensorHandle -{ -public: - /** Default Constructor - * - * @param[in] info Tensor metadata - */ - 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: - arm_compute::Tensor _tensor; /**< Backend Tensor */ -}; -} // namespace backends -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_NETENSORHANDLE_H__ */ diff --git a/arm_compute/graph2/backends/Utils.h b/arm_compute/graph2/backends/Utils.h deleted file mode 100644 index bba75757eb..0000000000 --- a/arm_compute/graph2/backends/Utils.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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_GRAPH2_BACKENDS_UTILS_H__ -#define __ARM_COMPUTE_GRAPH2_BACKENDS_UTILS_H__ - -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/runtime/IMemoryManager.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 -std::pair, FunctionNameType> create_named_function(FunctionNameType name, ParameterType... args) -{ - auto f = arm_compute::support::cpp14::make_unique(); - f->configure(std::forward(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 -std::pair, FunctionNameType> create_named_memory_managed_function(FunctionNameType name, - MemoryManagerType mm, - ParameterType... args) -{ - auto f = arm_compute::support::cpp14::make_unique(mm); - f->configure(std::forward(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 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 graph2 -} // namespace arm_compute - -#endif /* __ARM_COMPUTE_GRAPH2_BACKENDS_UTILS_H__ */ diff --git a/arm_compute/graph2/backends/ValidateHelpers.h b/arm_compute/graph2/backends/ValidateHelpers.h deleted file mode 100644 index 0c93f0f138..0000000000 --- a/arm_compute/graph2/backends/ValidateHelpers.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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_GRAPH2_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ -#define __ARM_COMPUTE_GRAPH2_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ - -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/Types.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -#include "arm_compute/core/Error.h" -#include "arm_compute/core/ITensorInfo.h" - -namespace arm_compute -{ -namespace graph2 -{ -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::graph2::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 -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)) - { - 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 -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 graph2 -} // namespace arm_compute - -#endif /* __ARM_COMPUTE_GRAPH2_BACKENDS_DETAIL_VALIDATE_HELPERS_H__ */ diff --git a/arm_compute/graph2/detail/ExecutionHelpers.h b/arm_compute/graph2/detail/ExecutionHelpers.h deleted file mode 100644 index bc3cfd5d72..0000000000 --- a/arm_compute/graph2/detail/ExecutionHelpers.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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_GRAPH2_DETAIL_EXECUTION_HELPERS_H__ -#define __ARM_COMPUTE_GRAPH2_DETAIL_EXECUTION_HELPERS_H__ - -#include "arm_compute/graph2/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_DETAIL_EXECUTION_HELPERS_H__ */ diff --git a/arm_compute/graph2/frontend/ILayer.h b/arm_compute/graph2/frontend/ILayer.h deleted file mode 100644 index f8f6a5d47e..0000000000 --- a/arm_compute/graph2/frontend/ILayer.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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_GRAPH2_ILAYER_H__ -#define __ARM_COMPUTE_GRAPH2_ILAYER_H__ - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ILAYER_H__ */ diff --git a/arm_compute/graph2/frontend/IStream.h b/arm_compute/graph2/frontend/IStream.h deleted file mode 100644 index 110be5230d..0000000000 --- a/arm_compute/graph2/frontend/IStream.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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_GRAPH2_ISTREAM_H__ -#define __ARM_COMPUTE_GRAPH2_ISTREAM_H__ - -#include "arm_compute/graph2/frontend/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ISTREAM_H__ */ diff --git a/arm_compute/graph2/frontend/IStreamOperators.h b/arm_compute/graph2/frontend/IStreamOperators.h deleted file mode 100644 index 1798e4a4ab..0000000000 --- a/arm_compute/graph2/frontend/IStreamOperators.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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_GRAPH2_ISTREAM_OPERATORS_H__ -#define __ARM_COMPUTE_GRAPH2_ISTREAM_OPERATORS_H__ - -#include "arm_compute/graph2/frontend/IStream.h" -#include "arm_compute/graph2/frontend/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ISTREAM_OPERATORS_H__ */ diff --git a/arm_compute/graph2/frontend/Layers.h b/arm_compute/graph2/frontend/Layers.h deleted file mode 100644 index 779b471b52..0000000000 --- a/arm_compute/graph2/frontend/Layers.h +++ /dev/null @@ -1,471 +0,0 @@ -/* - * 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_GRAPH2_LAYERS_H__ -#define __ARM_COMPUTE_GRAPH2_LAYERS_H__ - -#include "arm_compute/graph2/GraphBuilder.h" -#include "arm_compute/graph2/Types.h" -#include "arm_compute/graph2/frontend/ILayer.h" -#include "arm_compute/graph2/frontend/IStream.h" -#include "arm_compute/graph2/frontend/SubStream.h" - -#include "arm_compute/core/utils/misc/Utility.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -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 - 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(std::move(sub_stream1))); - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream2))); - - utility::for_each([&](SubStream && sub_stream) - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(std::move(sub_stream))); - }, - std::move(rest_sub_streams)...); - } - /** Construct a branch layer - * - * @param[in] sub_stream Sub-stream - */ - template - BranchLayer(SubStream &&sub_stream) - : _branch_merge_method(BranchMergeMethod::DEPTH_CONCATENATE), _sub_streams() - { - _sub_streams.push_back(arm_compute::support::cpp14::make_unique(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 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> _sub_streams; -}; -} // namespace frontend -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_LAYERS_H__ */ diff --git a/arm_compute/graph2/frontend/Stream.h b/arm_compute/graph2/frontend/Stream.h deleted file mode 100644 index bfefe12225..0000000000 --- a/arm_compute/graph2/frontend/Stream.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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_GRAPH2_STREAM_H__ -#define __ARM_COMPUTE_GRAPH2_STREAM_H__ - -#include "arm_compute/graph2/frontend/IStream.h" -#include "arm_compute/graph2/frontend/IStreamOperators.h" -#include "arm_compute/graph2/frontend/Types.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/GraphManager.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_STREAM_H__ */ \ No newline at end of file diff --git a/arm_compute/graph2/frontend/SubStream.h b/arm_compute/graph2/frontend/SubStream.h deleted file mode 100644 index dee09b76ea..0000000000 --- a/arm_compute/graph2/frontend/SubStream.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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_GRAPH2_SUB_STREAM_H__ -#define __ARM_COMPUTE_GRAPH2_SUB_STREAM_H__ - -#include "arm_compute/graph2/frontend/IStream.h" -#include "arm_compute/graph2/frontend/IStreamOperators.h" -#include "arm_compute/graph2/frontend/Types.h" - -#include -#include - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_SUB_STREAM_H__ */ diff --git a/arm_compute/graph2/frontend/Types.h b/arm_compute/graph2/frontend/Types.h deleted file mode 100644 index d433d1547b..0000000000 --- a/arm_compute/graph2/frontend/Types.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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_GRAPH2_STREAM_TYPES_H__ -#define __ARM_COMPUTE_GRAPH2_STREAM_TYPES_H__ - -#include "arm_compute/graph2/Types.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace frontend -{ -// Import types for graph -using graph2::DataType; -using graph2::TensorShape; - -using graph2::ActivationLayerInfo; -using graph2::NormalizationLayerInfo; -using graph2::NormType; -using graph2::PadStrideInfo; -using graph2::PoolingLayerInfo; -using graph2::PoolingType; -using graph2::Target; -using graph2::ConvolutionMethod; -using graph2::DepthwiseConvolutionMethod; -using graph2::TensorDescriptor; -using graph2::DimensionRoundingType; -using graph2::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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_STREAM_TYPES_H__ */ \ No newline at end of file diff --git a/arm_compute/graph2/mutators/DepthConcatSubTensorMutator.h b/arm_compute/graph2/mutators/DepthConcatSubTensorMutator.h deleted file mode 100644 index bdf2e01edb..0000000000 --- a/arm_compute/graph2/mutators/DepthConcatSubTensorMutator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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_GRAPH2_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ -#define __ARM_COMPUTE_GRAPH2_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ - -#include "arm_compute/graph2/IGraphMutator.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_DEPTH_CONCAT_SUBTENSOR_MUTATOR_H__ */ diff --git a/arm_compute/graph2/mutators/GraphMutators.h b/arm_compute/graph2/mutators/GraphMutators.h deleted file mode 100644 index 3275e32961..0000000000 --- a/arm_compute/graph2/mutators/GraphMutators.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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_GRAPH2_GRAPH_MUTATORS_H__ -#define __ARM_COMPUTE_GRAPH2_GRAPH_MUTATORS_H__ - -#include "arm_compute/graph2/mutators/DepthConcatSubTensorMutator.h" -#include "arm_compute/graph2/mutators/InPlaceOperationMutator.h" -#include "arm_compute/graph2/mutators/NodeFusionMutator.h" -#include "arm_compute/graph2/mutators/SplitLayerSubTensorMutator.h" - -#endif /* __ARM_COMPUTE_GRAPH2_GRAPH_MUTATORS_H__ */ diff --git a/arm_compute/graph2/mutators/InPlaceOperationMutator.h b/arm_compute/graph2/mutators/InPlaceOperationMutator.h deleted file mode 100644 index 7e4018a736..0000000000 --- a/arm_compute/graph2/mutators/InPlaceOperationMutator.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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_GRAPH2_INPLACE_OPERATION_MUTATOR_H__ -#define __ARM_COMPUTE_GRAPH2_INPLACE_OPERATION_MUTATOR_H__ - -#include "arm_compute/graph2/IGraphMutator.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_INPLACE_OPERATION_MUTATOR_H__ */ diff --git a/arm_compute/graph2/mutators/NodeFusionMutator.h b/arm_compute/graph2/mutators/NodeFusionMutator.h deleted file mode 100644 index 4371bd3ebe..0000000000 --- a/arm_compute/graph2/mutators/NodeFusionMutator.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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_GRAPH2_NODE_FUSION_MUTATOR_H__ -#define __ARM_COMPUTE_GRAPH2_NODE_FUSION_MUTATOR_H__ - -#include "arm_compute/graph2/IGraphMutator.h" - -namespace arm_compute -{ -namespace graph2 -{ -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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_NODE_FUSION_MUTATOR_H__ */ diff --git a/arm_compute/graph2/mutators/SplitLayerSubTensorMutator.h b/arm_compute/graph2/mutators/SplitLayerSubTensorMutator.h deleted file mode 100644 index 82ee509a32..0000000000 --- a/arm_compute/graph2/mutators/SplitLayerSubTensorMutator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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_GRAPH2_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ -#define __ARM_COMPUTE_GRAPH2_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ - -#include "arm_compute/graph2/IGraphMutator.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_SPLIT_LAYER_SUBTENSOR_MUTATOR_H__ */ diff --git a/arm_compute/graph2/nodes/ActivationLayerNode.h b/arm_compute/graph2/nodes/ActivationLayerNode.h deleted file mode 100644 index cb19c818c5..0000000000 --- a/arm_compute/graph2/nodes/ActivationLayerNode.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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_GRAPH2_ACTIVATION_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_ACTIVATION_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Activation Layer node */ -class ActivationLayerNode final : public INode -{ -public: - /** Constructor - * - * @param[in] info Activation Layer information - */ - ActivationLayerNode(ActivationLayerInfo info); - /** Activation metadata accessor - * - * @return The activation info of the layer - */ - ActivationLayerInfo activation_info() 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: - ActivationLayerInfo _info; -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ACTIVATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/BatchNormalizationLayerNode.h b/arm_compute/graph2/nodes/BatchNormalizationLayerNode.h deleted file mode 100644 index a6e8e2b98e..0000000000 --- a/arm_compute/graph2/nodes/BatchNormalizationLayerNode.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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_GRAPH2_BATCH_NORMALIZATION_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_BATCH_NORMALIZATION_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_BATCH_NORMALIZATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/ConstNode.h b/arm_compute/graph2/nodes/ConstNode.h deleted file mode 100644 index e1c66176f0..0000000000 --- a/arm_compute/graph2/nodes/ConstNode.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_GRAPH2_CONST_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_CONST_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_CONST_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/ConvolutionLayerNode.h b/arm_compute/graph2/nodes/ConvolutionLayerNode.h deleted file mode 100644 index 6e3c9bef32..0000000000 --- a/arm_compute/graph2/nodes/ConvolutionLayerNode.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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_GRAPH2_CONVOLUTION_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_CONVOLUTION_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_CONVOLUTION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/DepthConcatenateLayerNode.h b/arm_compute/graph2/nodes/DepthConcatenateLayerNode.h deleted file mode 100644 index 23c31048e9..0000000000 --- a/arm_compute/graph2/nodes/DepthConcatenateLayerNode.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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_GRAPH2_DEPTH_CONCATENATE_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_DEPTH_CONCATENATE_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 &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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_DEPTH_CONCATENATE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/DepthwiseConvolutionLayerNode.h b/arm_compute/graph2/nodes/DepthwiseConvolutionLayerNode.h deleted file mode 100644 index d5b8e34554..0000000000 --- a/arm_compute/graph2/nodes/DepthwiseConvolutionLayerNode.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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_GRAPH2_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_DEPTHWISE_CONVOLUTION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/EltwiseLayerNode.h b/arm_compute/graph2/nodes/EltwiseLayerNode.h deleted file mode 100644 index 48df2b715d..0000000000 --- a/arm_compute/graph2/nodes/EltwiseLayerNode.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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_GRAPH2_ELTWISE_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_ELTWISE_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Eltwise Layer node */ -class EltwiseLayerNode final : public INode -{ -public: - /** Constructor - * - * @param[in] op Element-wise operation to perform - */ - EltwiseLayerNode(EltwiseOperation op); - /** Eltwise operation accessor - * - * @return Eltwise operation that is to be performed by the node - */ - EltwiseOperation eltwise_operation() 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: - EltwiseOperation _op; -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_ELTWISE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/FlattenLayerNode.h b/arm_compute/graph2/nodes/FlattenLayerNode.h deleted file mode 100644 index 41f6f85045..0000000000 --- a/arm_compute/graph2/nodes/FlattenLayerNode.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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_GRAPH2_FLATTEN_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_FLATTEN_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_FLATTEN_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/FullyConnectedLayerNode.h b/arm_compute/graph2/nodes/FullyConnectedLayerNode.h deleted file mode 100644 index 5c71f4ca69..0000000000 --- a/arm_compute/graph2/nodes/FullyConnectedLayerNode.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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_GRAPH2_FULLY_CONNECTED_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_FULLY_CONNECTED_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_FULLY_CONNECTED_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/InputNode.h b/arm_compute/graph2/nodes/InputNode.h deleted file mode 100644 index 667dcfacf0..0000000000 --- a/arm_compute/graph2/nodes/InputNode.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_GRAPH2_INPUT_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_INPUT_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_INPUT_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/Nodes.h b/arm_compute/graph2/nodes/Nodes.h deleted file mode 100644 index 3786978661..0000000000 --- a/arm_compute/graph2/nodes/Nodes.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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_GRAPH2_NODES_H__ -#define __ARM_COMPUTE_GRAPH2_NODES_H__ - -#include "arm_compute/graph2/nodes/ActivationLayerNode.h" -#include "arm_compute/graph2/nodes/BatchNormalizationLayerNode.h" -#include "arm_compute/graph2/nodes/ConstNode.h" -#include "arm_compute/graph2/nodes/ConvolutionLayerNode.h" -#include "arm_compute/graph2/nodes/DepthConcatenateLayerNode.h" -#include "arm_compute/graph2/nodes/DepthwiseConvolutionLayerNode.h" -#include "arm_compute/graph2/nodes/EltwiseLayerNode.h" -#include "arm_compute/graph2/nodes/FlattenLayerNode.h" -#include "arm_compute/graph2/nodes/FullyConnectedLayerNode.h" -#include "arm_compute/graph2/nodes/InputNode.h" -#include "arm_compute/graph2/nodes/NormalizationLayerNode.h" -#include "arm_compute/graph2/nodes/OutputNode.h" -#include "arm_compute/graph2/nodes/PoolingLayerNode.h" -#include "arm_compute/graph2/nodes/ReshapeLayerNode.h" -#include "arm_compute/graph2/nodes/SoftmaxLayerNode.h" -#include "arm_compute/graph2/nodes/SplitLayerNode.h" - -#endif /* __ARM_COMPUTE_GRAPH2_NODES_H__ */ diff --git a/arm_compute/graph2/nodes/NodesFwd.h b/arm_compute/graph2/nodes/NodesFwd.h deleted file mode 100644 index 08f2454cde..0000000000 --- a/arm_compute/graph2/nodes/NodesFwd.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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_GRAPH2_NODES_FWD_H__ -#define __ARM_COMPUTE_GRAPH2_NODES_FWD_H__ - -namespace arm_compute -{ -namespace graph2 -{ -// 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_NODES_FWD_H__ */ diff --git a/arm_compute/graph2/nodes/NormalizationLayerNode.h b/arm_compute/graph2/nodes/NormalizationLayerNode.h deleted file mode 100644 index 78a843a1e7..0000000000 --- a/arm_compute/graph2/nodes/NormalizationLayerNode.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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_GRAPH2_NORMALIZATION_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_NORMALIZATION_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Normalization Layer node */ -class NormalizationLayerNode final : public INode -{ -public: - /** Constructor - * - * @param[in] norm_info Normalization Layer information - */ - NormalizationLayerNode(NormalizationLayerInfo norm_info); - /** Normalization info accessor - * - * @return Normalization layer info - */ - NormalizationLayerInfo normalization_info() 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: - NormalizationLayerInfo _info; -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_NORMALIZATION_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/OutputNode.h b/arm_compute/graph2/nodes/OutputNode.h deleted file mode 100644 index 0c28c84214..0000000000 --- a/arm_compute/graph2/nodes/OutputNode.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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_GRAPH2_OUTPUT_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_OUTPUT_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Output Layer node */ -class OutputNode final : public INode -{ -public: - /** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_OUTPUT_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/PoolingLayerNode.h b/arm_compute/graph2/nodes/PoolingLayerNode.h deleted file mode 100644 index 09332a9367..0000000000 --- a/arm_compute/graph2/nodes/PoolingLayerNode.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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_GRAPH2_POOLING_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_POOLING_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Pooling Layer node */ -class PoolingLayerNode final : public INode -{ -public: - /** Constructor - * - * @param[in] pool_info Pooling Layer information - */ - 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 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: - PoolingLayerInfo _info; -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_POOLING_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/ReshapeLayerNode.h b/arm_compute/graph2/nodes/ReshapeLayerNode.h deleted file mode 100644 index 27d52601da..0000000000 --- a/arm_compute/graph2/nodes/ReshapeLayerNode.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_GRAPH2_RESHAPE_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_RESHAPE_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Reshape Layer node */ -class ReshapeLayerNode final : public INode -{ -public: - /** Constructor - * - * @param[in] shape Reshaped tensor shape - */ - ReshapeLayerNode(TensorShape shape); - - // 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_RESHAPE_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/SoftmaxLayerNode.h b/arm_compute/graph2/nodes/SoftmaxLayerNode.h deleted file mode 100644 index b1091e28fc..0000000000 --- a/arm_compute/graph2/nodes/SoftmaxLayerNode.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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_GRAPH2_SOFTMAX_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_SOFTMAX_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -namespace arm_compute -{ -namespace graph2 -{ -/** Softmax Layer node */ -class SoftmaxLayerNode final : public INode -{ -public: - /** Constructor - * - * @param[in] beta (Optional) Beta parameter. Defaults to 1 - */ - SoftmaxLayerNode(float beta = 1.f); - /** Beta parameter accessor - * - * @return Beta parameter - */ - float beta() 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: - float _beta; -}; -} // namespace graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_SOFTMAX_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/nodes/SplitLayerNode.h b/arm_compute/graph2/nodes/SplitLayerNode.h deleted file mode 100644 index 90e6134ac0..0000000000 --- a/arm_compute/graph2/nodes/SplitLayerNode.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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_GRAPH2_SPLIT_LAYER_NODE_H__ -#define __ARM_COMPUTE_GRAPH2_SPLIT_LAYER_NODE_H__ - -#include "arm_compute/graph2/INode.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_SPLIT_LAYER_NODE_H__ */ diff --git a/arm_compute/graph2/printers/DotGraphPrinter.h b/arm_compute/graph2/printers/DotGraphPrinter.h deleted file mode 100644 index 0efdf772e3..0000000000 --- a/arm_compute/graph2/printers/DotGraphPrinter.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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_GRAPH2_DOTGRAPHPRINTER_H__ -#define __ARM_COMPUTE_GRAPH2_DOTGRAPHPRINTER_H__ - -#include "arm_compute/graph2/IGraphPrinter.h" - -#include "arm_compute/graph2/INodeVisitor.h" - -#include - -namespace arm_compute -{ -namespace graph2 -{ -/** 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 graph2 -} // namespace arm_compute -#endif /* __ARM_COMPUTE_GRAPH2_DOTGRAPHPRINTER_H__ */ diff --git a/arm_compute/graph2/printers/Printers.h b/arm_compute/graph2/printers/Printers.h deleted file mode 100644 index 0b70139683..0000000000 --- a/arm_compute/graph2/printers/Printers.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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_GRAPH2_PRINTERS_H__ -#define __ARM_COMPUTE_GRAPH2_PRINTERS_H__ - -#include "arm_compute/graph2/printers/DotGraphPrinter.h" - -#endif /* __ARM_COMPUTE_GRAPH2_PRINTERS_H__ */ diff --git a/docs/00_introduction.dox b/docs/00_introduction.dox index 555cec5c35..17d1bdea63 100644 --- a/docs/00_introduction.dox +++ b/docs/00_introduction.dox @@ -321,13 +321,13 @@ v17.12 Public major release - @ref CLGEMMLowpQuantizeDownInt32ToUint8ScaleKernel / @ref CLGEMMLowpQuantizeDownInt32ToUint8Scale - New graph nodes for NEON and OpenCL - - @ref graph::BranchLayer - - @ref graph::DepthConvertLayer - - @ref graph::DepthwiseConvolutionLayer - - @ref graph::DequantizationLayer - - @ref graph::FlattenLayer - - @ref graph::QuantizationLayer - - @ref graph::ReshapeLayer + - graph::BranchLayer + - graph::DepthConvertLayer + - graph::DepthwiseConvolutionLayer + - graph::DequantizationLayer + - graph::FlattenLayer + - graph::QuantizationLayer + - graph::ReshapeLayer v17.10 Public maintenance release - Bug fixes: @@ -632,9 +632,6 @@ For Linux, the library was successfully built and tested using the following Lin - gcc-linaro-4.9-2016.02-x86_64_aarch64-linux-gnu - gcc-linaro-6.3.1-2017.02-i686_aarch64-linux-gnu -@note If you are building with opencl=1 then scons will expect to find libOpenCL.so either in the current directory or in "build" (See the section below if you need a stub OpenCL library to link against) -@note If you are building with gles_compute=1 then scons will expect to find libEGL.so / libGLESv1_CM.so / libGLESv2.so either in the current directory or in "build" (See the section below if you need a stub OpenCL library to link against) - To cross-compile the library in debug mode, with NEON only support, for Linux 32bit: scons Werror=1 -j8 debug=1 neon=1 opencl=0 os=linux arch=armv7a @@ -672,7 +669,7 @@ or simply remove the build parameter as build=cross_compile is the default value The examples get automatically built by scons as part of the build process of the library described above. This section just describes how you can build and link your own application against our library. -@note The following command lines assume the arm_compute and libOpenCL binaries are present in the current directory or in the system library path. If this is not the case you can specify the location of the pre-built library with the compiler option -L. When building the OpenCL example the commands below assume that the CL headers are located in the include folder where the command is executed. +@note The following command lines assume the arm_compute binaries are present in the current directory or in the system library path. If this is not the case you can specify the location of the pre-built library with the compiler option -L. When building the OpenCL example the commands below assume that the CL headers are located in the include folder where the command is executed. To cross compile a NEON example for Linux 32bit: @@ -686,11 +683,11 @@ To cross compile a NEON example for Linux 64bit: To cross compile an OpenCL example for Linux 32bit: - arm-linux-gnueabihf-g++ examples/cl_convolution.cpp utils/Utils.cpp -I. -Iinclude -std=c++11 -mfpu=neon -L. -larm_compute -larm_compute_core -lOpenCL -o cl_convolution -DARM_COMPUTE_CL + arm-linux-gnueabihf-g++ examples/cl_convolution.cpp utils/Utils.cpp -I. -Iinclude -std=c++11 -mfpu=neon -L. -larm_compute -larm_compute_core -o cl_convolution -DARM_COMPUTE_CL To cross compile an OpenCL example for Linux 64bit: - aarch64-linux-gnu-g++ examples/cl_convolution.cpp utils/Utils.cpp -I. -Iinclude -std=c++11 -L. -larm_compute -larm_compute_core -lOpenCL -o cl_convolution -DARM_COMPUTE_CL + aarch64-linux-gnu-g++ examples/cl_convolution.cpp utils/Utils.cpp -I. -Iinclude -std=c++11 -L. -larm_compute -larm_compute_core -o cl_convolution -DARM_COMPUTE_CL To cross compile a GLES example for Linux 32bit: @@ -730,7 +727,7 @@ To compile natively (i.e directly on an ARM device) for NEON for Linux 64bit: To compile natively (i.e directly on an ARM device) for OpenCL for Linux 32bit or Linux 64bit: - g++ examples/cl_convolution.cpp utils/Utils.cpp -I. -Iinclude -std=c++11 -larm_compute -larm_compute_core -lOpenCL -o cl_convolution -DARM_COMPUTE_CL + g++ examples/cl_convolution.cpp utils/Utils.cpp -I. -Iinclude -std=c++11 -larm_compute -larm_compute_core -o cl_convolution -DARM_COMPUTE_CL To compile natively (i.e directly on an ARM device) for GLES for Linux 32bit or Linux 64bit: @@ -797,8 +794,6 @@ Here is a guide to using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement AlexNet's network using the Compute Library's graph API @@ -54,7 +54,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); // TODO (geopin01) : Get GPU target somehow and set gemm also for midgard ? const bool is_gemm_convolution5x5 = (target_hint == Target::NEON); diff --git a/examples/graph_googlenet.cpp b/examples/graph_googlenet.cpp index d6e76fdced..6c3fac4af2 100644 --- a/examples/graph_googlenet.cpp +++ b/examples/graph_googlenet.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -30,7 +30,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement Googlenet's network using the Compute Library's graph API @@ -53,7 +53,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = (target_hint == Target::CL) ? ConvolutionMethod::WINOGRAD : ConvolutionMethod::GEMM; // Parse arguments diff --git a/examples/graph_inception_v3.cpp b/examples/graph_inception_v3.cpp index 5f049d0f4a..22e6f6e489 100644 --- a/examples/graph_inception_v3.cpp +++ b/examples/graph_inception_v3.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -30,7 +30,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement InceptionV3's network using the Compute Library's graph API @@ -52,7 +52,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = (target_hint == Target::CL) ? ConvolutionMethod::WINOGRAD : ConvolutionMethod::GEMM; diff --git a/examples/graph_inception_v4.cpp b/examples/graph_inception_v4.cpp index 847c5b8250..1f7875176f 100644 --- a/examples/graph_inception_v4.cpp +++ b/examples/graph_inception_v4.cpp @@ -21,8 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/core/Error.h" -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -31,7 +30,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement InceptionV4's network using the Compute Library's graph API @@ -56,7 +55,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = (target_hint == Target::CL) ? ConvolutionMethod::WINOGRAD : ConvolutionMethod::GEMM; diff --git a/examples/graph_lenet.cpp b/examples/graph_lenet.cpp index 3803da9b83..8aca0fa45b 100644 --- a/examples/graph_lenet.cpp +++ b/examples/graph_lenet.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" @@ -30,7 +30,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement LeNet's network using the Compute Library's graph API @@ -48,7 +48,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); // Parse arguments if(argc < 2) diff --git a/examples/graph_mobilenet.cpp b/examples/graph_mobilenet.cpp index bd25b927fe..055f289f52 100644 --- a/examples/graph_mobilenet.cpp +++ b/examples/graph_mobilenet.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -29,7 +29,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement MobileNet's network using the Compute Library's graph API @@ -51,7 +51,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = ConvolutionMethod::GEMM; DepthwiseConvolutionMethod depthwise_convolution_hint = DepthwiseConvolutionMethod::OPTIMIZED_3x3; diff --git a/examples/graph_mobilenet_qasymm8.cpp b/examples/graph_mobilenet_qasymm8.cpp index 76b13dd851..cb49ffdfb4 100644 --- a/examples/graph_mobilenet_qasymm8.cpp +++ b/examples/graph_mobilenet_qasymm8.cpp @@ -21,14 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/Nodes.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" -using namespace arm_compute; -using namespace arm_compute::graph; +#include + +using namespace arm_compute::utils; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement QASYMM8 MobileNet's network using the Compute Library's graph API @@ -36,9 +37,11 @@ using namespace arm_compute::graph_utils; * @param[in] argc Number of arguments * @param[in] argv Arguments ( [optional] Target (0 = NEON, 1 = OpenCL, 2 = OpenCL with Tuner), [optional] Path to the weights folder, [optional] npy_input, [optional] labels ) */ -class GraphMobileNetQASYMM8Example : public utils::Example +class GraphMobileNetQASYMM8Example : public Example { public: + //FIXME: Missing quantization info to the tensor descriptor (Giorgio is working on it) +#if 0 void do_setup(int argc, char **argv) override { std::string data_path; /* Path to the trainable data */ @@ -217,6 +220,8 @@ private: return BranchLayer(std::move(sg)); } +#endif /* if 0 */ + Stream graph { 0, "MobileNetV1_QASYMM8" }; }; /** Main program for MobileNetQASYMM8 * @@ -225,5 +230,5 @@ private: */ int main(int argc, char **argv) { - return utils::run_example(argc, argv); + return arm_compute::utils::run_example(argc, argv); } diff --git a/examples/graph_resnet50.cpp b/examples/graph_resnet50.cpp index ec447de66f..eb74a1aa11 100644 --- a/examples/graph_resnet50.cpp +++ b/examples/graph_resnet50.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -29,7 +29,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement Microsoft's ResNet50 network using the Compute Library's graph API @@ -53,7 +53,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = (target_hint == Target::CL) ? ConvolutionMethod::WINOGRAD : ConvolutionMethod::GEMM; diff --git a/examples/graph_squeezenet.cpp b/examples/graph_squeezenet.cpp index ddbe6b43ce..32be14305f 100644 --- a/examples/graph_squeezenet.cpp +++ b/examples/graph_squeezenet.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -30,7 +30,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; using namespace arm_compute::logging; @@ -54,7 +54,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = (target_hint == Target::CL) ? ConvolutionMethod::WINOGRAD : ConvolutionMethod::GEMM; diff --git a/examples/graph_squeezenet_v1_1.cpp b/examples/graph_squeezenet_v1_1.cpp index faab79fcf1..2bdb00d7c2 100644 --- a/examples/graph_squeezenet_v1_1.cpp +++ b/examples/graph_squeezenet_v1_1.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -30,7 +30,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; namespace @@ -57,7 +57,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = (target_hint == Target::CL) ? ConvolutionMethod::WINOGRAD : ConvolutionMethod::GEMM; diff --git a/examples/graph_vgg16.cpp b/examples/graph_vgg16.cpp index 23742ed771..82be97c316 100644 --- a/examples/graph_vgg16.cpp +++ b/examples/graph_vgg16.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -29,7 +29,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; namespace @@ -66,7 +66,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); // Check if we can use GEMM-based convolutions evaluating if the platform has at least 1.8 GB of available memory const size_t memory_required = 1932735283L; diff --git a/examples/graph_vgg19.cpp b/examples/graph_vgg19.cpp index f282b90630..606b0e0142 100644 --- a/examples/graph_vgg19.cpp +++ b/examples/graph_vgg19.cpp @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph2.h" +#include "arm_compute/graph.h" #include "support/ToolchainSupport.h" #include "utils/GraphUtils.h" #include "utils/Utils.h" @@ -29,7 +29,7 @@ #include using namespace arm_compute::utils; -using namespace arm_compute::graph2::frontend; +using namespace arm_compute::graph::frontend; using namespace arm_compute::graph_utils; /** Example demonstrating how to implement VGG19's network using the Compute Library's graph API @@ -52,7 +52,7 @@ public: // Set target. 0 (NEON), 1 (OpenCL), 2 (OpenCL with Tuner). By default it is NEON const int target = argc > 1 ? std::strtol(argv[1], nullptr, 10) : 0; - Target target_hint = set_target_hint2(target); + Target target_hint = set_target_hint(target); ConvolutionMethod convolution_hint = ConvolutionMethod::DIRECT; // Parse arguments diff --git a/opencl-1.2-stubs/SConscript b/opencl-1.2-stubs/SConscript index dab2e2e7f7..da37282fe8 100644 --- a/opencl-1.2-stubs/SConscript +++ b/opencl-1.2-stubs/SConscript @@ -3,5 +3,3 @@ Import("env") opencl = env.SharedLibrary("OpenCL", "opencl_stubs.c") alias = Alias("opencl", opencl) Default(alias) - -Export("opencl") diff --git a/opengles-3.1-stubs/SConscript b/opengles-3.1-stubs/SConscript index 5d4cb87811..c43c6c4cae 100644 --- a/opengles-3.1-stubs/SConscript +++ b/opengles-3.1-stubs/SConscript @@ -3,9 +3,7 @@ Import("env") egl = env.SharedLibrary("EGL", "EGL.c") alias = Alias("egl", egl) Default(alias) -Export("egl") glesv2 = env.SharedLibrary("GLESv2", "GLESv2.c") alias = Alias("glesv2", glesv2) Default(alias) -Export("glesv2") diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp index 0ef800f265..a8ed9733ef 100644 --- a/src/core/CL/OpenCL.cpp +++ b/src/core/CL/OpenCL.cpp @@ -115,6 +115,8 @@ bool CLSymbols::load(const std::string &library) LOAD_FUNCTION_PTR(clSVMFree, handle); LOAD_FUNCTION_PTR(clEnqueueSVMMap, handle); LOAD_FUNCTION_PTR(clEnqueueSVMUnmap, handle); + LOAD_FUNCTION_PTR(clEnqueueMarker, handle); + LOAD_FUNCTION_PTR(clWaitForEvents, handle); #undef LOAD_FUNCTION_PTR @@ -133,6 +135,36 @@ bool opencl_is_available() } } // namespace arm_compute +cl_int clEnqueueMarker(cl_command_queue command_queue, + cl_event *event) +{ + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clEnqueueMarker_ptr; + if(func != nullptr) + { + return func(command_queue, event); + } + else + { + return CL_OUT_OF_RESOURCES; + } +} + +cl_int clWaitForEvents(cl_uint num_events, + const cl_event *event_list) +{ + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clWaitForEvents_ptr; + if(func != nullptr) + { + return func(num_events, event_list); + } + else + { + return CL_OUT_OF_RESOURCES; + } +} + cl_int clEnqueueSVMMap(cl_command_queue command_queue, cl_bool blocking_map, cl_map_flags flags, void *svm_ptr, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { diff --git a/src/graph/CL/CLMap.cpp b/src/graph/CL/CLMap.cpp deleted file mode 100644 index 5289ea9a04..0000000000 --- a/src/graph/CL/CLMap.cpp +++ /dev/null @@ -1,43 +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. - */ -#include "arm_compute/graph/CL/CLMap.h" - -#include "arm_compute/core/CL/ICLTensor.h" -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Validate.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/runtime/CL/CLScheduler.h" - -using namespace arm_compute::graph; - -CLMap::CLMap(ITensorObject *tensor, bool blocking) - : _tensor(dynamic_cast(tensor->tensor())), _blocking(blocking) -{ - ARM_COMPUTE_ERROR_ON_NULLPTR(_tensor); -} - -void CLMap::run() -{ - _tensor->map(arm_compute::CLScheduler::get().queue(), _blocking); -} diff --git a/src/graph/CL/CLUnmap.cpp b/src/graph/CL/CLUnmap.cpp deleted file mode 100644 index 31f2f19e9c..0000000000 --- a/src/graph/CL/CLUnmap.cpp +++ /dev/null @@ -1,43 +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. - */ -#include "arm_compute/graph/CL/CLUnmap.h" - -#include "arm_compute/core/CL/ICLTensor.h" -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Validate.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/runtime/CL/CLScheduler.h" - -using namespace arm_compute::graph; - -CLUnmap::CLUnmap(ITensorObject *tensor) - : _tensor(dynamic_cast(tensor->tensor())) -{ - ARM_COMPUTE_ERROR_ON_NULLPTR(_tensor); -} - -void CLUnmap::run() -{ - _tensor->unmap(arm_compute::CLScheduler::get().queue()); -} diff --git a/src/graph/Graph.cpp b/src/graph/Graph.cpp index 47bd672114..e1ffeed668 100644 --- a/src/graph/Graph.cpp +++ b/src/graph/Graph.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -23,293 +23,205 @@ */ #include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/CL/CLMap.h" -#include "arm_compute/graph/CL/CLUnmap.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/ITensorObject.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/runtime/CL/CLScheduler.h" -#include "arm_compute/runtime/CL/CLTensor.h" -#include "arm_compute/runtime/CL/CLTuner.h" -#include "arm_compute/runtime/Tensor.h" -#include "support/ToolchainSupport.h" - -#include - -using namespace arm_compute::graph; - -namespace +namespace arm_compute { -bool file_exists(const std::string &filename) +namespace graph { - std::ifstream file(filename); - return file.good(); -} - -} // namespace -struct Stage +Graph::Graph(GraphID id, std::string name) + : _id(id), _name(std::move(name)), _nodes(), _edges(), _tensors(), _tagged_nodes(), _mtx() { - ITensorObject *_input; - ITensorObject *_output; - std::unique_ptr _function; -}; +} -struct Graph::Private -{ -public: - /** Finalizes the current node's configuration - * - * @param _next_hint Device execution hint - */ - void configure(GraphHints _next_hints); - - GraphContext _ctx{}; - std::vector _pipeline{}; - std::vector> _tensors{}; - std::vector> _nodes{}; - GraphHints _current_hints{}; - GraphHints _next_hints{}; - std::unique_ptr _graph_input{ nullptr }; - std::unique_ptr _graph_output{ nullptr }; - std::unique_ptr _current_node{ nullptr }; - ITensorObject *_current_output{ nullptr }; - bool _info_enabled{ false }; - CLTuner _tuner{}; - -private: - ITensorObject *_current_input{ nullptr }; - GraphHints _previous_hints{}; -}; - -static const std::string tuner_data_filename = "acl_tuner.csv"; -Graph::~Graph() //NOLINT +bool Graph::remove_node(NodeID nid) { - if(_pimpl->_tuner.tune_new_kernels() && !_pimpl->_tuner.lws_table().empty()) + if(nid >= _nodes.size()) { - _pimpl->_tuner.save_to_file(tuner_data_filename); + return false; } -} -Graph::Graph() - : _pimpl{ new Private() } -{ - graph_init(); -} + std::unique_ptr &node = _nodes[nid]; -void Graph::graph_init(const bool use_cl_tuner) -{ - // Check if OpenCL is available and initialize the scheduler - if(opencl_is_available()) + // Remove node connections + if(node) { - if(_pimpl->_tuner.lws_table().empty() && file_exists(tuner_data_filename)) + for(auto &input_eid : node->_input_edges) { - _pimpl->_tuner.load_from_file(tuner_data_filename); + remove_connection(input_eid); } - _pimpl->_tuner.set_tune_new_kernels(use_cl_tuner); - arm_compute::CLScheduler::get().default_init(&_pimpl->_tuner); - } -} -void Graph::run() -{ - while(true) - { - if(_pimpl->_graph_input->has_accessor() && !_pimpl->_graph_input->call_accessor()) + for(auto &outpud_eid : node->_output_edges) { - return; + remove_connection(outpud_eid); } + } - for(auto &stage : _pimpl->_pipeline) - { - stage._function->run(); - } + node = nullptr; - if((_pimpl->_graph_output->has_accessor() && !_pimpl->_graph_output->call_accessor()) - || (!_pimpl->_graph_output->has_accessor())) - { - return; - } - } + return true; } -//Finalize current node's configuration -void Graph::Private::configure(GraphHints _next_hints) +EdgeID Graph::add_connection(NodeID source, size_t source_idx, NodeID sink, size_t sink_idx) { - ARM_COMPUTE_ERROR_ON(_current_node == nullptr); - ARM_COMPUTE_ERROR_ON(_graph_input == nullptr); + std::lock_guard lock(_mtx); - // Is it the first node of the graph ? - if(_current_input == nullptr) - { - _graph_input->set_target(_current_hints.target_hint()); - _current_input = _graph_input.get(); - _previous_hints = _current_hints; // For the first node just assume the previous node was of the same type as this one - } + // Check if node index is valid, if node exists and finally if the connection index is valid + ARM_COMPUTE_ERROR_ON((source >= _nodes.size()) || (_nodes[source] == nullptr) || (source_idx >= _nodes[source]->num_outputs())); + ARM_COMPUTE_ERROR_ON((sink >= _nodes.size()) || (_nodes[sink] == nullptr) || (sink_idx >= _nodes[sink]->num_inputs())); - if(_current_node->supports_in_place()) - { - _current_output = _current_input; - } + // Get nodes + std::unique_ptr &source_node = _nodes[source]; + std::unique_ptr &sink_node = _nodes[sink]; - //Automatic output configuration ? - if(_current_output == nullptr) + // Check for duplicate connections (Check only sink node) + Edge *sink_node_edge = sink_node->input_edge(sink_idx); + if((sink_node_edge != nullptr) && (sink_node_edge->producer_id() == source) && (sink_node_edge->producer_idx() == source_idx) + && (sink_node_edge->consumer_id() == sink) && (sink_node_edge->consumer_idx() == sink_idx)) { - _tensors.push_back(arm_compute::support::cpp14::make_unique(TensorInfo())); - _current_output = _tensors.back().get(); + return sink_node_edge->id(); } - // If either the writer or reader node needs OpenCL then use OpenCL memory: - if((_next_hints.target_hint() == TargetHint::OPENCL || _current_hints.target_hint() == TargetHint::OPENCL)) + // Check if there is already a tensor associated with output if not create one + TensorID tid = source_node->output_id(source_idx); + if(tid == NullTensorID) { - _current_output->set_target(TargetHint::OPENCL); - } - else - { - _current_output->set_target(TargetHint::NEON); + tid = create_tensor(); } + std::unique_ptr &tensor = _tensors[tid]; + + // Create connections + EdgeID eid = _edges.size(); + auto connection = arm_compute::support::cpp14::make_unique(eid, source_node.get(), source_idx, sink_node.get(), sink_idx, tensor.get()); + _edges.push_back(std::move(connection)); + + // Add connections to source and sink nodes + source_node->_output_edges.insert(eid); + sink_node->_input_edges[sink_idx] = eid; - // Instantiate Node - _ctx.hints() = _current_hints; - std::unique_ptr func = _current_node->instantiate_node(_ctx, _current_input, _current_output); + // Set tensor output node + source_node->_outputs[source_idx] = tid; + + // Bind tensor to the edge + tensor->bind_edge(eid); + + // Try and propagate shapes in sink node + sink_node->forward_descriptors(); + + return eid; +} - // If the operation is done in-place, do not allocate or it will prevent following layers from performing the configuration - if(!_current_node->supports_in_place()) +bool Graph::remove_connection(EdgeID eid) +{ + if(eid >= _edges.size()) { - // Allocate current input - _current_input->allocate(); + return false; } - // Map input if needed - if(_current_input->target() == TargetHint::OPENCL) + std::unique_ptr &edge = _edges[eid]; + + // Remove node connections + if(edge != nullptr) { - if(_previous_hints.target_hint() == TargetHint::NEON) + // Get tensor bound to the edge + if(edge->tensor() != nullptr) + { + edge->tensor()->unbind_edge(eid); + } + + // Remove edges from source node + if(edge->producer() != nullptr) { - ARM_COMPUTE_ERROR_ON(_current_hints.target_hint() == TargetHint::NEON); - _pipeline.push_back({ _current_input, _current_input, arm_compute::support::cpp14::make_unique(_current_input) }); + edge->producer()->_output_edges.erase(eid); } - if(_current_hints.target_hint() == TargetHint::NEON) + + // Remove edges from sink node + if((edge->consumer() != nullptr) && (edge->consumer_idx() < edge->consumer()->_input_edges.size())) { - ARM_COMPUTE_ERROR_ON(_previous_hints.target_hint() == TargetHint::NEON); - _pipeline.push_back({ _current_input, _current_input, arm_compute::support::cpp14::make_unique(_current_input, true) }); + edge->consumer()->_input_edges[edge->consumer_idx()] = EmptyEdgeID; } } - _pipeline.push_back({ _current_input, _current_output, std::move(func) }); + // Clear edge + edge = nullptr; - _current_input = _current_output; - _current_output = nullptr; - std::swap(_previous_hints, _current_hints); - std::swap(_current_hints, _next_hints); + return true; } -void Graph::add_node(std::unique_ptr node) +TensorID Graph::create_tensor(TensorDescriptor desc) { - ARM_COMPUTE_ERROR_ON_MSG(_pimpl->_graph_input == nullptr, "The graph's input must be set before the first node is added"); - ARM_COMPUTE_ERROR_ON_MSG(_pimpl->_graph_output != nullptr, "Nothing can be added after the output tensor"); - //Trigger the creation of the current Node: - - GraphHints _next_hints = _pimpl->_next_hints; - _next_hints.set_target_hint(node->override_target_hint(_pimpl->_next_hints.target_hint())); - ARM_COMPUTE_ERROR_ON(_next_hints.target_hint() == TargetHint::DONT_CARE); - if(_pimpl->_current_node) - { - //Finalize the previous Node: - _pimpl->configure(_pimpl->_next_hints); - } - else - { - // If that's the first node then use the same TargetHint before and after the node. - _pimpl->_current_hints = _next_hints; - } - if(_pimpl->_current_node) - { - _pimpl->_nodes.push_back(std::move(_pimpl->_current_node)); - } - _pimpl->_current_node = std::move(node); + TensorID tid = _tensors.size(); + auto tensor = support::cpp14::make_unique(tid, desc); + _tensors.push_back(std::move(tensor)); + + return tid; } -//Add a tensor with an Accessor (i.e either the input or output of the graph) -void Graph::add_tensor_object(std::unique_ptr tensor) +std::string Graph::name() const { - // If it's the first Tensor added then it will be the input of the Graph. - if(_pimpl->_graph_input == nullptr) - { - ARM_COMPUTE_ERROR_ON(_pimpl->_graph_output != nullptr); - ARM_COMPUTE_ERROR_ON(_pimpl->_current_node != nullptr); - _pimpl->_graph_input = std::move(tensor); - } - else - { - // Else it will be the output of the Graph - ARM_COMPUTE_ERROR_ON(_pimpl->_graph_output != nullptr); - ARM_COMPUTE_ERROR_ON(_pimpl->_current_node == nullptr); - _pimpl->_graph_output = std::move(tensor); - _pimpl->_current_output = _pimpl->_graph_output.get(); - - // Finalize the graph by configuring the last Node of the graph: - _pimpl->configure(_pimpl->_current_hints); // Ignore _next_hint as this is the last node, and just use the same hint as before this node. - _pimpl->_graph_output->allocate(); - } + return _name; } -bool Graph::opencl_is_available() +GraphID Graph::id() const { - return arm_compute::opencl_is_available(); + return _id; } -arm_compute::GPUTarget Graph::gpu_target() +const std::vector &Graph::inputs() { - // Check if OpenCL is available before returning the GPU target - if(opencl_is_available()) - { - return arm_compute::CLScheduler::get().target(); - } - else - { - return GPUTarget::MIDGARD; - } + return _tagged_nodes[NodeType::Input]; +} + +std::vector> &Graph::nodes() +{ + return _nodes; } -void Graph::set_temp(TensorInfo &&tmp) +const std::vector> &Graph::nodes() const { - ARM_COMPUTE_ERROR_ON(_pimpl->_graph_input == nullptr); - ARM_COMPUTE_ERROR_ON(_pimpl->_graph_output != nullptr); - ARM_COMPUTE_ERROR_ON_MSG(_pimpl->_current_output != nullptr, "TensorInfo for temporary tensor already set"); + return _nodes; +} + +const std::vector> &Graph::edges() const +{ + return _edges; +} - _pimpl->_tensors.push_back(arm_compute::support::cpp14::make_unique(std::move(tmp))); - _pimpl->_current_output = _pimpl->_tensors.back().get(); +std::vector> &Graph::tensors() +{ + return _tensors; +} + +const std::vector> &Graph::tensors() const +{ + return _tensors; } -GraphHints &Graph::hints() +const INode *Graph::node(NodeID id) const { - return _pimpl->_next_hints; + return (id >= _nodes.size()) ? nullptr : _nodes[id].get(); } -Graph &arm_compute::graph::operator<<(Graph &graph, TensorInfo &&info) +INode *Graph::node(NodeID id) { - graph.set_temp(std::move(info)); - return graph; + return (id >= _nodes.size()) ? nullptr : _nodes[id].get(); } -Graph &arm_compute::graph::operator<<(Graph &graph, Tensor &&tensor) +const Edge *Graph::edge(EdgeID id) const { - graph.add_tensor_object(arm_compute::support::cpp14::make_unique(std::move(tensor))); - return graph; + return (id >= _edges.size()) ? nullptr : _edges[id].get(); } -Graph &arm_compute::graph::operator<<(Graph &graph, SubTensor &&sub_tensor) +Edge *Graph::edge(EdgeID id) { - graph.add_tensor_object(arm_compute::support::cpp14::make_unique(std::move(sub_tensor))); - return graph; + return (id >= _edges.size()) ? nullptr : _edges[id].get(); } -Graph &arm_compute::graph::operator<<(Graph &graph, TargetHint target_hint) +const Tensor *Graph::tensor(TensorID id) const { - graph.hints().set_target_hint(target_hint); - return graph; + return (id >= _tensors.size()) ? nullptr : _tensors[id].get(); } -Graph &arm_compute::graph::operator<<(Graph &graph, ConvolutionMethodHint conv_method_hint) +Tensor *Graph::tensor(TensorID id) { - graph.hints().set_convolution_method_hint(conv_method_hint); - return graph; + return (id >= _tensors.size()) ? nullptr : _tensors[id].get(); } +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/GraphBuilder.cpp b/src/graph/GraphBuilder.cpp new file mode 100644 index 0000000000..0d1bdc3596 --- /dev/null +++ b/src/graph/GraphBuilder.cpp @@ -0,0 +1,394 @@ +/* + * 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. + */ +#include "arm_compute/graph/GraphBuilder.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Utils.h" +#include "arm_compute/graph/algorithms/BFS.h" +#include "arm_compute/graph/nodes/Nodes.h" + +#define CHECK_NODEIDX_PAIR(pair, g) \ + ARM_COMPUTE_ERROR_ON(((pair).node_id >= (g).nodes().size()) || ((g).node((pair).node_id) == nullptr) || ((pair).index >= (g).node((pair).node_id)->num_outputs())); + +namespace arm_compute +{ +namespace graph +{ +namespace +{ +Status set_node_params(Graph &g, NodeID nid, NodeParams ¶ms) +{ + INode *node = g.node(nid); + ARM_COMPUTE_RETURN_ERROR_ON(!node); + + node->set_common_node_parameters(params); + + return Status{}; +} + +Status set_accessor_on_node(Graph &g, NodeID nid, bool is_output, size_t idx, ITensorAccessorUPtr accessor) +{ + INode *node = g.node(nid); + ARM_COMPUTE_RETURN_ERROR_ON(!node); + + Tensor *tensor = is_output ? node->output(idx) : node->input(idx); + ARM_COMPUTE_RETURN_ERROR_ON(!tensor); + + tensor->set_accessor(std::move(accessor)); + + return Status{}; +} + +NodeID add_const_node_with_name(Graph &g, NodeParams params, const std::string &name, TensorDescriptor desc, ITensorAccessorUPtr accessor) +{ + params.name = params.name.empty() ? "" : params.name + name; + auto nid = GraphBuilder::add_const_node(g, params, desc, std::move(accessor)); + set_node_params(g, nid, params); + return nid; +} + +template +NodeID create_simple_single_input_output_node(Graph &g, NodeParams ¶ms, NodeIdxPair input, Args &&... args) +{ + CHECK_NODEIDX_PAIR(input, g); + + NodeID nid = g.add_node(std::forward(args)...); + g.add_connection(input.node_id, input.index, nid, 0); + set_node_params(g, nid, params); + + return nid; +} + +NodeID create_grouped_convolution(Graph &g, NodeParams ¶ms, NodeIdxPair input, NodeID weights, NodeID bias, + PadStrideInfo conv_info, ConvolutionMethod method, unsigned int num_groups) +{ + bool has_bias = (bias != EmptyNodeID); + + // Split input + NodeID input_split = GraphBuilder::add_split_node(g, params, input, num_groups, 2); + + // Split weights + NodeID weights_split = GraphBuilder::add_split_node(g, params, { weights, 0 }, num_groups, 3); + + // Split bias + NodeID bias_split = EmptyNodeID; + if(has_bias) + { + // Split bias + bias_split = GraphBuilder::add_split_node(g, params, { bias, 0 }, num_groups, 0); + } + + std::vector convolution_outputs; + for(unsigned int i = 0; i < num_groups; ++i) + { + NodeID conv_nid = g.add_node(conv_info, method); + g.add_connection(input_split, i, conv_nid, 0); + g.add_connection(weights_split, i, conv_nid, 1); + if(has_bias) + { + g.add_connection(bias_split, i, conv_nid, 2); + } + set_node_params(g, conv_nid, params); + convolution_outputs.push_back({ conv_nid, 0 }); + } + + // Depth concatenate output + return GraphBuilder::add_depth_concatenate_node(g, params, convolution_outputs); +} +} // namespace + +NodeID GraphBuilder::add_const_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor) +{ + auto nid = g.add_node(desc); + set_node_params(g, nid, params); + set_accessor_on_node(g, nid, true, 0, std::move(accessor)); + return nid; +} + +NodeID GraphBuilder::add_input_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor) +{ + auto nid = g.add_node(desc); + set_node_params(g, nid, params); + set_accessor_on_node(g, nid, true, 0, std::move(accessor)); + return nid; +} + +NodeID GraphBuilder::add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor) +{ + CHECK_NODEIDX_PAIR(input, g); + + NodeID nid = g.add_node(); + g.add_connection(input.node_id, input.index, nid, 0); + set_node_params(g, nid, params); + set_accessor_on_node(g, nid, false, 0, std::move(accessor)); + + return nid; +} + +NodeID GraphBuilder::add_activation_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info) +{ + return create_simple_single_input_output_node(g, params, input, act_info); +} + +NodeID GraphBuilder::add_batch_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, float epsilon, + ITensorAccessorUPtr mean_accessor, ITensorAccessorUPtr var_accessor, + ITensorAccessorUPtr beta_accessor, ITensorAccessorUPtr gamma_accessor) +{ + CHECK_NODEIDX_PAIR(input, g); + + bool has_beta = (beta_accessor != nullptr); + bool has_gamma = (gamma_accessor != nullptr); + + // Get input tensor descriptor + const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); + + // Calculate Common Descriptor + TensorDescriptor common_desc = input_tensor_desc; + common_desc.shape = TensorShape(common_desc.shape.z()); + + // Create mean and nodes + auto mean_nid = add_const_node_with_name(g, params, "Mean", common_desc, std::move(mean_accessor)); + auto var_nid = add_const_node_with_name(g, params, "Variance", common_desc, std::move(var_accessor)); + + // Create beta node + NodeID beta_nid = EmptyNodeID; + if(has_beta) + { + beta_nid = add_const_node_with_name(g, params, "Beta", common_desc, std::move(beta_accessor)); + } + + // Create gamma node + NodeID gamma_nid = EmptyNodeID; + if(has_gamma) + { + gamma_nid = add_const_node_with_name(g, params, "Gamma", common_desc, std::move(gamma_accessor)); + } + + // Create batch normalization node and add connections + NodeID batch_norm_nid = g.add_node(epsilon); + g.add_connection(input.node_id, input.index, batch_norm_nid, 0); + g.add_connection(mean_nid, 0, batch_norm_nid, 1); + g.add_connection(var_nid, 0, batch_norm_nid, 2); + if(has_beta) + { + g.add_connection(beta_nid, 0, batch_norm_nid, 3); + } + if(has_gamma) + { + g.add_connection(gamma_nid, 0, batch_norm_nid, 4); + } + set_node_params(g, batch_norm_nid, params); + + return batch_norm_nid; +} + +NodeID GraphBuilder::add_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, + Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo conv_info, + unsigned int num_groups, ConvolutionMethod method, + ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor) +{ + CHECK_NODEIDX_PAIR(input, g); + ARM_COMPUTE_ERROR_ON(depth == 0); + ARM_COMPUTE_ERROR_ON((kernel_spatial_extend.width == 0) || (kernel_spatial_extend.height == 0)); + + bool has_bias = (bias_accessor != nullptr); + + // Get input tensor descriptor + const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); + + // Create weights node + TensorDescriptor w_desc = input_tensor_desc; + w_desc.shape = TensorShape(kernel_spatial_extend.width, kernel_spatial_extend.height, w_desc.shape.z() / num_groups, depth); + NodeID w_nid = add_const_node_with_name(g, params, "Weights", w_desc, std::move(weights_accessor)); + + // Create bias nodes + NodeID b_nid = EmptyNodeID; + if(has_bias) + { + TensorDescriptor b_desc = input_tensor_desc; + b_desc.shape = TensorShape(depth); + b_nid = add_const_node_with_name(g, params, "Bias", b_desc, std::move(bias_accessor)); + } + + if(num_groups == 1) + { + // Create convolution node and connect + NodeID conv_nid = g.add_node(conv_info, method); + g.add_connection(input.node_id, input.index, conv_nid, 0); + g.add_connection(w_nid, 0, conv_nid, 1); + if(has_bias) + { + g.add_connection(b_nid, 0, conv_nid, 2); + } + set_node_params(g, conv_nid, params); + + return conv_nid; + } + else + { + return create_grouped_convolution(g, params, input, w_nid, b_nid, conv_info, method, num_groups); + } +} + +NodeID GraphBuilder::add_depth_concatenate_node(Graph &g, NodeParams params, std::vector inputs) +{ + ARM_COMPUTE_ERROR_ON(inputs.size() == 0); + + NodeID nid = g.add_node(inputs.size()); + + unsigned int i = 0; + for(const auto &input : inputs) + { + CHECK_NODEIDX_PAIR(input, g); + g.add_connection(input.node_id, input.index, nid, i++); + } + set_node_params(g, nid, params); + + return nid; +} + +NodeID GraphBuilder::add_depthwise_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, Size2D kernel_spatial_extend, PadStrideInfo conv_info, + DepthwiseConvolutionMethod method, + ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor) +{ + CHECK_NODEIDX_PAIR(input, g); + ARM_COMPUTE_ERROR_ON((kernel_spatial_extend.width == 0) || (kernel_spatial_extend.height == 0)); + + bool has_bias = (bias_accessor != nullptr); + + // Get input tensor descriptor + const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); + + // Create weights node + TensorDescriptor w_desc = input_tensor_desc; + w_desc.shape = TensorShape(kernel_spatial_extend.width, kernel_spatial_extend.height, w_desc.shape.z()); + NodeID w_nid = add_const_node_with_name(g, params, "Weights", w_desc, std::move(weights_accessor)); + + // Create bias nodes + NodeID b_nid = EmptyNodeID; + if(has_bias) + { + TensorDescriptor b_desc = input_tensor_desc; + b_desc.shape = TensorShape(b_desc.shape.z()); + b_nid = add_const_node_with_name(g, params, "Bias", b_desc, std::move(bias_accessor)); + } + + // Create convolution node and connect + NodeID conv_nid = g.add_node(conv_info, method); + g.add_connection(input.node_id, input.index, conv_nid, 0); + g.add_connection(w_nid, 0, conv_nid, 1); + if(has_bias) + { + g.add_connection(b_nid, 0, conv_nid, 2); + } + set_node_params(g, conv_nid, params); + + return conv_nid; +} + +NodeID GraphBuilder::add_elementwise_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation) +{ + CHECK_NODEIDX_PAIR(input0, g); + CHECK_NODEIDX_PAIR(input1, g); + + NodeID nid = g.add_node(operation); + + g.add_connection(input0.node_id, input0.index, nid, 0); + g.add_connection(input1.node_id, input1.index, nid, 1); + + set_node_params(g, nid, params); + + return nid; +} + +NodeID GraphBuilder::add_flatten_node(Graph &g, NodeParams params, NodeIdxPair input) +{ + return create_simple_single_input_output_node(g, params, input); +} + +NodeID GraphBuilder::add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, + ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor) +{ + CHECK_NODEIDX_PAIR(input, g); + ARM_COMPUTE_ERROR_ON(num_outputs == 0); + + bool has_bias = (bias_accessor != nullptr); + + // Get input tensor descriptor + const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); + + // Create weights node + TensorDescriptor w_desc = input_tensor_desc; + w_desc.shape = FullyConnectedLayerNode::compute_weights_shape(input_tensor_desc.shape, num_outputs); + NodeID w_nid = add_const_node_with_name(g, params, "Weights", w_desc, std::move(weights_accessor)); + + // Create bias nodes + NodeID b_nid = EmptyNodeID; + if(has_bias) + { + TensorDescriptor b_desc = input_tensor_desc; + b_desc.shape = TensorShape(num_outputs); + b_nid = add_const_node_with_name(g, params, "Bias", b_desc, std::move(bias_accessor)); + } + + // Create convolution node and connect + NodeID fc_nid = g.add_node(num_outputs); + g.add_connection(input.node_id, input.index, fc_nid, 0); + g.add_connection(w_nid, 0, fc_nid, 1); + if(has_bias) + { + g.add_connection(b_nid, 0, fc_nid, 2); + } + + set_node_params(g, fc_nid, params); + + return fc_nid; +} + +NodeID GraphBuilder::add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info) +{ + return create_simple_single_input_output_node(g, params, input, norm_info); +} + +NodeID GraphBuilder::add_pooling_node(Graph &g, NodeParams params, NodeIdxPair input, PoolingLayerInfo pool_info) +{ + return create_simple_single_input_output_node(g, params, input, pool_info); +} + +NodeID GraphBuilder::add_reshape_node(Graph &g, NodeParams params, NodeIdxPair input, TensorShape shape) +{ + return create_simple_single_input_output_node(g, params, input, shape); +} + +NodeID GraphBuilder::add_softmax_node(Graph &g, NodeParams params, NodeIdxPair input, float beta) +{ + return create_simple_single_input_output_node(g, params, input, beta); +} + +NodeID GraphBuilder::add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis) +{ + return create_simple_single_input_output_node(g, params, input, num_splits, axis); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/GraphContext.cpp b/src/graph/GraphContext.cpp index bfc6fcdfca..6fc45c0aa7 100644 --- a/src/graph/GraphContext.cpp +++ b/src/graph/GraphContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -22,45 +22,53 @@ * SOFTWARE. */ #include "arm_compute/graph/GraphContext.h" +#include -using namespace arm_compute::graph; - -GraphHints::GraphHints(TargetHint target_hint, ConvolutionMethodHint conv_method_hint) - : _target_hint(target_hint), _convolution_method_hint(conv_method_hint) +namespace arm_compute { -} - -void GraphHints::set_target_hint(TargetHint target_hint) +namespace graph { - _target_hint = target_hint; -} - -void GraphHints::set_convolution_method_hint(ConvolutionMethodHint convolution_method) +GraphContext::GraphContext() + : _config(), _memory_managers() { - _convolution_method_hint = convolution_method; } -TargetHint GraphHints::target_hint() const +const GraphConfig &GraphContext::config() const { - return _target_hint; + return _config; } -ConvolutionMethodHint GraphHints::convolution_method_hint() const +void GraphContext::set_config(const GraphConfig &config) { - return _convolution_method_hint; + _config = config; } -GraphContext::GraphContext() - : _hints() +bool GraphContext::insert_memory_management_ctx(MemoryManagerContext &&memory_ctx) { + Target target = memory_ctx.target; + if(target == Target::UNSPECIFIED || _memory_managers.find(target) != std::end(_memory_managers)) + { + return false; + } + + _memory_managers[target] = std::move(memory_ctx); + return true; } -GraphHints &GraphContext::hints() +MemoryManagerContext *GraphContext::memory_management_ctx(Target target) { - return _hints; + return (_memory_managers.find(target) != std::end(_memory_managers)) ? &_memory_managers[target] : nullptr; } -const GraphHints &GraphContext::hints() const +void GraphContext::finalize() { - return _hints; -} \ No newline at end of file + for(auto &mm_obj : _memory_managers) + { + if(mm_obj.second.mm != nullptr) + { + mm_obj.second.mm->finalize(); + } + } +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/GraphManager.cpp b/src/graph/GraphManager.cpp new file mode 100644 index 0000000000..759300e0c9 --- /dev/null +++ b/src/graph/GraphManager.cpp @@ -0,0 +1,117 @@ +/* + * 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. + */ +#include "arm_compute/graph/GraphManager.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/PassManager.h" +#include "arm_compute/graph/Utils.h" +#include "arm_compute/graph/detail/ExecutionHelpers.h" + +namespace arm_compute +{ +namespace graph +{ +GraphManager::GraphManager() + : _workloads() +{ + detail::default_initialize_backends(); +} + +void GraphManager::finalize_graph(Graph &graph, GraphContext &ctx, PassManager &pm, Target target) +{ + // Setup graph context if not done manually + setup_default_graph_context(ctx); + + // Check if graph has been registered + ARM_COMPUTE_ERROR_ON_MSG(_workloads.find(graph.id()) != std::end(_workloads), "Graph is already registered!"); + + // Force target to all graph construct + // TODO (geopin01) : Support heterogeneous execution + Target forced_target = is_target_supported(target) ? target : get_default_target(); + force_target_to_graph(graph, forced_target); + + // Configure all tensors + detail::configure_all_tensors(graph); + + // Apply all mutating passes + pm.run_all(graph); + + // TODO (geopin01): Perform a graph validation + + // Perform topological sort + // FIXME : Sort nodes and pass sorted indices in configure all nodes + + // Validate all nodes + detail::validate_all_nodes(graph); + + // Configure all nodes + auto workload = detail::configure_all_nodes(graph, ctx); + ARM_COMPUTE_ERROR_ON_MSG(workload.tasks.empty(), "Could not configure all nodes!"); + + // Allocate all tensors + detail::allocate_all_tensors(graph); + + // Call accessors on all Const nodes + detail::call_all_const_node_accessors(graph); + + _workloads.insert(std::make_pair(graph.id(), std::move(workload))); + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Created workload for graph with ID : " << graph.id().get() << std::endl); + + // Finalize Graph context + ctx.finalize(); + + // Make first run + execute_graph(graph); + + // Release all unused const nodes + detail::release_unused_tensors(graph); +} + +void GraphManager::execute_graph(Graph &graph) +{ + // Check if graph is finalized + auto it = _workloads.find(graph.id()); + ARM_COMPUTE_ERROR_ON_MSG(it == std::end(_workloads), "Graph is not registered!"); + + // Call input accessors + detail::call_all_input_node_accessors(it->second); + + // Run graph + detail::call_all_tasks(it->second); + + // Call output accessors + detail::call_all_output_node_accessors(it->second); +} + +void GraphManager::invalidate_graph(Graph &graph) +{ + auto it = _workloads.find(graph.id()); + ARM_COMPUTE_ERROR_ON_MSG(it == std::end(_workloads), "Graph is not registered!"); + + _workloads.erase(it); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/INode.cpp b/src/graph/INode.cpp index c753f66b43..c1c18e5853 100644 --- a/src/graph/INode.cpp +++ b/src/graph/INode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -23,33 +23,171 @@ */ #include "arm_compute/graph/INode.h" -#include "arm_compute/core/CL/OpenCL.h" -#include "arm_compute/core/Validate.h" +#include "arm_compute/core/Error.h" +#include "arm_compute/graph/Edge.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Tensor.h" -using namespace arm_compute::graph; +namespace arm_compute +{ +namespace graph +{ +// *INDENT-OFF* +// clang-format off +INode::INode() + : _graph(nullptr), _id(EmptyNodeID), _common_params({ "", Target::UNSPECIFIED}), + _outputs(), _input_edges(), _output_edges(), _assigned_target(Target::UNSPECIFIED) +{ +} +// clang-format on +// *INDENT-ON* -TargetHint INode::override_target_hint(TargetHint target_hint) const +void INode::set_graph(Graph *g) { - if(target_hint == TargetHint::OPENCL && !opencl_is_available()) + ARM_COMPUTE_ERROR_ON(g == nullptr); + _graph = g; +} + +void INode::set_id(NodeID id) +{ + _id = id; +} + +void INode::set_common_node_parameters(NodeParams common_params) +{ + _common_params = std::move(common_params); +} + +void INode::set_requested_target(Target target) +{ + _common_params.target = target; +} + +void INode::set_assigned_target(Target target) +{ + _assigned_target = target; +} + +void INode::set_output_tensor(TensorID tid, size_t idx) +{ + if(tid != NullTensorID && (idx < _outputs.size()) && (_graph->tensor(tid) != nullptr)) { - target_hint = TargetHint::DONT_CARE; + ARM_COMPUTE_ERROR_ON(_graph == nullptr); + Tensor *updated_tensor = _graph->tensor(tid); + _outputs[idx] = tid; + + // Set tensor to all output edges of the node + for(auto &output_edge_id : _output_edges) + { + auto output_edge = _graph->edge(output_edge_id); + if(output_edge != nullptr) + { + // Unbind edge from current tensor + auto current_output_tensor = output_edge->tensor(); + current_output_tensor->unbind_edge(output_edge->id()); + + // Update tensor to edge and rebind tensor + output_edge->update_bound_tensor(updated_tensor); + updated_tensor->bind_edge(output_edge->id()); + } + } } - GraphHints hints{ target_hint }; - target_hint = node_override_hints(hints).target_hint(); - ARM_COMPUTE_ERROR_ON(target_hint == TargetHint::OPENCL && !opencl_is_available()); - return target_hint; } -bool INode::supports_in_place() const + +NodeID INode::id() const +{ + return _id; +} + +std::string INode::name() const +{ + return _common_params.name; +} + +const Graph *INode::graph() const +{ + return _graph; +} + +Graph *INode::graph() +{ + return _graph; +} + +const std::vector &INode::outputs() const { - return _supports_in_place; + return _outputs; } -void INode::set_supports_in_place(bool value) + +const std::vector &INode::input_edges() const +{ + return _input_edges; +} + +const std::set &INode::output_edges() const +{ + return _output_edges; +} + +TensorID INode::input_id(size_t idx) const +{ + ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); + Edge *e = _graph->edge(_input_edges[idx]); + return (e != nullptr) ? e->tensor_id() : NullTensorID; +} + +TensorID INode::output_id(size_t idx) const +{ + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + return _outputs[idx]; +} + +Tensor *INode::input(size_t idx) const +{ + ARM_COMPUTE_ERROR_ON(_graph == nullptr); + ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); + Edge *e = _graph->edge(_input_edges[idx]); + return (e != nullptr) ? e->tensor() : nullptr; +} + +Tensor *INode::output(size_t idx) const { - _supports_in_place = value; + ARM_COMPUTE_ERROR_ON(_graph == nullptr); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + return _graph->tensor(_outputs[idx]); } -GraphHints INode::node_override_hints(GraphHints hints) const + +EdgeID INode::input_edge_id(size_t idx) const +{ + ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); + return _input_edges[idx]; +} + +Edge *INode::input_edge(size_t idx) const +{ + ARM_COMPUTE_ERROR_ON(_graph == nullptr); + ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); + return _graph->edge(_input_edges[idx]); +} + +size_t INode::num_inputs() const +{ + return _input_edges.size(); +} + +size_t INode::num_outputs() const +{ + return _outputs.size(); +} + +Target INode::requested_target() const +{ + return _common_params.target; +} + +Target INode::assigned_target() const { - TargetHint target_hint = hints.target_hint(); - hints.set_target_hint((target_hint == TargetHint::DONT_CARE) ? TargetHint::NEON : target_hint); - return hints; + return _assigned_target; } +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/NodeContext.cpp b/src/graph/NodeContext.cpp deleted file mode 100644 index 2aa5aa13e8..0000000000 --- a/src/graph/NodeContext.cpp +++ /dev/null @@ -1,75 +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. - */ -#include "arm_compute/graph/NodeContext.h" - -using namespace arm_compute::graph; - -void NodeContext::set_target(TargetHint target) -{ - _target = target; -} - -void NodeContext::add_input(arm_compute::ITensor *input) -{ - ARM_COMPUTE_ERROR_ON(input == nullptr); - _inputs.emplace_back(input); -} - -void NodeContext::add_output(arm_compute::ITensor *output) -{ - ARM_COMPUTE_ERROR_ON(output == nullptr); - _outputs.emplace_back(output); -} - -OperationType NodeContext::operation() const -{ - return _operation; -} - -TargetHint NodeContext::target() const -{ - return _target; -} - -arm_compute::ITensor *NodeContext::input(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(idx >= _inputs.size()); - return _inputs[idx]; -} - -arm_compute::ITensor *NodeContext::output(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - return _outputs[idx]; -} - -size_t NodeContext::num_inputs() const -{ - return _inputs.size(); -} - -size_t NodeContext::num_outputs() const -{ - return _outputs.size(); -} \ No newline at end of file diff --git a/src/graph/OperationRegistry.cpp b/src/graph/OperationRegistry.cpp deleted file mode 100644 index 651653f19c..0000000000 --- a/src/graph/OperationRegistry.cpp +++ /dev/null @@ -1,61 +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. - */ -#include "arm_compute/graph/OperationRegistry.h" - -using namespace arm_compute::graph; - -OperationRegistry::OperationRegistry() - : _registered_ops() -{ -} - -OperationRegistry &OperationRegistry::get() -{ - static OperationRegistry instance; - return instance; -} - -IOperation *OperationRegistry::find_operation(OperationType operation, TargetHint target) -{ - ARM_COMPUTE_ERROR_ON(!contains(operation, target)); - auto it = std::find_if(_registered_ops[operation].begin(), _registered_ops[operation].end(), [&](const std::unique_ptr &op) - { - return (op->target() == target); - }); - ARM_COMPUTE_ERROR_ON(it == _registered_ops[operation].end()); - return (*it).get(); -} - -bool OperationRegistry::contains(OperationType operation, TargetHint target) const -{ - auto it = _registered_ops.find(operation); - if(it != _registered_ops.end()) - { - return std::any_of(it->second.begin(), it->second.end(), [&](const std::unique_ptr &op) - { - return (op->target() == target); - }); - } - return false; -} diff --git a/src/graph/PassManager.cpp b/src/graph/PassManager.cpp new file mode 100644 index 0000000000..8ed68bd99b --- /dev/null +++ b/src/graph/PassManager.cpp @@ -0,0 +1,88 @@ +/* + * 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. + */ +#include "arm_compute/graph/PassManager.h" + +#include "arm_compute/graph/Logger.h" + +namespace arm_compute +{ +namespace graph +{ +PassManager::PassManager() + : _passes() +{ +} + +const std::vector> &PassManager::passes() const +{ + return _passes; +} + +IGraphMutator *PassManager::pass(size_t index) +{ + return (index >= _passes.size()) ? nullptr : _passes.at(index).get(); +} + +void PassManager::append(std::unique_ptr pass) +{ + if(pass) + { + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Appending mutating pass : " << pass->name() << std::endl); + _passes.push_back(std::move(pass)); + } +} + +void PassManager::clear() +{ + _passes.clear(); +} + +void PassManager::run_all(Graph &g) +{ + for(auto &pass : _passes) + { + if(pass) + { + ARM_COMPUTE_LOG_GRAPH_INFO("Running mutating pass : " << pass->name() << std::endl); + pass->mutate(g); + } + } +} + +void PassManager::run(Graph &g, size_t index) +{ + if(index >= _passes.size()) + { + return; + } + + auto &pass = _passes.at(index); + + if(pass != nullptr) + { + pass->mutate(g); + } +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/SubGraph.cpp b/src/graph/SubGraph.cpp deleted file mode 100644 index b1cbb9cc95..0000000000 --- a/src/graph/SubGraph.cpp +++ /dev/null @@ -1,110 +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. - */ -#include "arm_compute/graph/SubGraph.h" - -#include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/INode.h" -#include "arm_compute/graph/Tensor.h" - -using namespace arm_compute::graph; - -SubGraph::SubGraph() - : _nodes(), _input(nullptr), _output(nullptr) -{ -} - -void SubGraph::add_node(std::unique_ptr node) -{ - _nodes.push_back(std::move(node)); -} - -void SubGraph::add_tensor_object(std::unique_ptr tensor) -{ - // If it's the first Tensor added then it will be the input of the Graph. - if(_input == nullptr) - { - _input = std::move(tensor); - } - else - { - _output = std::move(tensor); - } -} - -std::unique_ptr SubGraph::construct(const GraphContext &ctx, std::unique_ptr input, std::unique_ptr output) -{ - auto graph = arm_compute::support::cpp14::make_unique(); - - // Set hint - // TODO(geopin01): store hints of sub-graph - graph->hints() = ctx.hints(); - - // Configure input - if(_input == nullptr) - { - _input = std::move(input); - } - graph->add_tensor_object(std::move(_input)); - - // Make sure first and last nodes of the subgraph always do operations out-of-place - _nodes.front()->set_supports_in_place(false); - _nodes.back()->set_supports_in_place(false); - - // Construct nodes - for(auto &node : _nodes) - { - graph->add_node(std::move(node)); - } - - // Configure output - if(_output == nullptr) - { - _output = std::move(output); - } - graph->add_tensor_object(std::move(_output)); - - return graph; -} - -bool SubGraph::has_input() const -{ - return _input != nullptr; -} - -bool SubGraph::has_output() const -{ - return _output != nullptr; -} - -SubGraph &arm_compute::graph::operator<<(SubGraph &graph, Tensor &&tensor) -{ - graph.add_tensor_object(arm_compute::support::cpp14::make_unique(std::move(tensor))); - return graph; -} - -SubGraph &arm_compute::graph::operator<<(SubGraph &graph, SubTensor &&sub_tensor) -{ - graph.add_tensor_object(arm_compute::support::cpp14::make_unique(std::move(sub_tensor))); - return graph; -} diff --git a/src/graph/SubTensor.cpp b/src/graph/SubTensor.cpp deleted file mode 100644 index 2e640dd93c..0000000000 --- a/src/graph/SubTensor.cpp +++ /dev/null @@ -1,119 +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. - */ -#include "arm_compute/graph/SubTensor.h" - -#include "arm_compute/core/Error.h" -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Validate.h" -#include "arm_compute/runtime/CL/CLSubTensor.h" -#include "arm_compute/runtime/CL/CLTensor.h" -#include "arm_compute/runtime/SubTensor.h" -#include "arm_compute/runtime/Tensor.h" -#include "utils/TypePrinter.h" - -using namespace arm_compute::graph; - -namespace -{ -template -std::unique_ptr initialise_subtensor(arm_compute::ITensor *parent, TensorShape shape, Coordinates coords, bool extend_parent) -{ - auto ptensor = dynamic_cast(parent); - auto subtensor = arm_compute::support::cpp14::make_unique(ptensor, shape, coords, extend_parent); - return std::move(subtensor); -} -} // namespace - -SubTensor::SubTensor() - : _target(TargetHint::DONT_CARE), _tensor_shape(), _coords(), _parent(nullptr), _subtensor(nullptr), _extend_parent(false) -{ -} - -SubTensor::SubTensor(Tensor &parent, TensorShape tensor_shape, Coordinates coords, bool extend_parent) - : _target(TargetHint::DONT_CARE), _tensor_shape(tensor_shape), _coords(coords), _parent(nullptr), _subtensor(nullptr), _extend_parent(extend_parent) -{ - ARM_COMPUTE_ERROR_ON(parent.tensor() == nullptr); - _parent = parent.tensor(); - _target = parent.target(); - - instantiate_subtensor(); -} - -SubTensor::SubTensor(arm_compute::ITensor *parent, TensorShape tensor_shape, Coordinates coords, TargetHint target, bool extend_parent) - : _target(target), _tensor_shape(tensor_shape), _coords(coords), _parent(parent), _subtensor(nullptr), _extend_parent(extend_parent) -{ - ARM_COMPUTE_ERROR_ON(parent == nullptr); - instantiate_subtensor(); -} - -bool SubTensor::call_accessor() -{ - return true; -} - -bool SubTensor::has_accessor() const -{ - return false; -} - -arm_compute::ITensor *SubTensor::set_target(TargetHint target) -{ - ARM_COMPUTE_ERROR_ON(target != _target); - return (target == _target) ? _subtensor.get() : nullptr; -} - -arm_compute::ITensor *SubTensor::tensor() -{ - return _subtensor.get(); -} - -const arm_compute::ITensor *SubTensor::tensor() const -{ - return _subtensor.get(); -} - -TargetHint SubTensor::target() const -{ - return _target; -} - -void SubTensor::allocate() -{ - // NOP for sub-tensors -} - -void SubTensor::instantiate_subtensor() -{ - switch(_target) - { - case TargetHint::OPENCL: - _subtensor = initialise_subtensor(_parent, _tensor_shape, _coords, _extend_parent); - break; - case TargetHint::NEON: - _subtensor = initialise_subtensor(_parent, _tensor_shape, _coords, _extend_parent); - break; - default: - ARM_COMPUTE_ERROR("Invalid TargetHint"); - } -} diff --git a/src/graph/Tensor.cpp b/src/graph/Tensor.cpp index 4db79e93ad..47fb5c65bc 100644 --- a/src/graph/Tensor.cpp +++ b/src/graph/Tensor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -23,138 +23,89 @@ */ #include "arm_compute/graph/Tensor.h" -#include "arm_compute/core/Error.h" -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Validate.h" -#include "arm_compute/runtime/CL/CLTensor.h" -#include "arm_compute/runtime/Tensor.h" -#include "utils/TypePrinter.h" - -using namespace arm_compute::graph; - -namespace +namespace arm_compute { -template -std::unique_ptr initialise_tensor(TensorInfo &info) +namespace graph { - auto tensor = arm_compute::support::cpp14::make_unique(); - tensor->allocator()->init(info); - return std::move(tensor); -} - -template -void tensor_allocate(arm_compute::ITensor &tensor) +Tensor::Tensor(TensorID id, TensorDescriptor desc) + : _id(id), _desc(desc), _handle(nullptr), _accessor(nullptr), _bound_edges() { - auto itensor = dynamic_cast(&tensor); - ARM_COMPUTE_ERROR_ON_NULLPTR(itensor); - itensor->allocator()->allocate(); } -} // namespace -Tensor::Tensor(TensorInfo &&info) - : _target(TargetHint::DONT_CARE), _info(info), _accessor(nullptr), _tensor(nullptr) +TensorID Tensor::id() const { + return _id; } -Tensor::Tensor(Tensor &&src) noexcept - : _target(src._target), - _info(std::move(src._info)), - _accessor(std::move(src._accessor)), - _tensor(std::move(src._tensor)) +TensorDescriptor &Tensor::desc() { + return _desc; } -void Tensor::set_info(TensorInfo &&info) +const TensorDescriptor &Tensor::desc() const { - _info = info; -} - -bool Tensor::call_accessor() -{ - ARM_COMPUTE_ERROR_ON_NULLPTR(_accessor.get()); - auto cl_tensor = dynamic_cast(_tensor.get()); - if(cl_tensor != nullptr && cl_tensor->buffer() == nullptr) - { - cl_tensor->map(); - } - bool retval = _accessor->access_tensor(*_tensor); - if(cl_tensor != nullptr) - { - cl_tensor->unmap(); - } - return retval; + return _desc; } -bool Tensor::has_accessor() const +void Tensor::set_handle(std::unique_ptr backend_tensor) { - return (_accessor != nullptr); + _handle = std::move(backend_tensor); } -arm_compute::ITensor *Tensor::tensor() +ITensorHandle *Tensor::handle() { - return _tensor.get(); + return _handle.get(); } -const arm_compute::ITensor *Tensor::tensor() const +void Tensor::set_accessor(std::unique_ptr accessor) { - return _tensor.get(); + _accessor = std::move(accessor); } -const TensorInfo &Tensor::info() const +ITensorAccessor *Tensor::accessor() { - return _info; + return _accessor.get(); } -arm_compute::ITensor *Tensor::set_target(TargetHint target) +bool Tensor::call_accessor() { - if(_tensor != nullptr) + // Early exit guard + if(!_accessor || !_handle) { - ARM_COMPUTE_ERROR_ON(target != _target); + return false; } - else + + // Map tensor + _handle->map(true); + + // Return in case of null backend buffer + if(_handle->tensor().buffer() == nullptr) { - switch(target) - { - case TargetHint::OPENCL: - _tensor = initialise_tensor(_info); - break; - case TargetHint::NEON: - _tensor = initialise_tensor(_info); - break; - default: - ARM_COMPUTE_ERROR("Invalid TargetHint"); - } - _target = target; + return false; } - return _tensor.get(); + + // Call accessor + _accessor->access_tensor(_handle->tensor()); + + // Unmap tensor + _handle->unmap(); + + return true; } -void Tensor::allocate() +void Tensor::bind_edge(EdgeID eid) { - ARM_COMPUTE_ERROR_ON_NULLPTR(_tensor.get()); - switch(_target) - { - case TargetHint::OPENCL: - tensor_allocate(*_tensor); - break; - case TargetHint::NEON: - tensor_allocate(*_tensor); - break; - default: - ARM_COMPUTE_ERROR("Invalid TargetHint"); - } + _bound_edges.insert(eid); } -void Tensor::allocate_and_fill_if_needed() +void Tensor::unbind_edge(EdgeID eid) { - allocate(); - if(_accessor != nullptr) - { - call_accessor(); - } + _bound_edges.erase(eid); } -TargetHint Tensor::target() const +const std::set Tensor::bound_edges() const { - return _target; + return _bound_edges; } +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/Utils.cpp b/src/graph/Utils.cpp new file mode 100644 index 0000000000..8537bbfb2a --- /dev/null +++ b/src/graph/Utils.cpp @@ -0,0 +1,104 @@ +/* + * 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. + */ +#include "arm_compute/graph/Utils.h" + +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/backends/BackendRegistry.h" +#include "arm_compute/graph/mutators/GraphMutators.h" + +namespace arm_compute +{ +namespace graph +{ +bool is_target_supported(Target target) +{ + return backends::BackendRegistry::get().contains(target) && backends::BackendRegistry::get().find_backend(target)->is_backend_supported(); +} + +Target get_default_target() +{ + if(is_target_supported(Target::NEON)) + { + return Target::NEON; + } + if(is_target_supported(Target::CL)) + { + return Target::CL; + } + if(is_target_supported(Target::GC)) + { + return Target::GC; + } + ARM_COMPUTE_ERROR("No backend exists!"); +} + +void force_target_to_graph(Graph &g, Target target) +{ + auto &nodes = g.nodes(); + for(auto &node : nodes) + { + if(node) + { + node->set_assigned_target(target); + } + } + + auto &tensors = g.tensors(); + for(auto &tensor : tensors) + { + if(tensor) + { + tensor->desc().target = target; + } + } +} + +PassManager create_default_pass_manager(Target target) +{ + PassManager pm; + + if(target != Target::GC) + { + pm.append(support::cpp14::make_unique()); + pm.append(support::cpp14::make_unique()); + pm.append(support::cpp14::make_unique()); + pm.append(support::cpp14::make_unique()); + } + + return pm; +} + +/** Default setups a graph Context + * + * @param[in] ctx Context to default initialize + */ +void setup_default_graph_context(GraphContext &ctx) +{ + for(const auto &backend : backends::BackendRegistry::get().backends()) + { + backend.second->setup_backend_context(ctx); + } +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/Workload.cpp b/src/graph/Workload.cpp new file mode 100644 index 0000000000..c53a8a42da --- /dev/null +++ b/src/graph/Workload.cpp @@ -0,0 +1,41 @@ +/* + * 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. + */ +#include "arm_compute/graph/Workload.h" + +#include "arm_compute/graph/INode.h" +#include "arm_compute/graph/ITensorHandle.h" + +namespace arm_compute +{ +namespace graph +{ +void ExecutionTask::operator()() +{ + if(task) + { + task->run(); + } +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/BackendRegistry.cpp b/src/graph/backends/BackendRegistry.cpp new file mode 100644 index 0000000000..2803322e64 --- /dev/null +++ b/src/graph/backends/BackendRegistry.cpp @@ -0,0 +1,63 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/BackendRegistry.h" + +using namespace arm_compute::graph::backends; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +BackendRegistry::BackendRegistry() + : _registered_backends() +{ +} + +BackendRegistry &BackendRegistry::get() +{ + static BackendRegistry instance; + return instance; +} + +IDeviceBackend *BackendRegistry::find_backend(Target target) +{ + ARM_COMPUTE_ERROR_ON(!contains(target)); + return _registered_backends[target].get(); +} + +bool BackendRegistry::contains(Target target) const +{ + auto it = _registered_backends.find(target); + return (it != _registered_backends.end()); +} + +const std::map> &BackendRegistry::backends() const +{ + return _registered_backends; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/backends/CL/CLDeviceBackend.cpp b/src/graph/backends/CL/CLDeviceBackend.cpp new file mode 100644 index 0000000000..f10eb33a98 --- /dev/null +++ b/src/graph/backends/CL/CLDeviceBackend.cpp @@ -0,0 +1,180 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/CL/CLDeviceBackend.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/INode.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/backends/BackendRegistrar.h" +#include "arm_compute/graph/backends/CL/CLFunctionFactory.h" +#include "arm_compute/graph/backends/CL/CLNodeValidator.h" +#include "arm_compute/graph/backends/CL/CLSubTensorHandle.h" +#include "arm_compute/graph/backends/CL/CLTensorHandle.h" + +#include "arm_compute/core/TensorInfo.h" +#include "arm_compute/runtime/BlobLifetimeManager.h" +#include "arm_compute/runtime/CL/CLBufferAllocator.h" +#include "arm_compute/runtime/CL/CLScheduler.h" +#include "arm_compute/runtime/MemoryManagerOnDemand.h" +#include "arm_compute/runtime/PoolManager.h" + +#include "support/ToolchainSupport.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace +{ +bool file_exists(const std::string &filename) +{ + std::ifstream file(filename); + return file.good(); +} +} // namespace + +/** Register CL backend */ +static detail::BackendRegistrar CLDeviceBackend_registrar(Target::CL); + +/** Tuner export file */ +static const std::string tuner_data_filename = "acl_tuner.csv"; + +CLDeviceBackend::CLDeviceBackend() + : _tuner(), _allocator(cl::Context::getDefault()) +{ +} + +CLDeviceBackend::~CLDeviceBackend() +{ + // TODO (geopin01) : Shouldn't call non exception safe stuff here + if(_tuner.tune_new_kernels() && !_tuner.lws_table().empty()) + { + _tuner.save_to_file(tuner_data_filename); + } +} + +void CLDeviceBackend::set_kernel_tuning(bool enable_tuning) +{ + _tuner.set_tune_new_kernels(enable_tuning); +} + +void CLDeviceBackend::initialize_backend() +{ + // Load tuner data if available + if(_tuner.lws_table().empty() && file_exists(tuner_data_filename)) + { + _tuner.load_from_file(tuner_data_filename); + } + + // Setup Scheduler + CLScheduler::get().default_init(&_tuner); + + // Create allocator with new context + _allocator = CLBufferAllocator(); +} + +void CLDeviceBackend::setup_backend_context(GraphContext &ctx) +{ + // Setup tuner + set_kernel_tuning(ctx.config().use_tuner); + + // Setup a management backend + if(ctx.memory_management_ctx(Target::CL) == nullptr) + { + MemoryManagerContext mm_ctx; + mm_ctx.target = Target::CL; + mm_ctx.mm = create_memory_manager(MemoryManagerAffinity::Buffer); + + ctx.insert_memory_management_ctx(std::move(mm_ctx)); + } +} + +bool CLDeviceBackend::is_backend_supported() +{ + return arm_compute::opencl_is_available(); +} + +std::unique_ptr CLDeviceBackend::create_tensor(const Tensor &tensor) +{ + // Get tensor descriptor + const TensorDescriptor &tensor_desc = tensor.desc(); + ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::CL); + + // Create backend tensor handle + TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type); + auto backend_tensor_handle = support::cpp14::make_unique(info); + + return std::move(backend_tensor_handle); +} + +std::unique_ptr CLDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) +{ + if(parent == nullptr) + { + return nullptr; + } + + return support::cpp14::make_unique(parent, shape, coords, extend_parent); +} + +std::unique_ptr CLDeviceBackend::configure_node(INode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring CL node with ID : " << node.id() << std::endl); + ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::CL); + + // Configure node + return CLFunctionFactory::create(&node, ctx); +} + +arm_compute::Status CLDeviceBackend::validate_node(INode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating CL node with ID : " << node.id() << std::endl); + ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::CL); + + return CLNodeValidator::validate(&node); +} + +std::shared_ptr CLDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity) +{ + if(affinity == MemoryManagerAffinity::Offset) + { + ARM_COMPUTE_LOG_GRAPH_WARNING("CL Backend does not support offset affinity memory management!"); + return nullptr; + } + + auto lifetime_mgr = std::make_shared(); + auto pool_mgr = std::make_shared(); + auto mm = std::make_shared(lifetime_mgr, pool_mgr); + + mm->set_allocator(&_allocator); + + return mm; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/CL/CLFunctionsFactory.cpp b/src/graph/backends/CL/CLFunctionsFactory.cpp new file mode 100644 index 0000000000..1b448fefd2 --- /dev/null +++ b/src/graph/backends/CL/CLFunctionsFactory.cpp @@ -0,0 +1,590 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/CL/CLFunctionFactory.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/TypePrinter.h" +#include "arm_compute/graph/Types.h" +#include "arm_compute/graph/backends/Utils.h" +#include "arm_compute/graph/nodes/Nodes.h" +#include "arm_compute/runtime/CL/CLFunctions.h" + +#include "support/ToolchainSupport.h" + +using namespace arm_compute::utils::cast; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace +{ +/** Returns backing tensor of a given tensor + * + * @param[in] tensor Tensor to extract the backing tensor from + * + * @return Backing tensor if present else nullptr + */ +arm_compute::ICLTensor *get_backing_tensor(arm_compute::graph::Tensor *tensor) +{ + arm_compute::ICLTensor *backing_tensor = nullptr; + if(tensor != nullptr) + { + ARM_COMPUTE_ERROR_ON(tensor->desc().target != arm_compute::graph::Target::CL); + // Get backing tensor handle + ITensorHandle *tensor_handle = tensor->handle(); + // Get backing tensor + backing_tensor = (tensor_handle != nullptr) ? polymorphic_cast(&tensor_handle->tensor()) : nullptr; + } + + return backing_tensor; +} + +/** Create a backend activation layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend activation layer function + */ +std::unique_ptr create_activation_layer(ActivationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL ActivationLayerNode node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const ActivationLayerInfo act_info = node.activation_info(); + + // Create function + auto func = support::cpp14::make_unique(); + func->configure(input, output, act_info); + + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLActivationLayer" + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Activation function: " << act_info.activation() + << " a: " << act_info.a() + << " b: " << act_info.b() + << " InPlace : " << is_in_place_operation(input, output) + << std::endl); + + return std::move(func); +} + +/** Create a backend batch normalization layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend batch normalization layer function + */ +std::unique_ptr create_batch_normalization_layer(BatchNormalizationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating CL BatchNormalization node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + + // TODO (geopin01) : Var and mean are compulsory, switch function to accept nullptr as beta and/or gamma + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 5); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *mean = get_backing_tensor(node.input(1)); + ICLTensor *var = get_backing_tensor(node.input(2)); + ICLTensor *beta = get_backing_tensor(node.input(3)); + ICLTensor *gamma = get_backing_tensor(node.input(4)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const float epsilon = node.epsilon(); + const ActivationLayerInfo fused_act = node.fused_activation(); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLBatchNormalizationLayer" + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Epsilon: " << epsilon << " " + << (fused_act.enabled() ? to_string(fused_act.activation()) : "") + << " InPlace : " << is_in_place_operation(input, output) + << std::endl); + + return std::move(func); +} + +/** Create a backend convolution layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend convolution layer function + */ +std::unique_ptr create_convolution_layer(ConvolutionLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating CL ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *weights = get_backing_tensor(node.input(1)); + ICLTensor *biases = get_backing_tensor(node.input(2)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const ConvolutionMethod conv_algorithm = node.convolution_method(); + + // Create and configure function (we assume that functions have been validated before creation) + std::shared_ptr mm = get_memory_manager(ctx, Target::CL); + std::unique_ptr func; + std::string func_name; + + if(conv_algorithm == ConvolutionMethod::WINOGRAD) + { + std::tie(func, func_name) = create_named_function( + std::string("CLWinogradConvolutionLayer"), input, weights, biases, output, conv_info); + } + else if(conv_algorithm == ConvolutionMethod::DIRECT) + { + std::tie(func, func_name) = create_named_function( + std::string("CLDirectConvolutionLayer"), input, weights, biases, output, conv_info); + } + else if(conv_algorithm == ConvolutionMethod::GEMM) + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("CLGEMMConvolutionLayer"), mm, + input, weights, biases, output, conv_info); + } + else + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("CLConvolutionLayer"), mm, + input, weights, biases, output, conv_info); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + return func; +} + +/** Create a backend layer depth concatenate function + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth concatenate layer function + */ +std::unique_ptr create_depth_concatenate_layer(DepthConcatenateLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating CL DepthConcatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Return nullptr if depth concatenate is switched off + if(!node.is_enabled()) + { + return nullptr; + } + + // Extract IO and info + std::vector inputs; + for(unsigned int i = 0; i < node.num_inputs(); ++i) + { + inputs.push_back(get_backing_tensor(node.input(i))); + } + ICLTensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(inputs, output); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLDepthConcatenateLayer" + << " Data Type: " << output->info()->data_type() + << " Shape: " << output->info()->tensor_shape() + << " Num Inputs: " << inputs.size() + << std::endl); + + return std::move(func); +} + +/** Create a backend layer depth-wise convolution function + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth-wise convolution layer function + */ +std::unique_ptr create_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *weights = get_backing_tensor(node.input(1)); + ICLTensor *biases = get_backing_tensor(node.input(2)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); + + // Create and configure function (we assume that functions have been validated before creation) + std::unique_ptr func; + std::string func_name; + if(dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) + { + std::tie(func, func_name) = create_named_function( + std::string("CLDepthwiseConvolutionLayer3x3"), input, weights, biases, output, conv_info); + } + else + { + std::tie(func, func_name) = create_named_function( + std::string("CLDepthwiseConvolutionLayer"), input, weights, biases, output, conv_info); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + return func; +} + +/** Create a backend element-wise operation layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend element-wise operation layer function + */ +std::unique_ptr create_eltwise_layer(EltwiseLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 2); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input1 = get_backing_tensor(node.input(0)); + ICLTensor *input2 = get_backing_tensor(node.input(1)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const EltwiseOperation eltwise_op = node.eltwise_operation(); + ARM_COMPUTE_ERROR_ON(input1 == nullptr); + ARM_COMPUTE_ERROR_ON(input2 == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + std::unique_ptr func = nullptr; + std::string func_name; + if(eltwise_op == EltwiseOperation::ADD) + { + std::tie(func, func_name) = create_named_function(std::string("CLArithmeticAddition"), + input1, input2, output, + ConvertPolicy::SATURATE); + } + else if(eltwise_op == EltwiseOperation::SUB) + { + std::tie(func, func_name) = create_named_function( + std::string("CLArithmeticSubtraction"), input1, input2, output, ConvertPolicy::SATURATE); + } + else if(eltwise_op == EltwiseOperation::MUL) + { + std::tie(func, func_name) = create_named_function( + std::string("CLPixelWiseMultiplication"), input1, input2, output, 1.f, ConvertPolicy::SATURATE, + RoundingPolicy::TO_NEAREST_EVEN); + } + else + { + ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input1->info()->data_type() + << " Shape : " << input1->info()->tensor_shape() + << std::endl); + + return func; +} + +/** Create a backend flatten layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend flatten layer function + */ +std::unique_ptr create_flatten_layer(FlattenLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL FlattenLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLFlattenLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend fully connected layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend fully connected layer function + */ +std::unique_ptr create_fully_connected_layer(FullyConnectedLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL FullyConnectedLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *weights = get_backing_tensor(node.input(1)); + ICLTensor *biases = get_backing_tensor(node.input(2)); + ICLTensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::CL)); + func->configure(input, weights, biases, output); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(weights == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLFullyConnectedLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Biases Shape: " << biases->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend normalization layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend normalization layer function + */ +std::unique_ptr create_normalization_layer(NormalizationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL NormalizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const NormalizationLayerInfo norm_info = node.normalization_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, norm_info); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLNormalizationLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Normalization info: " << norm_info.type() + << std::endl); + + return std::move(func); +} + +/** Create a backend pooling layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend pooling layer function + */ +std::unique_ptr create_pooling_layer(PoolingLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL PoolingLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const PoolingLayerInfo pool_info = node.pooling_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, pool_info); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLPoolingLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Pooling info: " << pool_info.pool_type() + << std::endl); + + return std::move(func); +} + +/** Create a backend reshape layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend reshape layer function + */ +std::unique_ptr create_reshape_layer(ReshapeLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL ReshapeLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *output = get_backing_tensor(node.output(0)); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLReshapeLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend softmax layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend softmax layer function + */ +std::unique_ptr create_softmax_layer(SoftmaxLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating CL SoftmaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ICLTensor *input = get_backing_tensor(node.input(0)); + ICLTensor *output = get_backing_tensor(node.output(0)); + const float beta = node.beta(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::CL)); + func->configure(input, output, beta); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLSoftmaxLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} +} // namespace + +std::unique_ptr CLFunctionFactory::create(INode *node, GraphContext &ctx) +{ + if(node == nullptr) + { + return nullptr; + } + + NodeType type = node->type(); + switch(type) + { + case NodeType::ActivationLayer: + return create_activation_layer(*polymorphic_downcast(node)); + case NodeType::BatchNormalizationLayer: + return create_batch_normalization_layer(*polymorphic_downcast(node)); + case NodeType::ConvolutionLayer: + return create_convolution_layer(*polymorphic_downcast(node), ctx); + case NodeType::DepthConcatenateLayer: + return create_depth_concatenate_layer(*polymorphic_downcast(node)); + case NodeType::DepthwiseConvolutionLayer: + return create_depthwise_convolution_layer(*polymorphic_downcast(node)); + case NodeType::EltwiseLayer: + return create_eltwise_layer(*polymorphic_downcast(node)); + case NodeType::FlattenLayer: + return create_flatten_layer(*polymorphic_downcast(node)); + case NodeType::FullyConnectedLayer: + return create_fully_connected_layer(*polymorphic_downcast(node), ctx); + case NodeType::NormalizationLayer: + return create_normalization_layer(*polymorphic_downcast(node)); + case NodeType::PoolingLayer: + return create_pooling_layer(*polymorphic_downcast(node)); + case NodeType::ReshapeLayer: + return create_reshape_layer(*polymorphic_downcast(node)); + case NodeType::SoftmaxLayer: + return create_softmax_layer(*polymorphic_downcast(node), ctx); + default: + return nullptr; + } +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/CL/CLNodeValidator.cpp b/src/graph/backends/CL/CLNodeValidator.cpp new file mode 100644 index 0000000000..c16b2e67df --- /dev/null +++ b/src/graph/backends/CL/CLNodeValidator.cpp @@ -0,0 +1,64 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/CL/CLNodeValidator.h" + +#include "arm_compute/graph/backends/ValidateHelpers.h" +#include "arm_compute/graph/nodes/Nodes.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/runtime/CL/CLFunctions.h" + +using namespace arm_compute::utils::cast; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +Status CLNodeValidator::validate(INode *node) +{ + if(node == nullptr) + { + return Status{}; + } + + NodeType type = node->type(); + switch(type) + { + case NodeType::ConvolutionLayer: + return detail::validate_convolution_layer(*polymorphic_downcast(node)); + case NodeType::DepthwiseConvolutionLayer: + return detail::validate_depthwise_convolution_layer(*polymorphic_downcast(node)); + default: + return Status{}; + } +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/CL/CLSubTensorHandle.cpp b/src/graph/backends/CL/CLSubTensorHandle.cpp new file mode 100644 index 0000000000..a1bc8a1dd3 --- /dev/null +++ b/src/graph/backends/CL/CLSubTensorHandle.cpp @@ -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. + */ +#include "arm_compute/graph/backends/CL/CLSubTensorHandle.h" + +#include "arm_compute/core/utils/misc/Cast.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +CLSubTensorHandle::CLSubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent) + : _sub_tensor() +{ + ARM_COMPUTE_ERROR_ON(!parent_handle); + auto parent_tensor = arm_compute::utils::cast::polymorphic_downcast(&parent_handle->tensor()); + _sub_tensor = arm_compute::CLSubTensor(parent_tensor, shape, coords, extend_parent); +} + +void CLSubTensorHandle::allocate() +{ + // noop +} + +const arm_compute::ITensor &CLSubTensorHandle::tensor() const +{ + return _sub_tensor; +} + +arm_compute::ITensor &CLSubTensorHandle::tensor() +{ + return _sub_tensor; +} + +void CLSubTensorHandle::map(bool blocking) +{ + _sub_tensor.map(blocking); +} + +void CLSubTensorHandle::unmap() +{ + _sub_tensor.unmap(); +} + +void CLSubTensorHandle::release_if_unused() +{ + // noop +} + +bool CLSubTensorHandle::is_subtensor() const +{ + return true; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/CL/CLTensorHandle.cpp b/src/graph/backends/CL/CLTensorHandle.cpp new file mode 100644 index 0000000000..563c4d9ac6 --- /dev/null +++ b/src/graph/backends/CL/CLTensorHandle.cpp @@ -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. + */ +#include "arm_compute/graph/backends/CL/CLTensorHandle.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +CLTensorHandle::CLTensorHandle(const ITensorInfo &info) + : _tensor() +{ + _tensor.allocator()->init(info); +} + +void CLTensorHandle::allocate() +{ + _tensor.allocator()->allocate(); +} + +const arm_compute::ITensor &CLTensorHandle::tensor() const +{ + return _tensor; +} + +arm_compute::ITensor &CLTensorHandle::tensor() +{ + return _tensor; +} + +void CLTensorHandle::map(bool blocking) +{ + _tensor.map(blocking); +} + +void CLTensorHandle::unmap() +{ + _tensor.unmap(); +} + +void CLTensorHandle::release_if_unused() +{ + // TODO (geopin01): Release tensor only if all sub-tensors are marked as not used + if(!_tensor.is_used()) + { + _tensor.allocator()->free(); + } +} + +bool CLTensorHandle::is_subtensor() const +{ + return false; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/GLES/GCDeviceBackend.cpp b/src/graph/backends/GLES/GCDeviceBackend.cpp new file mode 100644 index 0000000000..8cd9994744 --- /dev/null +++ b/src/graph/backends/GLES/GCDeviceBackend.cpp @@ -0,0 +1,138 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/GLES/GCDeviceBackend.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/INode.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/backends/BackendRegistrar.h" +#include "arm_compute/graph/backends/GLES/GCFunctionFactory.h" +#include "arm_compute/graph/backends/GLES/GCNodeValidator.h" +#include "arm_compute/graph/backends/GLES/GCTensorHandle.h" + +#include "arm_compute/core/TensorInfo.h" +#include "arm_compute/runtime/BlobLifetimeManager.h" +#include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h" +#include "arm_compute/runtime/GLES_COMPUTE/GCScheduler.h" +#include "arm_compute/runtime/MemoryManagerOnDemand.h" +#include "arm_compute/runtime/PoolManager.h" + +#include "support/ToolchainSupport.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** Register GLES backend */ +static detail::BackendRegistrar GCDeviceBackend_registrar(Target::GC); + +GCDeviceBackend::GCDeviceBackend() + : _allocator() +{ +} + +void GCDeviceBackend::initialize_backend() +{ + // Setup Scheduler + GCScheduler::get().default_init(); +} + +void GCDeviceBackend::setup_backend_context(GraphContext &ctx) +{ + // Setup a management backend + if(ctx.memory_management_ctx(Target::GC) == nullptr) + { + MemoryManagerContext mm_ctx; + mm_ctx.target = Target::GC; + mm_ctx.mm = create_memory_manager(MemoryManagerAffinity::Buffer); + + ctx.insert_memory_management_ctx(std::move(mm_ctx)); + } +} + +bool GCDeviceBackend::is_backend_supported() +{ + return arm_compute::opengles31_is_available(); +} + +std::unique_ptr GCDeviceBackend::create_tensor(const Tensor &tensor) +{ + // Get tensor descriptor + const TensorDescriptor &tensor_desc = tensor.desc(); + ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::GC); + + // Create backend tensor handle + TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type); + auto backend_tensor_handle = support::cpp14::make_unique(info); + + return std::move(backend_tensor_handle); +} + +std::unique_ptr GCDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) +{ + ARM_COMPUTE_UNUSED(parent, shape, coords, extend_parent); + ARM_COMPUTE_ERROR("GLES backend has no sub-tensor support!"); + return nullptr; +} + +std::unique_ptr GCDeviceBackend::configure_node(INode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring GC node with ID : " << node.id() << std::endl); + ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::GC); + + // Configure node + return GCFunctionFactory::create(&node, ctx); +} + +arm_compute::Status GCDeviceBackend::validate_node(INode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GC node with ID : " << node.id() << std::endl); + ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::GC); + + return GCNodeValidator::validate(&node); +} + +std::shared_ptr GCDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity) +{ + if(affinity == MemoryManagerAffinity::Offset) + { + ARM_COMPUTE_LOG_GRAPH_WARNING("GC Backend does not support offset affinity memory management!"); + return nullptr; + } + + auto lifetime_mgr = std::make_shared(); + auto pool_mgr = std::make_shared(); + auto mm = std::make_shared(lifetime_mgr, pool_mgr); + + mm->set_allocator(&_allocator); + + return mm; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/GLES/GCFunctionsFactory.cpp b/src/graph/backends/GLES/GCFunctionsFactory.cpp new file mode 100644 index 0000000000..12e7c042d4 --- /dev/null +++ b/src/graph/backends/GLES/GCFunctionsFactory.cpp @@ -0,0 +1,507 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/GLES/GCFunctionFactory.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/TypePrinter.h" +#include "arm_compute/graph/Types.h" +#include "arm_compute/graph/backends/Utils.h" +#include "arm_compute/graph/nodes/Nodes.h" +#include "arm_compute/runtime/GLES_COMPUTE/GCFunctions.h" + +#include "support/ToolchainSupport.h" + +using namespace arm_compute::utils::cast; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace +{ +/** Returns backing tensor of a given tensor + * + * @param[in] tensor Tensor to extract the backing tensor from + * + * @return Backing tensor if present else nullptr + */ +arm_compute::IGCTensor *get_backing_tensor(arm_compute::graph::Tensor *tensor) +{ + arm_compute::IGCTensor *backing_tensor = nullptr; + if(tensor != nullptr) + { + ARM_COMPUTE_ERROR_ON(tensor->desc().target != arm_compute::graph::Target::GC); + // Get backing tensor handle + ITensorHandle *tensor_handle = tensor->handle(); + // Get backing tensor + backing_tensor = (tensor_handle != nullptr) ? polymorphic_cast(&tensor_handle->tensor()) : nullptr; + } + + return backing_tensor; +} + +/** Create a backend activation layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend activation layer function + */ +std::unique_ptr create_activation_layer(ActivationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC ActivationLayerNode node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const ActivationLayerInfo act_info = node.activation_info(); + + // Create function + auto func = support::cpp14::make_unique(); + func->configure(input, output, act_info); + + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCActivationLayer" + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Activation function: " << act_info.activation() + << " a: " << act_info.a() + << " b: " << act_info.b() + << " InPlace : " << is_in_place_operation(input, output) + << std::endl); + + return std::move(func); +} + +/** Create a backend batch normalization layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend batch normalization layer function + */ +std::unique_ptr create_batch_normalization_layer(BatchNormalizationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating GC BatchNormalization node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + + // TODO (geopin01) : Var and mean are compulsory, switch function to accept nullptr as beta and/or gamma + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 5); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *mean = get_backing_tensor(node.input(1)); + IGCTensor *var = get_backing_tensor(node.input(2)); + IGCTensor *beta = get_backing_tensor(node.input(3)); + IGCTensor *gamma = get_backing_tensor(node.input(4)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const float epsilon = node.epsilon(); + const ActivationLayerInfo fused_act = node.fused_activation(); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCBatchNormalizationLayer" + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Epsilon: " << epsilon << " " + << (fused_act.enabled() ? to_string(fused_act.activation()) : "") + << " InPlace : " << is_in_place_operation(input, output) + << std::endl); + + return std::move(func); +} + +/** Create a backend convolution layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend convolution layer function + */ +std::unique_ptr create_convolution_layer(ConvolutionLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating GC ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *weights = get_backing_tensor(node.input(1)); + IGCTensor *biases = get_backing_tensor(node.input(2)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const ConvolutionMethod conv_algorithm = node.convolution_method(); + + // Create and configure function (we assume that functions have been validated before creation) + std::shared_ptr mm = get_memory_manager(ctx, Target::GC); + std::unique_ptr func; + std::string func_name; + + if(conv_algorithm == ConvolutionMethod::DIRECT) + { + std::tie(func, func_name) = create_named_function( + std::string("GCDirectConvolutionLayer"), input, weights, biases, output, conv_info); + } + else + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("GCConvolutionLayer"), mm, + input, weights, biases, output, conv_info); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + return func; +} + +/** Create a backend layer depth concatenate function + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth concatenate layer function + */ +std::unique_ptr create_depth_concatenate_layer(DepthConcatenateLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating GC DepthConcatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Return nullptr if depth concatenate is switched off + if(!node.is_enabled()) + { + return nullptr; + } + + // Extract IO and info + std::vector inputs; + for(unsigned int i = 0; i < node.num_inputs(); ++i) + { + inputs.push_back(get_backing_tensor(node.input(i))); + } + IGCTensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(inputs, output); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCDepthConcatenateLayer" + << " Data Type: " << output->info()->data_type() + << " Shape: " << output->info()->tensor_shape() + << " Num Inputs: " << inputs.size() + << std::endl); + + return std::move(func); +} + +/** Create a backend layer depth-wise convolution function + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth-wise convolution layer function + */ +std::unique_ptr create_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *weights = get_backing_tensor(node.input(1)); + IGCTensor *biases = get_backing_tensor(node.input(2)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); + + // Create and configure function (we assume that functions have been validated before creation) + std::unique_ptr func; + std::string func_name; + if(dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) + { + std::tie(func, func_name) = create_named_function( + std::string("GCDepthwiseConvolutionLayer3x3"), input, weights, biases, output, conv_info); + } + else + { + ARM_COMPUTE_ERROR("Generic DepthwiseConvolutionLayer is not supported in GLES backend"); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + return func; +} + +/** Create a backend element-wise operation layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend element-wise operation layer function + */ +std::unique_ptr create_eltwise_layer(EltwiseLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 2); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input1 = get_backing_tensor(node.input(0)); + IGCTensor *input2 = get_backing_tensor(node.input(1)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const EltwiseOperation eltwise_op = node.eltwise_operation(); + ARM_COMPUTE_ERROR_ON(input1 == nullptr); + ARM_COMPUTE_ERROR_ON(input2 == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + std::unique_ptr func = nullptr; + std::string func_name; + if(eltwise_op == EltwiseOperation::ADD) + { + std::tie(func, func_name) = create_named_function(std::string("GCArithmeticAddition"), + input1, input2, output, + ConvertPolicy::SATURATE); + } + else if(eltwise_op == EltwiseOperation::SUB) + { + ARM_COMPUTE_ERROR("Arithmetic subtraction is not supported in GLES backend"); + } + else if(eltwise_op == EltwiseOperation::MUL) + { + std::tie(func, func_name) = create_named_function( + std::string("GCPixelWiseMultiplication"), input1, input2, output, 1.f); + } + else + { + ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input1->info()->data_type() + << " Shape : " << input1->info()->tensor_shape() + << std::endl); + + return func; +} + +/** Create a backend fully connected layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend fully connected layer function + */ +std::unique_ptr create_fully_connected_layer(FullyConnectedLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC FullyConnectedLayer node with ID : " << node.id() << " and Name: " << node.name() + << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *weights = get_backing_tensor(node.input(1)); + IGCTensor *biases = get_backing_tensor(node.input(2)); + IGCTensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::GC)); + func->configure(input, weights, biases, output); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(weights == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCFullyConnectedLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Biases Shape: " << biases->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend normalization layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend normalization layer function + */ +std::unique_ptr create_normalization_layer(NormalizationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC NormalizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const NormalizationLayerInfo norm_info = node.normalization_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, norm_info); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCNormalizationLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Normalization info: " << norm_info.type() + << std::endl); + + return std::move(func); +} + +/** Create a backend pooling layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend pooling layer function + */ +std::unique_ptr create_pooling_layer(PoolingLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC PoolingLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const PoolingLayerInfo pool_info = node.pooling_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, pool_info); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCPoolingLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Pooling info: " << pool_info.pool_type() + << std::endl); + + return std::move(func); +} + +/** Create a backend softmax layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend softmax layer function + */ +std::unique_ptr create_softmax_layer(SoftmaxLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE( + "Creating GC SoftmaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + IGCTensor *input = get_backing_tensor(node.input(0)); + IGCTensor *output = get_backing_tensor(node.output(0)); + const float beta = node.beta(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::CL)); + func->configure(input, output, beta); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCSoftmaxLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} +} // namespace + +std::unique_ptr GCFunctionFactory::create(INode *node, GraphContext &ctx) +{ + if(node == nullptr) + { + return nullptr; + } + + NodeType type = node->type(); + switch(type) + { + case NodeType::ActivationLayer: + return create_activation_layer(*polymorphic_downcast(node)); + case NodeType::BatchNormalizationLayer: + return create_batch_normalization_layer(*polymorphic_downcast(node)); + case NodeType::ConvolutionLayer: + return create_convolution_layer(*polymorphic_downcast(node), ctx); + case NodeType::DepthConcatenateLayer: + return create_depth_concatenate_layer(*polymorphic_downcast(node)); + case NodeType::DepthwiseConvolutionLayer: + return create_depthwise_convolution_layer(*polymorphic_downcast(node)); + case NodeType::EltwiseLayer: + return create_eltwise_layer(*polymorphic_downcast(node)); + case NodeType::FullyConnectedLayer: + return create_fully_connected_layer(*polymorphic_downcast(node), ctx); + case NodeType::NormalizationLayer: + return create_normalization_layer(*polymorphic_downcast(node)); + case NodeType::PoolingLayer: + return create_pooling_layer(*polymorphic_downcast(node)); + case NodeType::SoftmaxLayer: + return create_softmax_layer(*polymorphic_downcast(node), ctx); + default: + return nullptr; + } +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/GLES/GCNodeValidator.cpp b/src/graph/backends/GLES/GCNodeValidator.cpp new file mode 100644 index 0000000000..1e89265382 --- /dev/null +++ b/src/graph/backends/GLES/GCNodeValidator.cpp @@ -0,0 +1,122 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/GLES/GCNodeValidator.h" + +#include "arm_compute/graph/backends/ValidateHelpers.h" +#include "arm_compute/graph/nodes/Nodes.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/runtime/GLES_COMPUTE/GCFunctions.h" + +using namespace arm_compute::utils::cast; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace +{ +/** Validates a Depthwise Convolution layer node + * + * @param[in] node Node to validate + * + * @return Status + */ +Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GCDepthwiseConvolutionLayer 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)); + ARM_COMPUTE_ERROR_ON(weights == nullptr); + + // TODO (geopin01) : Switch when validation is implemented + // Validate function + ARM_COMPUTE_RETURN_ERROR_ON_MSG(weights->tensor_shape().x() != 3 && weights->tensor_shape().y() != 3, "Unsupported depthwise convolution"); + node.set_depthwise_convolution_method(DepthwiseConvolutionMethod::OPTIMIZED_3x3); + + return Status{}; +} +/** Validates a Convolution layer node + * + * @param[in] node Node to validate + * + * @return Status + */ +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 *weights = detail::get_backing_tensor_info(node.input(1)); + const PadStrideInfo conv_info = node.convolution_info(); + const ConvolutionMethod conv_algorithm = node.convolution_method(); + + // Validate function + if(conv_algorithm == ConvolutionMethod::DIRECT) + { + bool is_square = weights->tensor_shape().x() == weights->tensor_shape().y(); + bool is_direct = (weights->tensor_shape().x() == 1) || (weights->tensor_shape().x() == 3) || (weights->tensor_shape().x() == 5); + bool is_correct_stride = (conv_info.stride().first) <= 2 && (conv_info.stride().second <= 2); + if(!(is_square && is_direct && is_correct_stride)) + { + node.set_convolution_method(ConvolutionMethod::DEFAULT); + } + } + + return Status{}; +} +} // namespace + +Status GCNodeValidator::validate(INode *node) +{ + if(node == nullptr) + { + return Status{}; + } + + NodeType type = node->type(); + switch(type) + { + case NodeType::ConvolutionLayer: + return validate_convolution_layer(*polymorphic_downcast(node)); + case NodeType::DepthwiseConvolutionLayer: + return validate_depthwise_convolution_layer(*polymorphic_downcast(node)); + case NodeType::FlattenLayer: + return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation"); + case NodeType::ReshapeLayer: + return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation"); + default: + return Status{}; + } +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/GLES/GCTensorHandle.cpp b/src/graph/backends/GLES/GCTensorHandle.cpp new file mode 100644 index 0000000000..ae7c778130 --- /dev/null +++ b/src/graph/backends/GLES/GCTensorHandle.cpp @@ -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. + */ +#include "arm_compute/graph/backends/GLES/GCTensorHandle.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +GCTensorHandle::GCTensorHandle(const ITensorInfo &info) + : _tensor() +{ + _tensor.allocator()->init(info); +} + +void GCTensorHandle::allocate() +{ + _tensor.allocator()->allocate(); +} + +const arm_compute::ITensor &GCTensorHandle::tensor() const +{ + return _tensor; +} + +arm_compute::ITensor &GCTensorHandle::tensor() +{ + return _tensor; +} + +void GCTensorHandle::map(bool blocking) +{ + _tensor.map(blocking); +} + +void GCTensorHandle::unmap() +{ + _tensor.unmap(); +} + +void GCTensorHandle::release_if_unused() +{ + // TODO (geopin01): Release tensor only if all sub-tensors are marked as not used + if(!_tensor.is_used()) + { + _tensor.allocator()->free(); + } +} + +bool GCTensorHandle::is_subtensor() const +{ + return false; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/NEON/NEDeviceBackend.cpp b/src/graph/backends/NEON/NEDeviceBackend.cpp new file mode 100644 index 0000000000..87f88dffdf --- /dev/null +++ b/src/graph/backends/NEON/NEDeviceBackend.cpp @@ -0,0 +1,146 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/NEON/NEDeviceBackend.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/INode.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/backends/BackendRegistrar.h" +#include "arm_compute/graph/backends/NEON/NEFunctionFactory.h" +#include "arm_compute/graph/backends/NEON/NENodeValidator.h" +#include "arm_compute/graph/backends/NEON/NESubTensorHandle.h" +#include "arm_compute/graph/backends/NEON/NETensorHandle.h" + +#include "arm_compute/core/TensorInfo.h" +#include "arm_compute/runtime/Allocator.h" +#include "arm_compute/runtime/BlobLifetimeManager.h" +#include "arm_compute/runtime/MemoryManagerOnDemand.h" +#include "arm_compute/runtime/OffsetLifetimeManager.h" +#include "arm_compute/runtime/PoolManager.h" +#include "arm_compute/runtime/Scheduler.h" + +#include "support/ToolchainSupport.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +/** Register NEON backend */ +static detail::BackendRegistrar NEDeviceBackend_registrar(Target::NEON); + +NEDeviceBackend::NEDeviceBackend() + : _allocator() +{ +} + +void NEDeviceBackend::initialize_backend() +{ +} + +void NEDeviceBackend::setup_backend_context(GraphContext &ctx) +{ + // Set number of threads + Scheduler::get().set_num_threads(ctx.config().num_threads); + + // Create function level memory manager + if(ctx.memory_management_ctx(Target::NEON) == nullptr) + { + MemoryManagerContext mm_ctx; + mm_ctx.target = Target::NEON; + mm_ctx.mm = create_memory_manager(MemoryManagerAffinity::Buffer); + + ctx.insert_memory_management_ctx(std::move(mm_ctx)); + } +} + +bool NEDeviceBackend::is_backend_supported() +{ + return true; +} + +std::unique_ptr NEDeviceBackend::create_tensor(const Tensor &tensor) +{ + // Get tensor descriptor + const TensorDescriptor &tensor_desc = tensor.desc(); + ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::NEON); + + // Create backend tensor handle + TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type); + auto backend_tensor_handle = support::cpp14::make_unique(info); + + return std::move(backend_tensor_handle); +} + +std::unique_ptr NEDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) +{ + if(parent == nullptr) + { + return nullptr; + } + + return support::cpp14::make_unique(parent, shape, coords, extend_parent); +} + +std::unique_ptr NEDeviceBackend::configure_node(INode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring NEON node with ID : " << node.id() << std::endl); + ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::NEON); + + // Configure node + return NEFunctionFactory::create(&node, ctx); +} + +arm_compute::Status NEDeviceBackend::validate_node(INode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating NEON node with ID : " << node.id() << std::endl); + ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::NEON); + + return NENodeValidator::validate(&node); +} + +std::shared_ptr NEDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity) +{ + std::shared_ptr lifetime_mgr = nullptr; + if(affinity == MemoryManagerAffinity::Buffer) + { + lifetime_mgr = std::make_shared(); + } + else + { + lifetime_mgr = std::make_shared(); + } + auto pool_mgr = std::make_shared(); + auto mm = std::make_shared(lifetime_mgr, pool_mgr); + + mm->set_allocator(&_allocator); + + return mm; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/NEON/NEFunctionFactory.cpp b/src/graph/backends/NEON/NEFunctionFactory.cpp new file mode 100644 index 0000000000..228af9ca6f --- /dev/null +++ b/src/graph/backends/NEON/NEFunctionFactory.cpp @@ -0,0 +1,563 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/NEON/NEFunctionFactory.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/TypePrinter.h" +#include "arm_compute/graph/backends/Utils.h" +#include "arm_compute/graph/nodes/Nodes.h" +#include "arm_compute/runtime/NEON/NEFunctions.h" +#include "support/ToolchainSupport.h" + +using namespace arm_compute::utils::cast; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +namespace +{ +/** Returns backing tensor of a given tensor + * + * @param[in] tensor Tensor to extract the backing tensor from + * + * @return Backing tensor if present else nullptr + */ +arm_compute::ITensor *get_backing_tensor(arm_compute::graph::Tensor *tensor) +{ + return ((tensor == nullptr) || (tensor->handle() == nullptr)) ? nullptr : &tensor->handle()->tensor(); +} + +/** Create a backend activation layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend activation layer function + */ +std::unique_ptr create_activation_layer(ActivationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON ActivationLayerNode node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *output = get_backing_tensor(node.output(0)); + const ActivationLayerInfo act_info = node.activation_info(); + + // Create function + auto func = support::cpp14::make_unique(); + func->configure(input, output, act_info); + + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEActivationLayer" + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Activation function: " << act_info.activation() + << " a: " << act_info.a() + << " b: " << act_info.b() + << " InPlace : " << is_in_place_operation(input, output) + << std::endl); + + return std::move(func); +} + +/** Create a backend batch normalization layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend batch normalization layer function + */ +std::unique_ptr create_batch_normalization_layer(BatchNormalizationLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON BatchNormalization node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + + // TODO (geopin01) : Var and mean are compulsory, switch function to accept nullptr as beta and/or gamma + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 5); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *mean = get_backing_tensor(node.input(1)); + ITensor *var = get_backing_tensor(node.input(2)); + ITensor *beta = get_backing_tensor(node.input(3)); + ITensor *gamma = get_backing_tensor(node.input(4)); + ITensor *output = get_backing_tensor(node.output(0)); + const float epsilon = node.epsilon(); + const ActivationLayerInfo fused_act = node.fused_activation(); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEBatchNormalizationLayer" + << " Data Type: " << input->info()->data_type() + << " Shape: " << input->info()->tensor_shape() + << " Epsilon: " << epsilon << " " + << (fused_act.enabled() ? to_string(fused_act.activation()) : "") + << " InPlace : " << is_in_place_operation(input, output) + << std::endl); + + return std::move(func); +} + +/** Create a backend convolution layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend convolution layer function + */ +std::unique_ptr create_convolution_layer(ConvolutionLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *weights = get_backing_tensor(node.input(1)); + ITensor *biases = get_backing_tensor(node.input(2)); + ITensor *output = get_backing_tensor(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const ConvolutionMethod conv_algorithm = node.convolution_method(); + + // Create and configure function (we assume that functions have been validated before creation) + std::shared_ptr mm = get_memory_manager(ctx, Target::NEON); + std::unique_ptr func; + std::string func_name; + if(conv_algorithm == ConvolutionMethod::DIRECT) + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEDirectConvolutionLayer"), mm, + input, weights, biases, output, conv_info); + } + else if(conv_algorithm == ConvolutionMethod::GEMM) + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEGEMMConvolutionLayer"), mm, + input, weights, biases, output, conv_info); + } + else if(conv_algorithm == ConvolutionMethod::WINOGRAD) + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEWinogradLayer"), mm, + input, weights, biases, output, conv_info); + } + else + { + std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEConvolutionLayer"), mm, + input, weights, biases, output, conv_info); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + return func; +} + +/** Create a backend layer depth concatenate function + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth concatenate layer function + */ +std::unique_ptr create_depth_concatenate_layer(DepthConcatenateLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON DepthConcatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Return nullptr if depth concatenate is switched off + if(!node.is_enabled()) + { + return nullptr; + } + + // Extract IO and info + std::vector inputs; + for(unsigned int i = 0; i < node.num_inputs(); ++i) + { + inputs.push_back(get_backing_tensor(node.input(i))); + } + ITensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(inputs, output); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEDepthConcatenateLayer" + << " Data Type: " << output->info()->data_type() + << " Shape: " << output->info()->tensor_shape() + << " Num Inputs: " << inputs.size() + << std::endl); + + return std::move(func); +} + +/** Create a backend layer depth-wise convolution function + * + * @param[in] node Node to create the backend function for + * + * @return Backend depth-wise convolution layer function + */ +std::unique_ptr create_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *weights = get_backing_tensor(node.input(1)); + ITensor *biases = get_backing_tensor(node.input(2)); + ITensor *output = get_backing_tensor(node.output(0)); + const PadStrideInfo conv_info = node.convolution_info(); + const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); + + // Create and configure function (we assume that functions have been validated before creation) + std::unique_ptr func; + std::string func_name; + if(dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) + { + std::tie(func, func_name) = create_named_function(std::string("NEDepthwiseConvolutionLayer3x3"), + input, weights, biases, output, conv_info); + } + else + { + std::tie(func, func_name) = create_named_function(std::string("NEDepthwiseConvolutionLayer"), + input, weights, biases, output, conv_info); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + return func; +} + +/** Create a backend element-wise operation layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend element-wise operation layer function + */ +std::unique_ptr create_eltwise_layer(EltwiseLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 2); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input1 = get_backing_tensor(node.input(0)); + ITensor *input2 = get_backing_tensor(node.input(1)); + ITensor *output = get_backing_tensor(node.output(0)); + const EltwiseOperation eltwise_op = node.eltwise_operation(); + ARM_COMPUTE_ERROR_ON(input1 == nullptr); + ARM_COMPUTE_ERROR_ON(input2 == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + std::unique_ptr func = nullptr; + std::string func_name; + if(eltwise_op == EltwiseOperation::ADD) + { + std::tie(func, func_name) = create_named_function(std::string("NEArithmeticAddition"), + input1, input2, output, ConvertPolicy::SATURATE); + } + else if(eltwise_op == EltwiseOperation::SUB) + { + std::tie(func, func_name) = create_named_function(std::string("NEArithmeticSubtraction"), + input1, input2, output, ConvertPolicy::SATURATE); + } + else if(eltwise_op == EltwiseOperation::MUL) + { + std::tie(func, func_name) = create_named_function(std::string("NEPixelWiseMultiplication"), + input1, input2, output, 1.f, + ConvertPolicy::SATURATE, RoundingPolicy::TO_NEAREST_EVEN); + } + else + { + ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); + } + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name + << " Data Type: " << input1->info()->data_type() + << " Shape : " << input1->info()->tensor_shape() + << std::endl); + + return func; +} + +/** Create a backend flatten layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend flatten layer function + */ +std::unique_ptr create_flatten_layer(FlattenLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON FlattenLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEFlattenLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend fully connected layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend fully connected layer function + */ +std::unique_ptr create_fully_connected_layer(FullyConnectedLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON FullyConnectedLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *weights = get_backing_tensor(node.input(1)); + ITensor *biases = get_backing_tensor(node.input(2)); + ITensor *output = get_backing_tensor(node.output(0)); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::NEON)); + func->configure(input, weights, biases, output); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(weights == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEFullyConnectedLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Weights shape: " << weights->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend normalization layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend normalization layer function + */ +std::unique_ptr create_normalization_layer(NormalizationLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON NormalizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *output = get_backing_tensor(node.output(0)); + const NormalizationLayerInfo norm_info = node.normalization_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::NEON)); + func->configure(input, output, norm_info); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NENormalizationLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Normalization info: " << norm_info.type() + << std::endl); + + return std::move(func); +} + +/** Create a backend pooling layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend pooling layer function + */ +std::unique_ptr create_pooling_layer(PoolingLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON PoolingLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *output = get_backing_tensor(node.output(0)); + const PoolingLayerInfo pool_info = node.pooling_info(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output, pool_info); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEPoolingLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << " Pooling info: " << pool_info.pool_type() + << std::endl); + + return std::move(func); +} + +/** Create a backend reshape layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend reshape layer function + */ +std::unique_ptr create_reshape_layer(ReshapeLayerNode &node) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON ReshapeLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *output = get_backing_tensor(node.output(0)); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(); + func->configure(input, output); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEReshapeLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} + +/** Create a backend softmax layer function + * + * @param[in] node Node to create the backend function for + * + * @return Backend softmax layer function + */ +std::unique_ptr create_softmax_layer(SoftmaxLayerNode &node, GraphContext &ctx) +{ + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON SoftmaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); + ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); + ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); + + // Extract IO and info + ITensor *input = get_backing_tensor(node.input(0)); + ITensor *output = get_backing_tensor(node.output(0)); + const float beta = node.beta(); + ARM_COMPUTE_ERROR_ON(input == nullptr); + ARM_COMPUTE_ERROR_ON(output == nullptr); + + // Create and configure function + auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::NEON)); + func->configure(input, output, beta); + + // Log info + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NESoftmaxLayer" + << " Data Type: " << input->info()->data_type() + << " Input shape: " << input->info()->tensor_shape() + << " Output shape: " << output->info()->tensor_shape() + << std::endl); + + return std::move(func); +} +} // namespace + +std::unique_ptr NEFunctionFactory::create(INode *node, GraphContext &ctx) +{ + if(node == nullptr) + { + return nullptr; + } + + NodeType type = node->type(); + switch(type) + { + case NodeType::ActivationLayer: + return create_activation_layer(*polymorphic_downcast(node)); + case NodeType::BatchNormalizationLayer: + return create_batch_normalization_layer(*polymorphic_downcast(node)); + case NodeType::ConvolutionLayer: + return create_convolution_layer(*polymorphic_downcast(node), ctx); + case NodeType::DepthConcatenateLayer: + return create_depth_concatenate_layer(*polymorphic_downcast(node)); + case NodeType::DepthwiseConvolutionLayer: + return create_depthwise_convolution_layer(*polymorphic_downcast(node)); + case NodeType::EltwiseLayer: + return create_eltwise_layer(*polymorphic_downcast(node)); + case NodeType::FlattenLayer: + return create_flatten_layer(*polymorphic_downcast(node)); + case NodeType::FullyConnectedLayer: + return create_fully_connected_layer(*polymorphic_downcast(node), ctx); + case NodeType::NormalizationLayer: + return create_normalization_layer(*polymorphic_downcast(node), ctx); + case NodeType::PoolingLayer: + return create_pooling_layer(*polymorphic_downcast(node)); + case NodeType::ReshapeLayer: + return create_reshape_layer(*polymorphic_downcast(node)); + case NodeType::SoftmaxLayer: + return create_softmax_layer(*polymorphic_downcast(node), ctx); + default: + return nullptr; + } +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/NEON/NENodeValidator.cpp b/src/graph/backends/NEON/NENodeValidator.cpp new file mode 100644 index 0000000000..074f03580f --- /dev/null +++ b/src/graph/backends/NEON/NENodeValidator.cpp @@ -0,0 +1,65 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/NEON/NENodeValidator.h" + +#include "arm_compute/graph/backends/ValidateHelpers.h" +#include "arm_compute/graph/nodes/Nodes.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/runtime/NEON/NEFunctions.h" + +using namespace arm_compute::utils::cast; + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +Status NENodeValidator::validate(INode *node) +{ + if(node == nullptr) + { + return Status{}; + } + + NodeType type = node->type(); + switch(type) + { + case NodeType::ConvolutionLayer: + return detail::validate_convolution_layer(*polymorphic_downcast(node)); + case NodeType::DepthwiseConvolutionLayer: + return detail::validate_depthwise_convolution_layer(*polymorphic_downcast(node)); + + default: + return Status{}; + } +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/NEON/NESubTensorHandle.cpp b/src/graph/backends/NEON/NESubTensorHandle.cpp new file mode 100644 index 0000000000..c48ba6b9d6 --- /dev/null +++ b/src/graph/backends/NEON/NESubTensorHandle.cpp @@ -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. + */ +#include "arm_compute/graph/backends/NEON/NESubTensorHandle.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +NESubTensorHandle::NESubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent) + : _sub_tensor() +{ + ARM_COMPUTE_ERROR_ON(!parent_handle); + _sub_tensor = arm_compute::SubTensor(&parent_handle->tensor(), shape, coords, extend_parent); +} + +void NESubTensorHandle::allocate() +{ + // noop +} + +const arm_compute::ITensor &NESubTensorHandle::tensor() const +{ + return _sub_tensor; +} + +arm_compute::ITensor &NESubTensorHandle::tensor() +{ + return _sub_tensor; +} + +void NESubTensorHandle::map(bool blocking) +{ + ARM_COMPUTE_UNUSED(blocking); +} + +void NESubTensorHandle::unmap() +{ + // noop +} + +void NESubTensorHandle::release_if_unused() +{ + // noop +} + +bool NESubTensorHandle::is_subtensor() const +{ + return true; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/backends/NEON/NETensorHandle.cpp b/src/graph/backends/NEON/NETensorHandle.cpp new file mode 100644 index 0000000000..8508ac9511 --- /dev/null +++ b/src/graph/backends/NEON/NETensorHandle.cpp @@ -0,0 +1,77 @@ +/* + * 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. + */ +#include "arm_compute/graph/backends/NEON/NETensorHandle.h" + +namespace arm_compute +{ +namespace graph +{ +namespace backends +{ +NETensorHandle::NETensorHandle(const ITensorInfo &info) + : _tensor() +{ + _tensor.allocator()->init(info); +} + +void NETensorHandle::allocate() +{ + _tensor.allocator()->allocate(); +} + +const arm_compute::ITensor &NETensorHandle::tensor() const +{ + return _tensor; +} + +arm_compute::ITensor &NETensorHandle::tensor() +{ + return _tensor; +} + +void NETensorHandle::map(bool blocking) +{ + ARM_COMPUTE_UNUSED(blocking); +} + +void NETensorHandle::unmap() +{ +} + +void NETensorHandle::release_if_unused() +{ + // TODO (geopin01): Release tensor only if all sub-tensors are marked as not used + if(!_tensor.is_used()) + { + _tensor.allocator()->free(); + } +} + +bool NETensorHandle::is_subtensor() const +{ + return false; +} +} // namespace backends +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/detail/ExecutionHelpers.cpp b/src/graph/detail/ExecutionHelpers.cpp new file mode 100644 index 0000000000..5a50728164 --- /dev/null +++ b/src/graph/detail/ExecutionHelpers.cpp @@ -0,0 +1,199 @@ +/* + * 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. + */ +#include "arm_compute/graph/detail/ExecutionHelpers.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/GraphContext.h" +#include "arm_compute/graph/GraphManager.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/backends/BackendRegistry.h" + +namespace arm_compute +{ +namespace graph +{ +namespace detail +{ +void default_initialize_backends() +{ + for(const auto &backend : backends::BackendRegistry::get().backends()) + { + backend.second->initialize_backend(); + } +} + +void configure_all_tensors(Graph &g) +{ + auto &tensors = g.tensors(); + + for(auto &tensor : tensors) + { + if(tensor) + { + Target target = tensor->desc().target; + auto backend = backends::BackendRegistry::get().find_backend(target); + ARM_COMPUTE_ERROR_ON_MSG(!backend, "Requested backend doesn't exist!"); + auto handle = backend->create_tensor(*tensor); + ARM_COMPUTE_ERROR_ON_MSG(!backend, "Couldn't create backend handle!"); + tensor->set_handle(std::move(handle)); + } + } +} + +void allocate_all_tensors(Graph &g) +{ + auto &tensors = g.tensors(); + + for(auto &tensor : tensors) + { + if(tensor && !tensor->bound_edges().empty()) + { + ARM_COMPUTE_ERROR_ON_MSG(!tensor->handle(), "Tensor handle is not configured!"); + tensor->handle()->allocate(); + } + } +} + +void validate_all_nodes(Graph &g) +{ + auto &nodes = g.nodes(); + + // Create tasks + for(auto &node : nodes) + { + if(node != nullptr) + { + Target assigned_target = node->assigned_target(); + auto backend = backends::BackendRegistry::get().find_backend(assigned_target); + ARM_COMPUTE_ERROR_ON_MSG(!backend, "Requested backend doesn't exist!"); + Status status = backend->validate_node(*node); + ARM_COMPUTE_ERROR_ON_MSG(!bool(status), status.error_description().c_str()); + } + } +} + +ExecutionWorkload configure_all_nodes(Graph &g, GraphContext &ctx) +{ + ExecutionWorkload workload; + auto &nodes = g.nodes(); + + // Create tasks + for(auto &node : nodes) + { + if(node != nullptr) + { + Target assigned_target = node->assigned_target(); + auto backend = backends::BackendRegistry::get().find_backend(assigned_target); + ARM_COMPUTE_ERROR_ON_MSG(!backend, "Requested backend doesn't exist!"); + auto func = backend->configure_node(*node, ctx); + if(func != nullptr) + { + ExecutionTask task; + task.task = std::move(func); + task.node = node.get(); + workload.tasks.push_back(std::move(task)); + } + } + } + + // Add inputs and outputs + for(auto &node : nodes) + { + if(node != nullptr && node->type() == NodeType::Input) + { + workload.inputs.push_back(node->output(0)); + } + + if(node != nullptr && node->type() == NodeType::Output) + { + workload.outputs.push_back(node->input(0)); + continue; + } + } + + return workload; +} + +void release_unused_tensors(Graph &g) +{ + for(auto &tensor : g.tensors()) + { + if(tensor != nullptr && tensor->handle() != nullptr) + { + tensor->handle()->release_if_unused(); + } + } +} + +void call_tensor_accessor(Tensor *tensor) +{ + ARM_COMPUTE_ERROR_ON(!tensor); + tensor->call_accessor(); +} + +void call_all_const_node_accessors(Graph &g) +{ + auto &nodes = g.nodes(); + + for(auto &node : nodes) + { + if(node != nullptr && node->type() == NodeType::Const) + { + call_tensor_accessor(node->output(0)); + } + } +} + +void call_all_input_node_accessors(ExecutionWorkload &workload) +{ + for(auto &input : workload.inputs) + { + if(input != nullptr) + { + input->call_accessor(); + } + } +} + +void call_all_tasks(ExecutionWorkload &workload) +{ + for(auto &task : workload.tasks) + { + task(); + } +} + +void call_all_output_node_accessors(ExecutionWorkload &workload) +{ + for(auto &output : workload.outputs) + { + if(output != nullptr) + { + output->call_accessor(); + } + } +} +} // namespace detail +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/frontend/Stream.cpp b/src/graph/frontend/Stream.cpp new file mode 100644 index 0000000000..96a166c79c --- /dev/null +++ b/src/graph/frontend/Stream.cpp @@ -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. + */ +#include "arm_compute/graph/frontend/Stream.h" + +#include "arm_compute/graph/Utils.h" +#include "arm_compute/graph/frontend/ILayer.h" + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +Stream::Stream(size_t id, std::string name) + : _manager(), _ctx(), _g(id, std::move(name)) +{ +} + +void Stream::finalize(Target target, const GraphConfig &config) +{ + PassManager pm = create_default_pass_manager(target); + _ctx.set_config(config); + _manager.finalize_graph(_g, _ctx, pm, target); +} + +void Stream::run() +{ + _manager.execute_graph(_g); +} + +void Stream::add_layer(ILayer &layer) +{ + auto nid = layer.create_layer(*this); + _tail_node = nid; +} + +const Graph &Stream::graph() const +{ + return _g; +} + +Graph &Stream::graph() +{ + return _g; +} +} // namespace frontend +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/frontend/SubStream.cpp b/src/graph/frontend/SubStream.cpp new file mode 100644 index 0000000000..e8bd23a557 --- /dev/null +++ b/src/graph/frontend/SubStream.cpp @@ -0,0 +1,59 @@ +/* + * 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. + */ +#include "arm_compute/graph/frontend/SubStream.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/frontend/ILayer.h" + +namespace arm_compute +{ +namespace graph +{ +namespace frontend +{ +SubStream::SubStream(IStream &s) + : _s(s) +{ + _hints = s.hints(); + _tail_node = s.tail_node(); +} + +void SubStream::add_layer(ILayer &layer) +{ + auto nid = layer.create_layer(*this); + _tail_node = nid; +} + +const Graph &SubStream::graph() const +{ + return _s.graph(); +} + +Graph &SubStream::graph() +{ + return _s.graph(); +} +} // namespace frontend +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/mutators/DepthConcatSubTensorMutator.cpp b/src/graph/mutators/DepthConcatSubTensorMutator.cpp new file mode 100644 index 0000000000..c56f4c5106 --- /dev/null +++ b/src/graph/mutators/DepthConcatSubTensorMutator.cpp @@ -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. + */ +#include "arm_compute/graph/mutators/DepthConcatSubTensorMutator.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/backends/BackendRegistry.h" +#include "arm_compute/graph/nodes/DepthConcatenateLayerNode.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/core/utils/misc/Iterable.h" + +namespace arm_compute +{ +namespace graph +{ +const char *DepthConcatSubTensorMutator::name() +{ + return "DepthConcatSubTensorMutator"; +} + +void DepthConcatSubTensorMutator::mutate(Graph &g) +{ + // Should be in reverse order of execution + for(auto &node : arm_compute::utils::iterable::reverse_iterate(g.nodes())) + { + if(node && node->type() == NodeType::DepthConcatenateLayer && node->output(0) != nullptr) + { + // Get output tensor + auto output_tensor = node->output(0); + + // Check that all tensor have the same target and valid inputs + bool is_valid = std::all_of(node->input_edges().cbegin(), node->input_edges().cend(), + [&](const EdgeID & eid) + { + return (g.edge(eid) != nullptr) && (g.edge(eid)->tensor() != nullptr) && (g.edge(eid)->tensor()->desc().target == output_tensor->desc().target); + }); + + // Create subtensors + if(is_valid && backends::BackendRegistry::get().find_backend(output_tensor->desc().target) != nullptr) + { + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Using sub-tensors for the node with ID : " + << node->id() << " and name : " << node->name() << std::endl); + // Create sub-tensor handles + unsigned depth = 0; + for(unsigned int i = 0; i < node->input_edges().size(); ++i) + { + auto input_tensor = node->input(i); + const auto input_shape = input_tensor->desc().shape; + + auto backend = backends::BackendRegistry::get().find_backend(input_tensor->desc().target); + auto handle = backend->create_subtensor(output_tensor->handle(), input_shape, Coordinates(0, 0, depth), false); + input_tensor->set_handle(std::move(handle)); + + depth += input_shape.z(); + } + + auto *dc_node = arm_compute::utils::cast::polymorphic_downcast(node.get()); + dc_node->set_enabled(false); + } + } + } +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/mutators/InPlaceOperationMutator.cpp b/src/graph/mutators/InPlaceOperationMutator.cpp new file mode 100644 index 0000000000..bd3f098965 --- /dev/null +++ b/src/graph/mutators/InPlaceOperationMutator.cpp @@ -0,0 +1,63 @@ +/* + * 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. + */ +#include "arm_compute/graph/mutators/InPlaceOperationMutator.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Logger.h" + +namespace arm_compute +{ +namespace graph +{ +const char *InPlaceOperationMutator::name() +{ + return "InPlaceOperationMutator"; +} + +void InPlaceOperationMutator::mutate(Graph &g) +{ + std::set in_place_nodes = { NodeType::BatchNormalizationLayer, NodeType::ActivationLayer }; + + // Not interested in the order of nodes + for(auto &node : g.nodes()) + { + if(node && in_place_nodes.find(node->type()) != std::end(in_place_nodes)) + { + // Get input edge + Edge *input_edge = node->input_edge(0); + + // Check if parent has a single output if yes then force in place calculation else not + if((input_edge != nullptr) && (input_edge->producer() != nullptr) && (input_edge->producer()->output_edges().size() == 1)) + { + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Switching to in-place computation for the node with ID : " + << node->id() << " and name : " << node->name() << std::endl); + // Update output + auto tensor = input_edge->tensor(); + node->set_output_tensor(tensor->id(), 0); + } + } + } +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/mutators/NodeFusionMutator.cpp b/src/graph/mutators/NodeFusionMutator.cpp new file mode 100644 index 0000000000..2e893c2e07 --- /dev/null +++ b/src/graph/mutators/NodeFusionMutator.cpp @@ -0,0 +1,96 @@ +/* + * 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. + */ +#include "arm_compute/graph/mutators/NodeFusionMutator.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/nodes/Nodes.h" + +#include "arm_compute/core/utils/misc/Cast.h" + +namespace arm_compute +{ +namespace graph +{ +namespace detail +{ +void fuse_batch_norm_with_activation(Graph &g) +{ + // Not interested in the order of nodes + for(auto &node : g.nodes()) + { + // Check if the node is batch norm and not a branching node + if(node && node->type() == NodeType::BatchNormalizationLayer && node->output_edges().size() == 1) + { + auto output_edge_id = *node->output_edges().begin(); + auto output_edge = g.edge(output_edge_id); + // Check if following node is an activation layer node + if((output_edge != nullptr) && (output_edge->consumer() != nullptr) && (output_edge->consumer()->type() == NodeType::ActivationLayer)) + { + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Fusing Batch Normalization node with ID : " << output_edge->producer_id() + << " with Activation Layer node with ID : " << output_edge->consumer_id() << std::endl); + + auto *bn_node = arm_compute::utils::cast::polymorphic_downcast(output_edge->producer()); + auto *act_node = arm_compute::utils::cast::polymorphic_downcast(output_edge->consumer()); + + // Get driving nodes of activation node + std::vector act_driving_nodes; + for(auto &act_output_edge_id : act_node->output_edges()) + { + auto act_output_edge = g.edge(act_output_edge_id); + if(act_output_edge != nullptr) + { + ARM_COMPUTE_ERROR_ON(act_output_edge->consumer() == nullptr); + act_driving_nodes.push_back({ act_output_edge->consumer_id(), act_output_edge->consumer_idx() }); + } + } + + // Set activation info to batch normalization + bn_node->set_fused_activation(act_node->activation_info()); + + // Remove activation node + g.remove_node(act_node->id()); + + // Update batch normalization node outputs + for(auto &driving_node : act_driving_nodes) + { + g.add_connection(bn_node->id(), 0, driving_node.node_id, driving_node.index); + } + } + } + } +} +} // namespace detail + +const char *NodeFusionMutator::name() +{ + return "NodeFusionMutator"; +} + +void NodeFusionMutator::mutate(Graph &g) +{ + detail::fuse_batch_norm_with_activation(g); +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/mutators/SplitLayerSubTensorMutator.cpp b/src/graph/mutators/SplitLayerSubTensorMutator.cpp new file mode 100644 index 0000000000..179a6c35fb --- /dev/null +++ b/src/graph/mutators/SplitLayerSubTensorMutator.cpp @@ -0,0 +1,89 @@ +/* + * 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. + */ +#include "arm_compute/graph/mutators/SplitLayerSubTensorMutator.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Logger.h" +#include "arm_compute/graph/backends/BackendRegistry.h" +#include "arm_compute/graph/nodes/SplitLayerNode.h" + +#include "arm_compute/core/utils/misc/Cast.h" +#include "arm_compute/core/utils/misc/Iterable.h" + +namespace arm_compute +{ +namespace graph +{ +const char *SplitLayerSubTensorMutator::name() +{ + return "SplitLayerSubTensorMutator"; +} + +void SplitLayerSubTensorMutator::mutate(Graph &g) +{ + // Should be in reverse order of execution + for(auto &node : arm_compute::utils::iterable::reverse_iterate(g.nodes())) + { + if(node && node->type() == NodeType::SplitLayer && node->input(0) != nullptr) + { + // Get output tensor + Tensor *input_tensor = node->input(0); + + // Check that all tensor have the same target and are valid + bool is_valid = std::all_of(node->outputs().cbegin(), node->outputs().cend(), + [&](const TensorID & tid) + { + return (g.tensor(tid) != nullptr) && (g.tensor(tid)->desc().target == input_tensor->desc().target); + }); + + // Create subtensors + if(is_valid && backends::BackendRegistry::get().find_backend(input_tensor->desc().target) != nullptr) + { + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Using sub-tensors for the node with ID : " + << node->id() << " and name : " << node->name() << std::endl); + + auto *split_node = arm_compute::utils::cast::polymorphic_downcast(node.get()); + + const unsigned int axis = split_node->axis(); + const unsigned int num_splits = split_node->num_splits(); + const bool extend_parent = (axis < 2); + + // Create sub-tensor handles + for(unsigned int i = 0; i < node->outputs().size(); ++i) + { + Tensor *output_tensor = node->output(i); + const TensorShape output_shape = output_tensor->desc().shape; + Coordinates coords; + std::tie(std::ignore, coords) = SplitLayerNode::compute_output_shape(input_tensor->desc().shape, num_splits, axis, i); + + backends::IDeviceBackend *backend = backends::BackendRegistry::get().find_backend(output_tensor->desc().target); + std::unique_ptr handle = backend->create_subtensor(input_tensor->handle(), output_shape, coords, extend_parent); + output_tensor->set_handle(std::move(handle)); + } + } + } + } +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/nodes/ActivationLayer.cpp b/src/graph/nodes/ActivationLayer.cpp deleted file mode 100644 index 546c42a1e5..0000000000 --- a/src/graph/nodes/ActivationLayer.cpp +++ /dev/null @@ -1,56 +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. - */ -#include "arm_compute/graph/nodes/ActivationLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -ActivationLayer::ActivationLayer(const ActivationLayerInfo activation_info) - : _activation_info(activation_info) -{ - set_supports_in_place(true); -} - -std::unique_ptr ActivationLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::ActivationLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - node_ctx.add_parameter("ActivationLayerInfo", _activation_info); - - // Get function - return OperationRegistry::get().find_operation(OperationType::ActivationLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/ActivationLayerNode.cpp b/src/graph/nodes/ActivationLayerNode.cpp new file mode 100644 index 0000000000..9996d2ce3f --- /dev/null +++ b/src/graph/nodes/ActivationLayerNode.cpp @@ -0,0 +1,83 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/ActivationLayerNode.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +ActivationLayerNode::ActivationLayerNode(ActivationLayerInfo info) + : _info(info) +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +ActivationLayerInfo ActivationLayerNode::activation_info() const +{ + return _info; +} + +bool ActivationLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor ActivationLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + return src->desc(); +} + +Status ActivationLayerNode::validate() +{ + return Status{}; +} + +NodeType ActivationLayerNode::type() const +{ + return NodeType::ActivationLayer; +} + +void ActivationLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/BatchNormalizationLayer.cpp b/src/graph/nodes/BatchNormalizationLayer.cpp deleted file mode 100644 index 24287ac61a..0000000000 --- a/src/graph/nodes/BatchNormalizationLayer.cpp +++ /dev/null @@ -1,105 +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. - */ -#include "arm_compute/graph/nodes/BatchNormalizationLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -std::unique_ptr BatchNormalizationLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - unsigned int batch_norm_size = in->info()->dimension(2); - if(_mean.tensor() == nullptr) - { - _mean.set_info(TensorInfo(TensorShape(batch_norm_size), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position())); - } - if(_var.tensor() == nullptr) - { - _var.set_info(TensorInfo(TensorShape(batch_norm_size), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position())); - } - if(_beta.tensor() == nullptr) - { - _beta.set_info(TensorInfo(TensorShape(batch_norm_size), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position())); - } - if(_gamma.tensor() == nullptr) - { - _gamma.set_info(TensorInfo(TensorShape(batch_norm_size), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position())); - } - - bool mean_is_loaded = _mean.tensor() != nullptr; - bool var_is_loaded = _var.tensor() != nullptr; - bool gamma_is_loaded = _gamma.tensor() != nullptr; - bool beta_is_loaded = _beta.tensor() != nullptr; - - // Set mean, var, gamma and beta target - _mean.set_target(_target_hint); - _var.set_target(_target_hint); - _gamma.set_target(_target_hint); - _beta.set_target(_target_hint); - - // Create node context - NodeContext node_ctx(OperationType::BatchNormalizationLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_input(_mean.tensor()); - node_ctx.add_input(_var.tensor()); - node_ctx.add_input(_beta.tensor()); - node_ctx.add_input(_gamma.tensor()); - node_ctx.add_output(out); - node_ctx.add_parameter("epsilon", _epsilon); - node_ctx.add_parameter("act_info", _act_info); - - // Configure operation - auto func = OperationRegistry::get().find_operation(OperationType::BatchNormalizationLayer, _target_hint)->configure(node_ctx); - - // Fill tensors - if(!mean_is_loaded) - { - _mean.allocate_and_fill_if_needed(); - } - if(!var_is_loaded) - { - _var.allocate_and_fill_if_needed(); - } - if(!gamma_is_loaded) - { - _gamma.allocate_and_fill_if_needed(); - } - if(!beta_is_loaded) - { - _beta.allocate_and_fill_if_needed(); - } - - // Get function - return func; -} \ No newline at end of file diff --git a/src/graph/nodes/BatchNormalizationLayerNode.cpp b/src/graph/nodes/BatchNormalizationLayerNode.cpp new file mode 100644 index 0000000000..f7b041c828 --- /dev/null +++ b/src/graph/nodes/BatchNormalizationLayerNode.cpp @@ -0,0 +1,94 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/BatchNormalizationLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +BatchNormalizationLayerNode::BatchNormalizationLayerNode(float epsilon, ActivationLayerInfo fused_activation) + : _epsilon(epsilon), _fused_activation(fused_activation) +{ + _input_edges.resize(5, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +float BatchNormalizationLayerNode::epsilon() const +{ + return _epsilon; +} + +ActivationLayerInfo BatchNormalizationLayerNode::fused_activation() const +{ + return _fused_activation; +} + +void BatchNormalizationLayerNode::set_fused_activation(ActivationLayerInfo fused_activation) +{ + _fused_activation = fused_activation; +} + +bool BatchNormalizationLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor BatchNormalizationLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + return src->desc(); +} + +Status BatchNormalizationLayerNode::validate() +{ + return Status{}; +} + +NodeType BatchNormalizationLayerNode::type() const +{ + return NodeType::BatchNormalizationLayer; +} + +void BatchNormalizationLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/BranchLayer.cpp b/src/graph/nodes/BranchLayer.cpp deleted file mode 100644 index 7a20a565b8..0000000000 --- a/src/graph/nodes/BranchLayer.cpp +++ /dev/null @@ -1,130 +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. - */ -#include "arm_compute/graph/nodes/BranchLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/SubGraph.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/runtime/IFunction.h" -#include "support/ToolchainSupport.h" -#include "utils/TypePrinter.h" - -#include -#include -#include - -using namespace arm_compute::graph; - -/** Branch function */ -class BranchFunction final : public arm_compute::IFunction -{ -public: - /** Default Constructor */ - BranchFunction() - : _graphs() - { - } - /** Registers graph to be executed by the branch function - * - * @param[in] graph Graph to register - */ - void register_graph(std::unique_ptr graph) - { - _graphs.push_back(std::move(graph)); - } - // Inherited methods overriden: - void run() override - { - for(auto &g : _graphs) - { - ARM_COMPUTE_ERROR_ON(g.get() == nullptr); - g->run(); - } - } - -private: - std::vector> _graphs; -}; - -std::unique_ptr BranchLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON(_branch_merge_method != BranchMergeMethod::DEPTH_CONCATENATE); - ARM_COMPUTE_UNUSED(_branch_merge_method); - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - // Create branch function - auto func = arm_compute::support::cpp14::make_unique(); - - // Track output depth - int depth = 0; - - // Constuct all sub-graphs given the input/output - for(auto &sg : _sub_graphs) - { - ARM_COMPUTE_ERROR_ON(sg.get() == nullptr); - - // IO buffers - std::unique_ptr in; - std::unique_ptr out; - SubTensor *out_sub_tensor = nullptr; - - // Create input sub-tensor - if(!sg->has_input()) - { - ARM_COMPUTE_ERROR_ON(dynamic_cast(input) == nullptr); - in = arm_compute::support::cpp14::make_unique(*dynamic_cast(input), - input->tensor()->info()->tensor_shape(), - Coordinates()); - } - - // Create output sub-tensor - if(!sg->has_output()) - { - ARM_COMPUTE_ERROR_ON((dynamic_cast(output) == nullptr) && (dynamic_cast(output) == nullptr)); - - out = arm_compute::support::cpp14::make_unique(output->tensor(), - TensorShape(), - Coordinates(0, 0, depth), - output->target(), - true); - out_sub_tensor = dynamic_cast(out.get()); - } - - // Construct sub_graph - auto g = sg->construct(ctx, std::move(in), std::move(out)); - - // Register graph to function - func->register_graph(std::move(g)); - - // Update and track depth - if(out_sub_tensor != nullptr) - { - ARM_COMPUTE_ERROR_ON(out_sub_tensor->tensor() == nullptr); - depth += out_sub_tensor->tensor()->info()->tensor_shape()[2]; - } - } - - return std::move(func); -} \ No newline at end of file diff --git a/src/graph/nodes/ConstNode.cpp b/src/graph/nodes/ConstNode.cpp new file mode 100644 index 0000000000..631971c98f --- /dev/null +++ b/src/graph/nodes/ConstNode.cpp @@ -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. + */ +#include "arm_compute/graph/nodes/ConstNode.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +ConstNode::ConstNode(TensorDescriptor desc) + : _desc(desc) +{ + _outputs.resize(1, NullTensorID); +} + +bool ConstNode::forward_descriptors() +{ + if(output_id(0) != NullTensorID) + { + Tensor *t = output(0); + ARM_COMPUTE_ERROR_ON(t == nullptr); + t->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor ConstNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + return _desc; +} + +Status ConstNode::validate() +{ + return Status{}; +} + +NodeType ConstNode::type() const +{ + return NodeType::Const; +} + +void ConstNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/nodes/ConvolutionLayer.cpp b/src/graph/nodes/ConvolutionLayer.cpp deleted file mode 100644 index 5b3a84a4ad..0000000000 --- a/src/graph/nodes/ConvolutionLayer.cpp +++ /dev/null @@ -1,363 +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. - */ -#include "arm_compute/graph/nodes/ConvolutionLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h" -#include "arm_compute/runtime/CL/functions/CLDirectConvolutionLayer.h" -#include "arm_compute/runtime/CL/functions/CLWinogradConvolutionLayer.h" -#include "arm_compute/runtime/IFunction.h" -#include "arm_compute/runtime/NEON/functions/NEConvolutionLayer.h" -#include "arm_compute/runtime/NEON/functions/NEDirectConvolutionLayer.h" -#include "arm_compute/runtime/NEON/functions/NEWinogradLayer.h" -#include "support/ToolchainSupport.h" -#include "utils/GraphTypePrinter.h" -#include "utils/TypePrinter.h" - -#include -#include - -using namespace arm_compute::graph; - -namespace -{ -/** Calculates the output shaped of the convolution layer - * - * @param[in] input_shape Input tensor shape - * @param[in] weights_shape Weights shape - * @param[in] conv_info Convolution information (padding, stride, etc.) - * - * @return The expected output tensor shape - */ -TensorShape calculate_convolution_layer_output_shape(const TensorShape &input_shape, const TensorShape &weights_shape, const PadStrideInfo &conv_info) -{ - unsigned int output_width = 0; - unsigned int output_height = 0; - - // Get output width and height - std::tie(output_width, output_height) = arm_compute::scaled_dimensions(input_shape.x(), input_shape.y(), weights_shape.x(), weights_shape.y(), conv_info); - - // Create output shape - TensorShape output_shape = input_shape; - output_shape.set(0, output_width); - output_shape.set(1, output_height); - output_shape.set(2, weights_shape[3]); - - return output_shape; -} - -// Instantiate GEMM based convolution layer -template -std::unique_ptr instantiate_function(arm_compute::ITensor *input, arm_compute::ITensor *weights, arm_compute::ITensor *biases, arm_compute::ITensor *output, - const PadStrideInfo &conv_info, const WeightsInfo &weights_info) -{ - auto conv = arm_compute::support::cpp14::make_unique(); - conv->configure( - dynamic_cast(input), - dynamic_cast(weights), - dynamic_cast(biases), - dynamic_cast(output), - conv_info, weights_info); - return std::move(conv); -} - -// Instantiate direct convolution layer -template -std::unique_ptr instantiate_direct_function(arm_compute::ITensor *input, arm_compute::ITensor *weights, arm_compute::ITensor *biases, arm_compute::ITensor *output, - const PadStrideInfo &conv_info) -{ - auto conv = arm_compute::support::cpp14::make_unique(); - conv->configure( - dynamic_cast(input), - dynamic_cast(weights), - dynamic_cast(biases), - dynamic_cast(output), - conv_info); - return std::move(conv); -} - -template -std::unique_ptr instantiate(arm_compute::ITensor *input, arm_compute::ITensor *weights, arm_compute::ITensor *biases, arm_compute::ITensor *output, - const PadStrideInfo &conv_info, const WeightsInfo &weights_info, - ConvolutionMethodHint conv_method); - -template <> -std::unique_ptr instantiate(arm_compute::ITensor *input, arm_compute::ITensor *weights, arm_compute::ITensor *biases, arm_compute::ITensor *output, - const PadStrideInfo &conv_info, - const WeightsInfo &weights_info, - ConvolutionMethodHint conv_method) -{ - if((conv_method == ConvolutionMethodHint::WINOGRAD) - && arm_compute::CLWinogradConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT - { - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLWinogradConvolutionLayer"); - return instantiate_direct_function(input, weights, biases, output, conv_info); - } - else if((conv_method == ConvolutionMethodHint::DIRECT) - && arm_compute::CLDirectConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT - { - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDirectConvolutionLayer"); - return instantiate_direct_function(input, weights, biases, output, conv_info); - } - else - { - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLConvolutionLayer"); - return instantiate_function(input, weights, biases, output, conv_info, weights_info); - } -} - -template <> -std::unique_ptr instantiate(arm_compute::ITensor *input, arm_compute::ITensor *weights, arm_compute::ITensor *biases, arm_compute::ITensor *output, - const PadStrideInfo &conv_info, - const WeightsInfo &weights_info, - ConvolutionMethodHint conv_method) -{ - const unsigned int kernel_size_x = weights->info()->tensor_shape().x(); - const unsigned int kernel_size_y = weights->info()->tensor_shape().y(); - const unsigned int conv_stride_x = conv_info.stride().first; - const unsigned int conv_stride_y = conv_info.stride().second; - - bool is_square_kernel = (kernel_size_x == kernel_size_y); - bool has_same_stride = (conv_stride_x == conv_stride_y); - - // TODO (COMPID-765) : Winograd should have a validate function - if(conv_method == ConvolutionMethodHint::WINOGRAD && is_square_kernel && ((kernel_size_x == 3) || (kernel_size_x == 5)) && has_same_stride && (conv_info.stride().first == 1)) - { - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEWinogradConvolutionLayer"); - return instantiate_direct_function(input, weights, biases, output, conv_info); - } - else if((conv_method == ConvolutionMethodHint::DIRECT) - && arm_compute::NEDirectConvolutionLayer::validate(input->info(), weights->info(), biases != nullptr ? biases->info() : nullptr, output->info(), conv_info)) // NOLINT - { - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEDirectConvolutionLayer"); - return instantiate_direct_function(input, weights, biases, output, conv_info); - } - else - { - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEConvolutionLayer"); - return instantiate_function(input, weights, biases, output, conv_info, weights_info); - } -} -} // namespace - -/** Grouped Convolution function */ -class GroupedConvolutionFunction final : public arm_compute::IFunction -{ -public: - /** Default Constructor */ - GroupedConvolutionFunction() = default; - /** Default Destructor */ - ~GroupedConvolutionFunction() final = default; - /** Prevent instances from being copy constructed */ - GroupedConvolutionFunction(const GroupedConvolutionFunction &) = delete; - /** Prevent instances from being copy assigned */ - GroupedConvolutionFunction &operator=(const GroupedConvolutionFunction &) = delete; - /** Allow instances to be move constructed */ - GroupedConvolutionFunction(GroupedConvolutionFunction &&) noexcept = default; - /** Allow instances to be move assigned */ - GroupedConvolutionFunction &operator=(GroupedConvolutionFunction &&) noexcept = default; - /** Adds a convolution - * - * @param convolution Convolution function to add - */ - void add_convolution_function(std::unique_ptr convolution) // NOLINT - { - _convolutions.emplace_back(std::move(convolution)); - } - - // Inherited methods overridden: - void run() override - { - for(auto &c : _convolutions) - { - c->run(); - } - } - -private: - std::vector> _convolutions{}; -}; - -std::unique_ptr ConvolutionLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - - // Set weights and biases info - if(_weights.tensor() == nullptr) - { - TensorInfo info = TensorInfo(TensorShape(_conv_width, _conv_height, in->info()->dimension(2) / _num_groups, _ofm), - in->info()->num_channels(), - in->info()->data_type(), - in->info()->fixed_point_position()); - info.set_quantization_info(_weights_quant_info); - _weights.set_info(std::move(info)); - } - if(_biases.has_accessor() && _biases.tensor() == nullptr) - { - DataType dt = in->info()->data_type(); - _biases.set_info(TensorInfo(TensorShape(_ofm), in->info()->num_channels(), is_data_type_quantized_asymmetric(dt) ? DataType::S32 : dt, in->info()->fixed_point_position())); - } - - std::unique_ptr func; - _target_hint = ctx.hints().target_hint(); - const ConvolutionMethodHint conv_method_hint = ctx.hints().convolution_method_hint(); - - // Check if the weights and biases are loaded - bool weights_are_loaded = _weights.tensor() != nullptr; - bool biases_are_loaded = _biases.has_accessor() ? _biases.tensor() != nullptr : true; - - // Set bias and weights target - _weights.set_target(_target_hint); - if(_biases.has_accessor()) - { - _biases.set_target(_target_hint); - } - - // Calculate output shape - TensorShape output_shape = calculate_convolution_layer_output_shape(in->info()->tensor_shape(), _weights.info().tensor_shape(), _conv_info); - - // Output auto inizialitation if not yet initialized - arm_compute::auto_init_if_empty(*out->info(), output_shape, 1, in->info()->data_type(), in->info()->fixed_point_position(), - (_out_quant_info.empty()) ? in->info()->quantization_info() : _out_quant_info); - - // Create appropriate convolution function - if(_num_groups == 1) - { - func = instantiate_convolution(in, out, conv_method_hint); - } - else - { - func = instantiate_grouped_convolution(in, out, conv_method_hint); - } - - // Fill weights - if(!weights_are_loaded) - { - _weights.allocate_and_fill_if_needed(); - } - // Fill biases - if(!biases_are_loaded) - { - _biases.allocate_and_fill_if_needed(); - } - - ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() - << " Input Shape: " << in->info()->tensor_shape() - << " Weights shape: " << _weights.info().tensor_shape() - << " Biases Shape: " << _biases.info().tensor_shape() - << " Output Shape: " << out->info()->tensor_shape() - << " PadStrideInfo: " << _conv_info - << " Groups: " << _num_groups - << " WeightsInfo: " << _weights_info - << std::endl); - - return func; -} - -std::unique_ptr ConvolutionLayer::instantiate_convolution(ITensor *input, ITensor *output, ConvolutionMethodHint conv_method_hint) -{ - std::unique_ptr func; - if(_target_hint == TargetHint::OPENCL) - { - func = instantiate(input, _weights.tensor(), _biases.tensor(), output, _conv_info, _weights_info, conv_method_hint); - } - else - { - func = instantiate(input, _weights.tensor(), _biases.tensor(), output, _conv_info, _weights_info, conv_method_hint); - } - return func; -} - -std::unique_ptr ConvolutionLayer::instantiate_grouped_convolution(ITensor *input, ITensor *output, ConvolutionMethodHint conv_method_hint) -{ - // Get tensor shapes - TensorShape input_shape = input->info()->tensor_shape(); - TensorShape output_shape = output->info()->tensor_shape(); - TensorShape weights_shape = _weights.info().tensor_shape(); - TensorShape biases_shape = _biases.info().tensor_shape(); - - ARM_COMPUTE_ERROR_ON_MSG((input_shape.z() % _num_groups) != 0, "Input depth not multiple of the number of groups!"); - ARM_COMPUTE_ERROR_ON_MSG((output_shape.z() % _num_groups) != 0, "Output depth not multiple of the number of groups!"); - ARM_COMPUTE_ERROR_ON_MSG((weights_shape[3] % _num_groups) != 0, "Number of kernels not multiple of the number of groups!"); - ARM_COMPUTE_ERROR_ON_MSG((biases_shape.x() % _num_groups) != 0, "Biases not multiple of the number of groups!"); - - // Create a grouped convolution function - auto grouped_conv = arm_compute::support::cpp14::make_unique(); - - // Create sub-tensors vectors - _is = arm_compute::support::cpp14::make_unique(_num_groups); - _os = arm_compute::support::cpp14::make_unique(_num_groups); - _ws = arm_compute::support::cpp14::make_unique(_num_groups); - _bs = arm_compute::support::cpp14::make_unique(_num_groups); - - // Calculate sub-tensor splits - const int input_split = input_shape.z() / _num_groups; - const int output_split = output_shape.z() / _num_groups; - const int weights_split = weights_shape[3] / _num_groups; - const int biases_split = biases_shape.x() / _num_groups; - - // Calculate sub-tensor shapes - input_shape.set(2, input_split); - output_shape.set(2, output_split); - weights_shape.set(3, weights_split); - biases_shape.set(0, biases_split); - - // Configure sub-tensors - for(int i = 0; i < static_cast(_num_groups); ++i) - { - // Create convolution function - std::unique_ptr func; - - // Calculate sub-tensors starting coordinates - Coordinates input_coord(0, 0, input_split * i); - Coordinates output_coord(0, 0, output_split * i); - Coordinates weights_coord(0, 0, 0, weights_split * i); - Coordinates biases_coord(biases_split * i); - - // Create sub-tensors for input, output, weights and bias - auto hint_to_use = (_target_hint == TargetHint::OPENCL) ? TargetHint::OPENCL : TargetHint::NEON; - _is[i] = SubTensor(input, input_shape, input_coord, hint_to_use); - _os[i] = SubTensor(output, output_shape, output_coord, hint_to_use); - _ws[i] = SubTensor(_weights.tensor(), weights_shape, weights_coord, hint_to_use); - _bs[i] = SubTensor(_biases.tensor(), biases_shape, biases_coord, hint_to_use); - - // Instantiate convolution function - if(_target_hint == TargetHint::OPENCL) - { - func = instantiate(_is[i].tensor(), _ws[i].tensor(), _bs[i].tensor(), _os[i].tensor(), _conv_info, _weights_info, conv_method_hint); - } - else - { - func = instantiate(_is[i].tensor(), _ws[i].tensor(), _bs[i].tensor(), _os[i].tensor(), _conv_info, _weights_info, conv_method_hint); - } - - // Add convolution function to the list of convolutions for the grouped convolution - grouped_conv->add_convolution_function(std::move(func)); - } - - return std::move(grouped_conv); -} diff --git a/src/graph/nodes/ConvolutionLayerNode.cpp b/src/graph/nodes/ConvolutionLayerNode.cpp new file mode 100644 index 0000000000..461728487f --- /dev/null +++ b/src/graph/nodes/ConvolutionLayerNode.cpp @@ -0,0 +1,111 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/ConvolutionLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +ConvolutionLayerNode::ConvolutionLayerNode(PadStrideInfo info, ConvolutionMethod method) + : _info(std::move(info)), _method(method) +{ + _input_edges.resize(3, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +void ConvolutionLayerNode::set_convolution_method(ConvolutionMethod method) +{ + _method = method; +} + +ConvolutionMethod ConvolutionLayerNode::convolution_method() const +{ + return _method; +} + +PadStrideInfo ConvolutionLayerNode::convolution_info() const +{ + return _info; +} + +TensorShape ConvolutionLayerNode::compute_output_shape(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo info) +{ + unsigned int output_width = 0; + unsigned int output_height = 0; + std::tie(output_width, output_height) = scaled_dimensions(input_shape.x(), input_shape.y(), weights_shape.x(), weights_shape.y(), info); + + TensorShape output_shape{ input_shape }; + output_shape.set(0, output_width); + output_shape.set(1, output_height); + output_shape.set(2, weights_shape[3]); + + return output_shape; +} + +bool ConvolutionLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (input_id(1) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor ConvolutionLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + const Tensor *src = input(0); + const Tensor *weights = input(1); + + ARM_COMPUTE_ERROR_ON(src == nullptr || weights == nullptr); + + TensorDescriptor output_info = src->desc(); + TensorShape output_shape = compute_output_shape(src->desc().shape, weights->desc().shape, _info); + output_info.shape = output_shape; + return output_info; +} + +Status ConvolutionLayerNode::validate() +{ + return Status{}; +} + +NodeType ConvolutionLayerNode::type() const +{ + return NodeType::ConvolutionLayer; +} + +void ConvolutionLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/DeQuantizationLayer.cpp b/src/graph/nodes/DeQuantizationLayer.cpp deleted file mode 100644 index af9ecee157..0000000000 --- a/src/graph/nodes/DeQuantizationLayer.cpp +++ /dev/null @@ -1,68 +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. - */ -#include "arm_compute/graph/nodes/DequantizationLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" - -using namespace arm_compute::graph; - -std::unique_ptr DequantizationLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - _target_hint = ctx.hints().target_hint(); - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - - if(_min_max.tensor() == nullptr) - { - TensorShape shape = in->info()->tensor_shape(); - shape.set(Window::DimX, 2); - shape.remove_dimension(1); - shape.remove_dimension(1); - - _min_max.set_info(TensorInfo(shape, in->info()->num_channels(), DataType::F32)); - _min_max.set_target(_target_hint); - } - - bool minmax_is_loaded = _min_max.tensor() != nullptr; - - // Create node context - NodeContext node_ctx(OperationType::DequantizationLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(_min_max.tensor()); - node_ctx.add_output(out); - - // Fill min max - if(!minmax_is_loaded) - { - _min_max.allocate_and_fill_if_needed(); - } - - // Get function - return OperationRegistry::get().find_operation(OperationType::DequantizationLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/DepthConcatenateLayerNode.cpp b/src/graph/nodes/DepthConcatenateLayerNode.cpp new file mode 100644 index 0000000000..1c0539744f --- /dev/null +++ b/src/graph/nodes/DepthConcatenateLayerNode.cpp @@ -0,0 +1,133 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/DepthConcatenateLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +DepthConcatenateLayerNode::DepthConcatenateLayerNode(unsigned int total_nodes) + : _total_nodes(total_nodes), _is_enabled(true) +{ + _input_edges.resize(total_nodes, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +void DepthConcatenateLayerNode::set_enabled(bool is_enabled) +{ + _is_enabled = is_enabled; +} + +bool DepthConcatenateLayerNode::is_enabled() const +{ + return _is_enabled; +} + +TensorShape DepthConcatenateLayerNode::compute_output_shape(const std::vector &input_shapes) +{ + ARM_COMPUTE_ERROR_ON(input_shapes.size() == 0); + + TensorShape output_shape = input_shapes[0]; + + size_t max_x = 0; + size_t max_y = 0; + size_t depth = 0; + + for(const auto &shape : input_shapes) + { + max_x = std::max(shape.x(), max_x); + max_y = std::max(shape.y(), max_y); + depth += shape.z(); + } + + output_shape.set(0, max_x); + output_shape.set(1, max_y); + output_shape.set(2, depth); + + return output_shape; +} + +bool DepthConcatenateLayerNode::forward_descriptors() +{ + if(_outputs[0] != NullTensorID) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor DepthConcatenateLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + // Check if all input tensors are set + bool are_all_inputs_set = std::all_of(std::begin(_input_edges), std::end(_input_edges), [](const EdgeID & eid) + { + return eid != EmptyEdgeID; + }); + + TensorDescriptor output_info = {}; + + if(are_all_inputs_set) + { + std::vector inputs_shapes; + for(unsigned int i = 0; i < _input_edges.size(); ++i) + { + const Tensor *t = _graph->tensor(input_id(i)); + ARM_COMPUTE_ERROR_ON(t == nullptr); + inputs_shapes.push_back(t->desc().shape); + } + output_info = input(0)->desc(); + TensorShape output_shape = compute_output_shape(inputs_shapes); + output_info.shape = output_shape; + } + + return output_info; +} + +Status DepthConcatenateLayerNode::validate() +{ + ARM_COMPUTE_UNUSED(_total_nodes); + return Status{}; +} + +NodeType DepthConcatenateLayerNode::type() const +{ + return NodeType::DepthConcatenateLayer; +} + +void DepthConcatenateLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/DepthConvertLayer.cpp b/src/graph/nodes/DepthConvertLayer.cpp deleted file mode 100644 index 9b328e7b3e..0000000000 --- a/src/graph/nodes/DepthConvertLayer.cpp +++ /dev/null @@ -1,58 +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. - */ -#include "arm_compute/graph/nodes/DepthConvertLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" - -using namespace arm_compute::graph; - -DepthConvertLayer::DepthConvertLayer(const ConvertPolicy policy, uint32_t shift, DataType output_datatype) - : _policy(policy), _shift(shift), _output_datatype(output_datatype) -{ -} - -std::unique_ptr DepthConvertLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - _target_hint = ctx.hints().target_hint(); - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - - // Auto configure output - arm_compute::auto_init_if_empty(*out->info(), in->info()->tensor_shape(), 1, _output_datatype, in->info()->fixed_point_position()); - - // Create node context - NodeContext node_ctx(OperationType::DepthConvertLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - node_ctx.add_parameter("ConvertPolicy", _policy); - node_ctx.add_parameter("shift", _shift); - - // Get function - return OperationRegistry::get().find_operation(OperationType::DepthConvertLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/DepthwiseConvolutionLayer.cpp b/src/graph/nodes/DepthwiseConvolutionLayer.cpp deleted file mode 100644 index e5101cc33c..0000000000 --- a/src/graph/nodes/DepthwiseConvolutionLayer.cpp +++ /dev/null @@ -1,91 +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. - */ -#include "arm_compute/graph/nodes/DepthwiseConvolutionLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -std::unique_ptr DepthwiseConvolutionLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - if(_weights.tensor() == nullptr) - { - TensorShape weights_shape(_conv_width, _conv_height, input->tensor()->info()->tensor_shape().z()); - TensorInfo info = TensorInfo(TensorShape(weights_shape), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position()); - info.set_quantization_info(_quant_info); - _weights.set_info(std::move(info)); - } - if(_biases.has_accessor() && _biases.tensor() == nullptr) - { - DataType dt = in->info()->data_type(); - _biases.set_info(TensorInfo(TensorShape(in->info()->dimension(2)), in->info()->num_channels(), is_data_type_quantized_asymmetric(dt) ? DataType::S32 : dt, in->info()->fixed_point_position())); - } - - bool weights_is_loaded = _weights.tensor() != nullptr; - bool biases_is_loaded = _biases.has_accessor() ? _biases.tensor() != nullptr : true; - - _weights.set_target(_target_hint); - if(_biases.has_accessor()) - { - _biases.set_target(_target_hint); - } - - // Create node context - NodeContext node_ctx(OperationType::DepthwiseConvolutionLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_input(_weights.tensor()); - if(_biases.has_accessor()) - { - node_ctx.add_input(_biases.tensor()); - } - node_ctx.add_output(out); - node_ctx.add_parameter("ConvolutionInfo", _conv_info); - node_ctx.add_parameter("Optimized3x3", _opt3x3); - - // Configure operation - auto func = OperationRegistry::get().find_operation(OperationType::DepthwiseConvolutionLayer, _target_hint)->configure(node_ctx); - - // Fill tensors - if(!weights_is_loaded) - { - _weights.allocate_and_fill_if_needed(); - } - if(!biases_is_loaded) - { - _biases.allocate_and_fill_if_needed(); - } - - // Get function - return func; -} diff --git a/src/graph/nodes/DepthwiseConvolutionLayerNode.cpp b/src/graph/nodes/DepthwiseConvolutionLayerNode.cpp new file mode 100644 index 0000000000..67a39029e6 --- /dev/null +++ b/src/graph/nodes/DepthwiseConvolutionLayerNode.cpp @@ -0,0 +1,110 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/DepthwiseConvolutionLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +DepthwiseConvolutionLayerNode::DepthwiseConvolutionLayerNode(PadStrideInfo info, DepthwiseConvolutionMethod method) + : _info(std::move(info)), _method(method) +{ + _input_edges.resize(3, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +void DepthwiseConvolutionLayerNode::set_depthwise_convolution_method(DepthwiseConvolutionMethod method) +{ + _method = method; +} + +DepthwiseConvolutionMethod DepthwiseConvolutionLayerNode::depthwise_convolution_method() const +{ + return _method; +} + +PadStrideInfo DepthwiseConvolutionLayerNode::convolution_info() const +{ + return _info; +} + +TensorShape DepthwiseConvolutionLayerNode::compute_output_shape(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo info) +{ + unsigned int output_width = 0; + unsigned int output_height = 0; + std::tie(output_width, output_height) = scaled_dimensions(input_shape.x(), input_shape.y(), weights_shape.x(), weights_shape.y(), info); + + TensorShape output_shape{ input_shape }; + output_shape.set(0, output_width); + output_shape.set(1, output_height); + + return output_shape; +} + +bool DepthwiseConvolutionLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (input_id(1) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor DepthwiseConvolutionLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + const Tensor *src = input(0); + const Tensor *weights = input(1); + + ARM_COMPUTE_ERROR_ON(src == nullptr || weights == nullptr); + + TensorDescriptor output_info = src->desc(); + TensorShape output_shape = compute_output_shape(src->desc().shape, weights->desc().shape, _info); + output_info.shape = output_shape; + return output_info; +} + +Status DepthwiseConvolutionLayerNode::validate() +{ + return Status{}; +} + +NodeType DepthwiseConvolutionLayerNode::type() const +{ + return NodeType::DepthwiseConvolutionLayer; +} + +void DepthwiseConvolutionLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/EltwiseLayerNode.cpp b/src/graph/nodes/EltwiseLayerNode.cpp new file mode 100644 index 0000000000..b794043f2f --- /dev/null +++ b/src/graph/nodes/EltwiseLayerNode.cpp @@ -0,0 +1,83 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/EltwiseLayerNode.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +EltwiseLayerNode::EltwiseLayerNode(EltwiseOperation op) + : _op(op) +{ + _input_edges.resize(2, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +EltwiseOperation EltwiseLayerNode::eltwise_operation() const +{ + return _op; +} + +bool EltwiseLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor EltwiseLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_UNUSED(_op); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + return src->desc(); +} + +Status EltwiseLayerNode::validate() +{ + return Status{}; +} + +NodeType EltwiseLayerNode::type() const +{ + return NodeType::EltwiseLayer; +} + +void EltwiseLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/nodes/FlattenLayer.cpp b/src/graph/nodes/FlattenLayer.cpp deleted file mode 100644 index ea08296ba3..0000000000 --- a/src/graph/nodes/FlattenLayer.cpp +++ /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. - */ -#include "arm_compute/graph/nodes/FlattenLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -std::unique_ptr FlattenLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - _target_hint = ctx.hints().target_hint(); - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - - // Auto configure output - TensorShape tensor_shape = in->info()->tensor_shape(); - tensor_shape.collapse(in->info()->num_dimensions()); - arm_compute::auto_init_if_empty(*out->info(), tensor_shape, 1, in->info()->data_type(), in->info()->fixed_point_position()); - - // Create node context - NodeContext node_ctx(OperationType::FlattenLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - - // Get function - return OperationRegistry::get().find_operation(OperationType::FlattenLayer, _target_hint)->configure(node_ctx); -} \ No newline at end of file diff --git a/src/graph/nodes/FlattenLayerNode.cpp b/src/graph/nodes/FlattenLayerNode.cpp new file mode 100644 index 0000000000..8b847c7056 --- /dev/null +++ b/src/graph/nodes/FlattenLayerNode.cpp @@ -0,0 +1,80 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/FlattenLayerNode.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +FlattenLayerNode::FlattenLayerNode() +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +bool FlattenLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor FlattenLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + TensorDescriptor output_desc = src->desc(); + output_desc.shape.collapse(src->desc().shape.num_dimensions()); + + return output_desc; +} + +Status FlattenLayerNode::validate() +{ + return Status{}; +} + +NodeType FlattenLayerNode::type() const +{ + return NodeType::FlattenLayer; +} + +void FlattenLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/FloorLayer.cpp b/src/graph/nodes/FloorLayer.cpp deleted file mode 100644 index 8750546ed9..0000000000 --- a/src/graph/nodes/FloorLayer.cpp +++ /dev/null @@ -1,49 +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. - */ -#include "arm_compute/graph/nodes/FloorLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -std::unique_ptr FloorLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::FloorLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - - // Get function - return OperationRegistry::get().find_operation(OperationType::FloorLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/FullyConnectedLayer.cpp b/src/graph/nodes/FullyConnectedLayer.cpp index 3742150d37..cbf2b35ddd 100644 --- a/src/graph/nodes/FullyConnectedLayer.cpp +++ b/src/graph/nodes/FullyConnectedLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,18 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph/nodes/FullyConnectedLayer.h" +#include "arm_compute/graph/nodes/FullyConnectedLayerNode.h" -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" -using namespace arm_compute::graph; +namespace arm_compute +{ +namespace graph +{ +FullyConnectedLayerNode::FullyConnectedLayerNode(unsigned int num_outputs) + : _num_outputs(num_outputs) +{ + _input_edges.resize(3, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} -namespace +TensorShape FullyConnectedLayerNode::compute_weights_shape(TensorShape input_shape, unsigned int num_outputs) { -TensorShape calculate_fullyconnected_layer_output_shape(const TensorShape &input_shape, unsigned int output_neurons) + unsigned int num_weights = 1; + unsigned int num_dimensions = input_shape.num_dimensions(); + // Ignore the batch dimension if there is one: + if(num_dimensions == 2 || num_dimensions == 4) + { + num_dimensions--; + } + for(unsigned int i = 0; i < num_dimensions; i++) + { + num_weights *= input_shape[i]; + } + return TensorShape(num_weights, num_outputs); +} + +TensorShape FullyConnectedLayerNode::compute_output_shape(TensorShape input_shape, unsigned int num_outputs) { // Note: Only 1D batch space is supported at the moment unsigned int batches = input_shape[1]; @@ -40,67 +62,46 @@ TensorShape calculate_fullyconnected_layer_output_shape(const TensorShape &input { batches = input_shape[3]; } - return TensorShape(output_neurons, batches); + return TensorShape(num_outputs, batches); } -} // namespace -std::unique_ptr FullyConnectedLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) +bool FullyConnectedLayerNode::forward_descriptors() { - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - if(_weights.tensor() == nullptr) - { - unsigned int num_weights = 1; - unsigned int num_dimensions = in->info()->num_dimensions(); - // Ignore the batch dimension if there is one: - if(num_dimensions == 2 || num_dimensions == 4) - { - num_dimensions--; - } - for(unsigned int i = 0; i < num_dimensions; i++) - { - num_weights *= in->info()->dimension(i); - } - _weights.set_info(TensorInfo(TensorShape(num_weights, _num_neurons), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position())); - } - if(_biases.tensor() == nullptr) + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) { - _biases.set_info(TensorInfo(TensorShape(_num_neurons), in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position())); + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; } + return false; +} - // Auto configure output - arm_compute::auto_init_if_empty(*out->info(), - calculate_fullyconnected_layer_output_shape(in->info()->tensor_shape(), _num_neurons), - in->info()->num_channels(), in->info()->data_type(), in->info()->fixed_point_position()); - - bool weights_are_loaded = _weights.tensor() != nullptr; - bool biases_are_loaded = _biases.tensor() != nullptr; +TensorDescriptor FullyConnectedLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); - // Create node context - NodeContext node_ctx(OperationType::FullyConnectedLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_input(_weights.set_target(_target_hint)); - node_ctx.add_input(_biases.set_target(_target_hint)); - node_ctx.add_output(out); + TensorDescriptor output_info = src->desc(); + TensorShape output_shape = compute_output_shape(src->desc().shape, _num_outputs); + output_info.shape = output_shape; + return output_info; +} - // Configure operation - auto func = OperationRegistry::get().find_operation(OperationType::FullyConnectedLayer, _target_hint)->configure(node_ctx); +Status FullyConnectedLayerNode::validate() +{ + return Status{}; +} - // Fill biases - if(!weights_are_loaded) - { - _weights.allocate_and_fill_if_needed(); - } - if(!biases_are_loaded) - { - _biases.allocate_and_fill_if_needed(); - } +NodeType FullyConnectedLayerNode::type() const +{ + return NodeType::FullyConnectedLayer; +} - // Get function - return func; +void FullyConnectedLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); } +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/InputNode.cpp b/src/graph/nodes/InputNode.cpp new file mode 100644 index 0000000000..e912633a66 --- /dev/null +++ b/src/graph/nodes/InputNode.cpp @@ -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. + */ +#include "arm_compute/graph/nodes/InputNode.h" + +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +InputNode::InputNode(TensorDescriptor desc) + : _desc(desc) +{ + _outputs.resize(1, NullTensorID); +} + +bool InputNode::forward_descriptors() +{ + if(output_id(0) != NullTensorID) + { + Tensor *t = output(0); + ARM_COMPUTE_ERROR_ON(t == nullptr); + t->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor InputNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + return _desc; +} + +Status InputNode::validate() +{ + return Status{}; +} + +NodeType InputNode::type() const +{ + return NodeType::Input; +} + +void InputNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/nodes/L2NormalizeLayer.cpp b/src/graph/nodes/L2NormalizeLayer.cpp deleted file mode 100644 index 9813ba4450..0000000000 --- a/src/graph/nodes/L2NormalizeLayer.cpp +++ /dev/null @@ -1,56 +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. - */ -#include "arm_compute/graph/nodes/L2NormalizeLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -L2NormalizeLayer::L2NormalizeLayer(unsigned int axis, float epsilon) - : _axis(axis), _epsilon(epsilon) -{ -} - -std::unique_ptr L2NormalizeLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::L2NormalizeLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - node_ctx.add_parameter("axis", _axis); - node_ctx.add_parameter("epsilon", _epsilon); - - // Get function - return OperationRegistry::get().find_operation(OperationType::L2NormalizeLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/NormalizationLayer.cpp b/src/graph/nodes/NormalizationLayer.cpp deleted file mode 100644 index a489329243..0000000000 --- a/src/graph/nodes/NormalizationLayer.cpp +++ /dev/null @@ -1,55 +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. - */ -#include "arm_compute/graph/nodes/NormalizationLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -NormalizationLayer::NormalizationLayer(const NormalizationLayerInfo norm_info) - : _norm_info(norm_info) -{ -} - -std::unique_ptr NormalizationLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::NormalizationLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - node_ctx.add_parameter("NormalizationLayerInfo", _norm_info); - - // Get function - return OperationRegistry::get().find_operation(OperationType::NormalizationLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/NormalizationLayerNode.cpp b/src/graph/nodes/NormalizationLayerNode.cpp new file mode 100644 index 0000000000..a9f2fbd066 --- /dev/null +++ b/src/graph/nodes/NormalizationLayerNode.cpp @@ -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. + */ +#include "arm_compute/graph/nodes/NormalizationLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +NormalizationLayerNode::NormalizationLayerNode(NormalizationLayerInfo norm_info) + : _info(norm_info) +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +NormalizationLayerInfo NormalizationLayerNode::normalization_info() const +{ + return _info; +} + +bool NormalizationLayerNode::forward_descriptors() +{ + if(input_id(0) != NullTensorID && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor NormalizationLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + return src->desc(); +} + +Status NormalizationLayerNode::validate() +{ + return Status{}; +} + +NodeType NormalizationLayerNode::type() const +{ + return NodeType::NormalizationLayer; +} + +void NormalizationLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/OutputNode.cpp b/src/graph/nodes/OutputNode.cpp new file mode 100644 index 0000000000..4c63bfa20c --- /dev/null +++ b/src/graph/nodes/OutputNode.cpp @@ -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. + */ +#include "arm_compute/graph/nodes/OutputNode.h" + +#include "arm_compute/core/Error.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" +#include "arm_compute/graph/Tensor.h" + +namespace arm_compute +{ +namespace graph +{ +OutputNode::OutputNode() +{ + _input_edges.resize(1, EmptyEdgeID); +} + +bool OutputNode::forward_descriptors() +{ + return true; +} + +TensorDescriptor OutputNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + return TensorDescriptor(); +} + +Status OutputNode::validate() +{ + return Status{}; +} + +NodeType OutputNode::type() const +{ + return NodeType::Output; +} + +void OutputNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph/nodes/PoolingLayer.cpp b/src/graph/nodes/PoolingLayer.cpp deleted file mode 100644 index 2c151194f3..0000000000 --- a/src/graph/nodes/PoolingLayer.cpp +++ /dev/null @@ -1,55 +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. - */ -#include "arm_compute/graph/nodes/PoolingLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -PoolingLayer::PoolingLayer(const PoolingLayerInfo pool_info) - : _pool_info(pool_info) -{ -} - -std::unique_ptr PoolingLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::PoolingLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - node_ctx.add_parameter("PoolingLayerInfo", _pool_info); - - // Get function - return OperationRegistry::get().find_operation(OperationType::PoolingLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/PoolingLayerNode.cpp b/src/graph/nodes/PoolingLayerNode.cpp new file mode 100644 index 0000000000..a7b6b3679a --- /dev/null +++ b/src/graph/nodes/PoolingLayerNode.cpp @@ -0,0 +1,103 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/PoolingLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +PoolingLayerNode::PoolingLayerNode(PoolingLayerInfo pool_info) + : _info(std::move(pool_info)) +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +PoolingLayerInfo PoolingLayerNode::pooling_info() const +{ + return _info; +} + +TensorShape PoolingLayerNode::compute_output_shape(TensorShape input_shape, PoolingLayerInfo info) +{ + const int pool_size_x = info.is_global_pooling() ? input_shape.x() : info.pool_size().width; + const int pool_size_y = info.is_global_pooling() ? input_shape.y() : info.pool_size().height; + + unsigned int pooled_width = 0; + unsigned int pooled_height = 0; + std::tie(pooled_width, pooled_height) = scaled_dimensions(input_shape.x(), input_shape.y(), pool_size_x, pool_size_y, info.pad_stride_info()); + + TensorShape output_shape{ input_shape }; + output_shape.set(0, pooled_width); + output_shape.set(1, pooled_height); + + return output_shape; +} + +bool PoolingLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor PoolingLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + TensorDescriptor output_info = src->desc(); + TensorShape output_shape = compute_output_shape(src->desc().shape, _info); + output_info.shape = output_shape; + return output_info; +} + +Status PoolingLayerNode::validate() +{ + return Status{}; +} + +NodeType PoolingLayerNode::type() const +{ + return NodeType::PoolingLayer; +} + +void PoolingLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/QuantizationLayer.cpp b/src/graph/nodes/QuantizationLayer.cpp deleted file mode 100644 index c102f47633..0000000000 --- a/src/graph/nodes/QuantizationLayer.cpp +++ /dev/null @@ -1,48 +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. - */ -#include "arm_compute/graph/nodes/QuantizationLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" - -using namespace arm_compute::graph; - -std::unique_ptr QuantizationLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - _target_hint = ctx.hints().target_hint(); - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - - // Create node context - NodeContext node_ctx(OperationType::QuantizationLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - - // Get function - return OperationRegistry::get().find_operation(OperationType::QuantizationLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/ReshapeLayer.cpp b/src/graph/nodes/ReshapeLayer.cpp index b0c117e418..2757f06bd3 100644 --- a/src/graph/nodes/ReshapeLayer.cpp +++ b/src/graph/nodes/ReshapeLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -21,37 +21,61 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include "arm_compute/graph/nodes/ReshapeLayer.h" +#include "arm_compute/graph/nodes/ReshapeLayerNode.h" -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" -using namespace arm_compute::graph; - -ReshapeLayer::ReshapeLayer(TensorShape shape) +namespace arm_compute +{ +namespace graph +{ +ReshapeLayerNode::ReshapeLayerNode(TensorShape shape) : _shape(shape) { + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); } -std::unique_ptr ReshapeLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) +bool ReshapeLayerNode::forward_descriptors() { - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor ReshapeLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); - _target_hint = ctx.hints().target_hint(); - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); + TensorDescriptor output_desc = src->desc(); + output_desc.shape = _shape; - // Auto configure output - arm_compute::auto_init_if_empty(*out->info(), _shape, 1, in->info()->data_type(), in->info()->fixed_point_position(), in->info()->quantization_info()); + return output_desc; +} - // Create node context - NodeContext node_ctx(OperationType::ReshapeLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); +Status ReshapeLayerNode::validate() +{ + return Status{}; +} - // Get function - return OperationRegistry::get().find_operation(OperationType::ReshapeLayer, _target_hint)->configure(node_ctx); +NodeType ReshapeLayerNode::type() const +{ + return NodeType::ReshapeLayer; +} + +void ReshapeLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); } +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/ResidualLayer.cpp b/src/graph/nodes/ResidualLayer.cpp deleted file mode 100644 index 87404f9e1f..0000000000 --- a/src/graph/nodes/ResidualLayer.cpp +++ /dev/null @@ -1,199 +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. - */ -#include "arm_compute/graph/nodes/ResidualLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/Graph.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "arm_compute/graph/SubGraph.h" -#include "arm_compute/graph/Tensor.h" -#include "arm_compute/runtime/IFunction.h" -#include "support/ToolchainSupport.h" -#include "utils/Utils.h" - -#include -#include -#include - -using namespace arm_compute::graph; - -/** Residual function */ -class ResidualFunction final : public arm_compute::IFunction -{ -public: - /** Default Constructor */ - ResidualFunction(GraphContext &ctx, ITensorObject *output) - : _ctx(ctx), _input(nullptr), _output(output), _func(nullptr), _graphs(), _graph_outputs() - { - } - - /** Prevent instances from being copy constructed */ - ResidualFunction(const ResidualFunction &) = delete; - /** Prevent instances from being copy assigned */ - const ResidualFunction &operator=(const ResidualFunction &) = delete; - /** Prevent instances from being move constructed */ - ResidualFunction(ResidualFunction &&) = delete; - /** Prevent instances from being move assigned */ - ResidualFunction &operator=(ResidualFunction &&) = delete; - /** Default destructor */ - ~ResidualFunction() override = default; - - /** Set the input (when using only one sub graph) - * - * @param[in] input Input to set - */ - void set_input(std::unique_ptr input) - { - _input = std::move(input); - } - - /** Registers graph to be executed by the residual function - * - * @param[in] graph Graph to register - * @param[in] output Output to register - */ - void register_graph(std::unique_ptr graph, std::unique_ptr output) - { - _graphs.push_back(std::move(graph)); - _graph_outputs.push_back(std::move(output)); - } - - /** Configure the function */ - void configure() - { - ARM_COMPUTE_ERROR_ON(_graphs.size() < 1 || _graphs.size() > 2); - TargetHint target_hint = _ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::ArithmeticAddition); - node_ctx.set_target(target_hint); - - if(_graphs.size() == 1) - { - arm_compute::ITensor *in = _input->tensor(); - node_ctx.add_input(in); - } - - for(auto &o : _graph_outputs) - { - arm_compute::ITensor *in = o->tensor(); - node_ctx.add_input(in); - } - - arm_compute::ITensor *out = _output->tensor(); - auto_init_if_empty(*out->info(), *_graph_outputs[0]->tensor()->info()); - node_ctx.add_output(out); - - _func = OperationRegistry::get().find_operation(OperationType::ArithmeticAddition, target_hint)->configure(node_ctx); - - for(auto &o : _graph_outputs) - { - o->allocate(); - } - } - - // Inherited methods overriden: - void run() override - { - ARM_COMPUTE_ERROR_ON(_graphs.size() < 1 || _graphs.size() > 2); - - for(auto &g : _graphs) - { - ARM_COMPUTE_ERROR_ON(g.get() == nullptr); - g->run(); - } - - _func->run(); - } - -private: - GraphContext _ctx; - std::unique_ptr _input; - ITensorObject *_output; - std::unique_ptr _func; - std::vector> _graphs; - std::vector> _graph_outputs; -}; - -std::unique_ptr ResidualLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - ARM_COMPUTE_ERROR_ON(dynamic_cast(input) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(output) == nullptr); - - // Create residual function - auto func = arm_compute::support::cpp14::make_unique(ctx, output); - - if(_sub_graphs.size() == 1) - { - std::unique_ptr original_in; - original_in = arm_compute::support::cpp14::make_unique(*dynamic_cast(input), - input->tensor()->info()->tensor_shape(), - Coordinates()); - func->set_input(std::move(original_in)); - } - - // Constuct all sub-graphs given the input/output - for(auto &sg : _sub_graphs) - { - ARM_COMPUTE_ERROR_ON(sg.get() == nullptr); - - // IO buffers - std::unique_ptr in; - std::unique_ptr out; - std::unique_ptr func_in; - - // Create input sub-tensor - if(!sg->has_input()) - { - in = arm_compute::support::cpp14::make_unique(*dynamic_cast(input), - input->tensor()->info()->tensor_shape(), - Coordinates()); - } - - // Create output sub-tensor - if(!sg->has_output()) - { - ITensorInfo *info = input->tensor()->info(); - func_in = arm_compute::support::cpp14::make_unique(TensorInfo(info->num_channels(), info->data_type(), info->fixed_point_position())); - func_in->set_target(ctx.hints().target_hint()); - out = arm_compute::support::cpp14::make_unique(func_in->tensor(), - TensorShape(), - Coordinates(0, 0, 0), - func_in->target(), - true); - } - - // Construct sub_graph - auto g = sg->construct(ctx, std::move(in), std::move(out)); - - // Register graph to function - func->register_graph(std::move(g), std::move(func_in)); - } - - func->configure(); - - return std::move(func); -} diff --git a/src/graph/nodes/SoftmaxLayer.cpp b/src/graph/nodes/SoftmaxLayer.cpp deleted file mode 100644 index 7f2325b312..0000000000 --- a/src/graph/nodes/SoftmaxLayer.cpp +++ /dev/null @@ -1,49 +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. - */ -#include "arm_compute/graph/nodes/SoftmaxLayer.h" - -#include "arm_compute/graph/Error.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistry.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::graph; - -std::unique_ptr SoftmaxLayer::instantiate_node(GraphContext &ctx, ITensorObject *input, ITensorObject *output) -{ - ARM_COMPUTE_ERROR_ON_UNALLOCATED_TENSOR_OBJECT(input, output); - - arm_compute::ITensor *in = input->tensor(); - arm_compute::ITensor *out = output->tensor(); - _target_hint = ctx.hints().target_hint(); - - // Create node context - NodeContext node_ctx(OperationType::SoftmaxLayer); - node_ctx.set_target(_target_hint); - node_ctx.add_input(in); - node_ctx.add_output(out); - - // Get function - return OperationRegistry::get().find_operation(OperationType::SoftmaxLayer, _target_hint)->configure(node_ctx); -} diff --git a/src/graph/nodes/SoftmaxLayerNode.cpp b/src/graph/nodes/SoftmaxLayerNode.cpp new file mode 100644 index 0000000000..4c21ac6ad0 --- /dev/null +++ b/src/graph/nodes/SoftmaxLayerNode.cpp @@ -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. + */ +#include "arm_compute/graph/nodes/SoftmaxLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +SoftmaxLayerNode::SoftmaxLayerNode(float beta) + : _beta(beta) +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(1, NullTensorID); +} + +float SoftmaxLayerNode::beta() const +{ + return _beta; +} + +bool SoftmaxLayerNode::forward_descriptors() +{ + if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) + { + Tensor *dst = output(0); + ARM_COMPUTE_ERROR_ON(dst == nullptr); + dst->desc() = configure_output(0); + return true; + } + return false; +} + +TensorDescriptor SoftmaxLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + return src->desc(); +} + +Status SoftmaxLayerNode::validate() +{ + return Status{}; +} + +NodeType SoftmaxLayerNode::type() const +{ + return NodeType::SoftmaxLayer; +} + +void SoftmaxLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/nodes/SplitLayerNode.cpp b/src/graph/nodes/SplitLayerNode.cpp new file mode 100644 index 0000000000..c8fb43c2a1 --- /dev/null +++ b/src/graph/nodes/SplitLayerNode.cpp @@ -0,0 +1,117 @@ +/* + * 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. + */ +#include "arm_compute/graph/nodes/SplitLayerNode.h" + +#include "arm_compute/core/Utils.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/INodeVisitor.h" + +namespace arm_compute +{ +namespace graph +{ +SplitLayerNode::SplitLayerNode(unsigned int num_splits, unsigned int axis) + : _num_splits(num_splits), _axis(axis) +{ + _input_edges.resize(1, EmptyEdgeID); + _outputs.resize(num_splits, NullTensorID); +} + +unsigned int SplitLayerNode::num_splits() const +{ + return _num_splits; +} + +unsigned int SplitLayerNode::axis() const +{ + return _axis; +} + +std::pair SplitLayerNode::compute_output_shape(TensorShape input_shape, unsigned int num_splits, unsigned int axis, unsigned int idx) +{ + ARM_COMPUTE_ERROR_ON(axis >= input_shape.num_dimensions()); + ARM_COMPUTE_ERROR_ON_MSG(input_shape[axis] % num_splits, "Split should be exact"); + + const unsigned int split_size = input_shape[axis] / num_splits; + + TensorShape output_shape = input_shape; + output_shape.set(axis, split_size); + + Coordinates coords; + coords.set(axis, idx * split_size); + + return std::make_pair(output_shape, coords); +} + +bool SplitLayerNode::forward_descriptors() +{ + if(input_id(0) != NullTensorID) + { + for(unsigned int i = 0; i < _outputs.size(); ++i) + { + if(output_id(i) != NullTensorID) + { + Tensor *dst_i = output(i); + ARM_COMPUTE_ERROR_ON(dst_i == nullptr); + dst_i->desc() = configure_output(i); + } + } + return true; + } + return false; +} + +TensorDescriptor SplitLayerNode::configure_output(size_t idx) const +{ + ARM_COMPUTE_UNUSED(idx); + ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); + + const Tensor *src = input(0); + ARM_COMPUTE_ERROR_ON(src == nullptr); + + TensorShape output_shape; + + TensorDescriptor output_info = src->desc(); + std::tie(output_shape, std::ignore) = compute_output_shape(src->desc().shape, _num_splits, _axis, idx); + output_info.shape = output_shape; + + return output_info; +} + +Status SplitLayerNode::validate() +{ + return Status{}; +} + +NodeType SplitLayerNode::type() const +{ + return NodeType::SplitLayer; +} + +void SplitLayerNode::accept(INodeVisitor &v) +{ + v.visit(*this); +} +} // namespace graph +} // namespace arm_compute \ No newline at end of file diff --git a/src/graph/operations/CLSimpleOperations.cpp b/src/graph/operations/CLSimpleOperations.cpp deleted file mode 100644 index fe56122009..0000000000 --- a/src/graph/operations/CLSimpleOperations.cpp +++ /dev/null @@ -1,495 +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. - */ -#include "arm_compute/core/CL/ICLTensor.h" -#include "arm_compute/core/Error.h" -#include "arm_compute/graph/IOperation.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistrar.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/CL/CLFunctions.h" -#include "support/ToolchainSupport.h" -#include "utils/GraphTypePrinter.h" -#include "utils/TypePrinter.h" - -#include - -using namespace arm_compute::graph; - -/* Activation Layer */ -REGISTER_SIMPLE_OPERATION(CLActivationLayerOperation, OPENCL, OperationType::ActivationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto act_info = ctx.parameter("ActivationLayerInfo"); - - // Create and configure function - auto activation = arm_compute::support::cpp14::make_unique(); - activation->configure(in, out, act_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLActivationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << std::endl); - - return std::move(activation); -} - -/* Arithmetic addition */ -REGISTER_SIMPLE_OPERATION(CLArithmeticAdditionOperation, OPENCL, OperationType::ArithmeticAddition) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 2); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(1)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in1 = dynamic_cast(ctx.input(0)); - auto *in2 = dynamic_cast(ctx.input(1)); - auto *out = dynamic_cast(ctx.output(0)); - - auto addition = arm_compute::support::cpp14::make_unique(); - addition->configure(in1, in2, out, ConvertPolicy::SATURATE); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLArithmeticAddition" - << " Data Type: " << in1->info()->data_type() - << " Input 1 shape: " << in1->info()->tensor_shape() - << " Input 2 shape: " << in2->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(addition); -} - -/* Batch Normalization Layer */ -REGISTER_SIMPLE_OPERATION(CLBatchNormalizationLayerOperation, OPENCL, OperationType::BatchNormalizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 5); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(1)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(2)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(3)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(4)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *mean = dynamic_cast(ctx.input(1)); - auto *var = dynamic_cast(ctx.input(2)); - auto *beta = dynamic_cast(ctx.input(3)); - auto *gamma = dynamic_cast(ctx.input(4)); - auto *out = dynamic_cast(ctx.output(0)); - const auto epsilon = ctx.parameter("epsilon"); - const auto act_info = ctx.parameter("act_info"); - - // Create and configure function - auto batch_norm = arm_compute::support::cpp14::make_unique(); - batch_norm->configure(in, out, mean, var, beta, gamma, epsilon, act_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLBatchNormalizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Mean shape: " << mean->info()->tensor_shape() - << " Var shape: " << var->info()->tensor_shape() - << " Beta shape: " << beta->info()->tensor_shape() - << " Gamma shape: " << gamma->info()->tensor_shape() - << " Epsilon: " << epsilon - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << std::endl); - - return std::move(batch_norm); -} - -/* DepthConvertLayer Layer */ -REGISTER_SIMPLE_OPERATION(CLDepthConvertLayerOperation, OPENCL, OperationType::DepthConvertLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto conv_policy = ctx.parameter("ConvertPolicy"); - const auto shift = ctx.parameter("shift"); - - // Create and configure function - auto depthconvert = arm_compute::support::cpp14::make_unique(); - depthconvert->configure(in, out, conv_policy, shift); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDepthConvertLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " shift: " << shift - << std::endl); - - return std::move(depthconvert); -} - -/* DepthwiseConvolutionLayer Layer */ -REGISTER_SIMPLE_OPERATION(CLDepthwiseConvolutionOperation, OPENCL, OperationType::DepthwiseConvolutionLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 2 && ctx.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *weights = dynamic_cast(ctx.input(1)); - auto *biases = ctx.num_inputs() == 3 ? dynamic_cast(ctx.input(2)) : nullptr; - auto *out = dynamic_cast(ctx.output(0)); - const auto conv_info = ctx.parameter("ConvolutionInfo"); - const auto opt3x3 = ctx.parameter("Optimized3x3"); - - // Create and configure function - std::unique_ptr func; - bool run_3x3_opt = opt3x3 && weights->info()->dimension(0) == 3; - if(run_3x3_opt) - { - auto depwthwise_conv = arm_compute::support::cpp14::make_unique(); - depwthwise_conv->configure(in, weights, biases, out, conv_info); - func = std::move(depwthwise_conv); - } - else - { - auto depwthwise_conv = arm_compute::support::cpp14::make_unique(); - depwthwise_conv->configure(in, weights, biases, out, conv_info); - func = std::move(depwthwise_conv); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDepthwiseConvolutionLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape()); - if(biases == nullptr) - { - ARM_COMPUTE_LOG_GRAPH_INFO(" Biases shape: No biases provided" << std::endl); - } - else - { - ARM_COMPUTE_LOG_GRAPH_INFO(" Biases shape: " << biases->info()->tensor_shape() << std::endl); - } - - return func; -} - -/* DeQuantizationLayer Layer */ -REGISTER_SIMPLE_OPERATION(CLDequantizationLayerOperation, OPENCL, OperationType::DequantizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 2); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(1)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - auto *min_max = dynamic_cast(ctx.output(1)); - - // Create and configure function - auto dequantization = arm_compute::support::cpp14::make_unique(); - dequantization->configure(in, out, min_max); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLDequantizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Min max shape: " << min_max->info()->tensor_shape() - << std::endl); - - return std::move(dequantization); -} - -/* Flatten Layer */ -REGISTER_SIMPLE_OPERATION(CLFlattenLayerOperation, OPENCL, OperationType::FlattenLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto flatten = arm_compute::support::cpp14::make_unique(); - flatten->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFlattenLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(flatten); -} - -/* Floor Layer */ -REGISTER_SIMPLE_OPERATION(CLFloorLayerOperation, OPENCL, OperationType::FloorLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto floor = arm_compute::support::cpp14::make_unique(); - floor->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFloorLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(floor); -} - -/* Fully Connected Layer */ -REGISTER_SIMPLE_OPERATION(CLFullyConnectedLayer, OPENCL, OperationType::FullyConnectedLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(1)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(2)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *weights = dynamic_cast(ctx.input(1)); - auto *biases = dynamic_cast(ctx.input(2)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto fc = arm_compute::support::cpp14::make_unique(); - fc->configure(in, weights, biases, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFullyConnectedLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Biases Shape: " << biases->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(fc); -} - -/* L2 Normalize Layer */ -REGISTER_SIMPLE_OPERATION(CLL2NormalizeLayerOperation, OPENCL, OperationType::L2NormalizeLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto axis = ctx.parameter("axis"); - const auto epsilon = ctx.parameter("epsilon"); - - // Create and configure function - auto l2_norm = arm_compute::support::cpp14::make_unique(); - l2_norm->configure(in, out, axis, epsilon); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLL2NormalizeLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Axis: " << axis - << " Epsilon: " << epsilon - << std::endl); - - return std::move(l2_norm); -} - -/* Normalization Layer */ -REGISTER_SIMPLE_OPERATION(CLNormalizationLayerOperation, OPENCL, OperationType::NormalizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto norm_info = ctx.parameter("NormalizationLayerInfo"); - - // Create and configure function - auto norm = arm_compute::support::cpp14::make_unique(); - norm->configure(in, out, norm_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLNormalizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Normalization info: " << norm_info - << std::endl); - - return std::move(norm); -} - -/* Pooling Layer */ -REGISTER_SIMPLE_OPERATION(CLPoolingLayerOperation, OPENCL, OperationType::PoolingLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto pool_info = ctx.parameter("PoolingLayerInfo"); - - // Create and configure function - auto pool = arm_compute::support::cpp14::make_unique(); - pool->configure(in, out, pool_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLPoolingLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Pooling info: " << pool_info - << std::endl); - - return std::move(pool); -} - -/* Quantization Layer */ -REGISTER_SIMPLE_OPERATION(CLQuantizationLayerOperation, OPENCL, OperationType::QuantizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto quantization = arm_compute::support::cpp14::make_unique(); - quantization->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLQuantizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(quantization); -} - -/* Reshape Layer */ -REGISTER_SIMPLE_OPERATION(CLReshapeLayerOperation, OPENCL, OperationType::ReshapeLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto reshape = arm_compute::support::cpp14::make_unique(); - reshape->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLReshapeLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(reshape); -} - -/* Softmax Layer */ -REGISTER_SIMPLE_OPERATION(CLSoftmaxLayerOperation, OPENCL, OperationType::SoftmaxLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto smx = arm_compute::support::cpp14::make_unique(); - smx->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLSoftmaxLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(smx); -} diff --git a/src/graph/operations/NESimpleOperations.cpp b/src/graph/operations/NESimpleOperations.cpp deleted file mode 100644 index 4154b9a59c..0000000000 --- a/src/graph/operations/NESimpleOperations.cpp +++ /dev/null @@ -1,495 +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. - */ -#include "arm_compute/core/Error.h" -#include "arm_compute/core/ITensor.h" -#include "arm_compute/graph/IOperation.h" -#include "arm_compute/graph/NodeContext.h" -#include "arm_compute/graph/OperationRegistrar.h" -#include "arm_compute/graph/Types.h" -#include "arm_compute/runtime/NEON/NEFunctions.h" -#include "support/ToolchainSupport.h" -#include "utils/GraphTypePrinter.h" -#include "utils/TypePrinter.h" - -#include - -using namespace arm_compute::graph; - -/* Activation Layer */ -REGISTER_SIMPLE_OPERATION(NEActivationLayerOperation, NEON, OperationType::ActivationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto act_info = ctx.parameter("ActivationLayerInfo"); - - // Create and configure function - auto activation = arm_compute::support::cpp14::make_unique(); - activation->configure(in, out, act_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEActivationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << std::endl); - - return std::move(activation); -} - -/* Arithmetic addition */ -REGISTER_SIMPLE_OPERATION(NEArithmeticAdditionOperation, NEON, OperationType::ArithmeticAddition) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 2); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(1)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in1 = dynamic_cast(ctx.input(0)); - auto *in2 = dynamic_cast(ctx.input(1)); - auto *out = dynamic_cast(ctx.output(0)); - - auto addition = arm_compute::support::cpp14::make_unique(); - addition->configure(in1, in2, out, ConvertPolicy::SATURATE); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEArithmeticAddition" - << " Data Type: " << in1->info()->data_type() - << " Input 1 shape: " << in1->info()->tensor_shape() - << " Input 2 shape: " << in2->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(addition); -} - -/* Batch Normalization Layer */ -REGISTER_SIMPLE_OPERATION(NEBatchNormalizationLayerOperation, NEON, OperationType::BatchNormalizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 5); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(1)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(2)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(3)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(4)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *mean = dynamic_cast(ctx.input(1)); - auto *var = dynamic_cast(ctx.input(2)); - auto *beta = dynamic_cast(ctx.input(3)); - auto *gamma = dynamic_cast(ctx.input(4)); - auto *out = dynamic_cast(ctx.output(0)); - const auto epsilon = ctx.parameter("epsilon"); - const auto act_info = ctx.parameter("act_info"); - - // Create and configure function - auto batch_norm = arm_compute::support::cpp14::make_unique(); - batch_norm->configure(in, out, mean, var, beta, gamma, epsilon, act_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEBatchNormalizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Mean shape: " << mean->info()->tensor_shape() - << " Var shape: " << var->info()->tensor_shape() - << " Beta shape: " << beta->info()->tensor_shape() - << " Gamma shape: " << gamma->info()->tensor_shape() - << " Epsilon: " << epsilon - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << std::endl); - - return std::move(batch_norm); -} - -/* DepthConvertLayer Layer */ -REGISTER_SIMPLE_OPERATION(NEDepthConvertLayerOperation, NEON, OperationType::DepthConvertLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto conv_policy = ctx.parameter("ConvertPolicy"); - const auto shift = ctx.parameter("shift"); - - // Create and configure function - auto depthconvert = arm_compute::support::cpp14::make_unique(); - depthconvert->configure(in, out, conv_policy, shift); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEDepthConvertLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " shift: " << shift - << std::endl); - - return std::move(depthconvert); -} - -/* DepthwiseConvolutionLayer Layer */ -REGISTER_SIMPLE_OPERATION(NEDepthwiseConvolutionOperation, NEON, OperationType::DepthwiseConvolutionLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 2 && ctx.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *weights = dynamic_cast(ctx.input(1)); - auto *biases = ctx.num_inputs() == 3 ? dynamic_cast(ctx.input(2)) : nullptr; - auto *out = dynamic_cast(ctx.output(0)); - const auto conv_info = ctx.parameter("ConvolutionInfo"); - const auto opt3x3 = ctx.parameter("Optimized3x3"); - - // Create and configure function - std::unique_ptr func; - bool run_3x3_opt = opt3x3 && weights->info()->dimension(0) == 3; - if(run_3x3_opt) - { - auto depwthwise_conv = arm_compute::support::cpp14::make_unique(); - depwthwise_conv->configure(in, weights, biases, out, conv_info); - func = std::move(depwthwise_conv); - } - else - { - auto depwthwise_conv = arm_compute::support::cpp14::make_unique(); - depwthwise_conv->configure(in, weights, biases, out, conv_info); - func = std::move(depwthwise_conv); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEDepthwiseConvolutionLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape()); - if(biases == nullptr) - { - ARM_COMPUTE_LOG_GRAPH_INFO(" Biases shape: No biases provided" << std::endl); - } - else - { - ARM_COMPUTE_LOG_GRAPH_INFO(" Biases shape: " << biases->info()->tensor_shape() << std::endl); - } - - return func; -} - -/* DeQuantizationLayer Layer */ -REGISTER_SIMPLE_OPERATION(NEDequantizationLayerOperation, NEON, OperationType::DequantizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 2); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(1)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - auto *min_max = dynamic_cast(ctx.output(1)); - - // Create and configure function - auto dequantization = arm_compute::support::cpp14::make_unique(); - dequantization->configure(in, out, min_max); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEDequantizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Min max shape: " << min_max->info()->tensor_shape() - << std::endl); - - return std::move(dequantization); -} - -/* Flatten Layer */ -REGISTER_SIMPLE_OPERATION(NEFlattenLayerOperation, NEON, OperationType::FlattenLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto flatten = arm_compute::support::cpp14::make_unique(); - flatten->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEFlattenLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(flatten); -} - -/* Floor Layer */ -REGISTER_SIMPLE_OPERATION(NEFloorLayerOperation, NEON, OperationType::FloorLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto floor = arm_compute::support::cpp14::make_unique(); - floor->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEFloorLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(floor); -} - -/* Fully Connected Layer */ -REGISTER_SIMPLE_OPERATION(NEFullyConnectedLayer, NEON, OperationType::FullyConnectedLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(1)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(2)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *weights = dynamic_cast(ctx.input(1)); - auto *biases = dynamic_cast(ctx.input(2)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto fc = arm_compute::support::cpp14::make_unique(); - fc->configure(in, weights, biases, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEFullyConnectedLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Biases Shape: " << biases->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(fc); -} - -/* L2 Normalize Layer */ -REGISTER_SIMPLE_OPERATION(NEL2NormalizeLayerOperation, NEON, OperationType::L2NormalizeLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto axis = ctx.parameter("axis"); - const auto epsilon = ctx.parameter("epsilon"); - - // Create and configure function - auto l2_norm = arm_compute::support::cpp14::make_unique(); - l2_norm->configure(in, out, axis, epsilon); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEL2NormalizeLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Axis: " << axis - << " Epsilon: " << epsilon - << std::endl); - - return std::move(l2_norm); -} - -/* Normalization Layer */ -REGISTER_SIMPLE_OPERATION(NENormalizationLayerOperation, NEON, OperationType::NormalizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto norm_info = ctx.parameter("NormalizationLayerInfo"); - - // Create and configure function - auto norm = arm_compute::support::cpp14::make_unique(); - norm->configure(in, out, norm_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NENormalizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Normalization info: " << norm_info - << std::endl); - - return std::move(norm); -} - -/* Pooling Layer */ -REGISTER_SIMPLE_OPERATION(NEPoolingLayerOperation, NEON, OperationType::PoolingLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - const auto pool_info = ctx.parameter("PoolingLayerInfo"); - - // Create and configure function - auto pool = arm_compute::support::cpp14::make_unique(); - pool->configure(in, out, pool_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEPoolingLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Pooling info: " << pool_info - << std::endl); - - return std::move(pool); -} - -/* Quantization Layer */ -REGISTER_SIMPLE_OPERATION(NEQuantizationLayerOperation, NEON, OperationType::QuantizationLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto quantization = arm_compute::support::cpp14::make_unique(); - quantization->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEQuantizationLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(quantization); -} - -/* Reshape Layer */ -REGISTER_SIMPLE_OPERATION(NEReshapeLayerOperation, NEON, OperationType::ReshapeLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto reshape = arm_compute::support::cpp14::make_unique(); - reshape->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEReshapeLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(reshape); -} - -/* Softmax Layer */ -REGISTER_SIMPLE_OPERATION(NESoftmaxLayerOperation, NEON, OperationType::SoftmaxLayer) -{ - ARM_COMPUTE_ERROR_ON(ctx.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(ctx.num_outputs() != 1); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.input(0)) == nullptr); - ARM_COMPUTE_ERROR_ON(dynamic_cast(ctx.output(0)) == nullptr); - - // Extract IO and info - auto *in = dynamic_cast(ctx.input(0)); - auto *out = dynamic_cast(ctx.output(0)); - - // Create and configure function - auto smx = arm_compute::support::cpp14::make_unique(); - smx->configure(in, out); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NESoftmaxLayer" - << " Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); - - return std::move(smx); -} diff --git a/src/graph/printers/DotGraphPrinter.cpp b/src/graph/printers/DotGraphPrinter.cpp new file mode 100644 index 0000000000..47b1bb56bf --- /dev/null +++ b/src/graph/printers/DotGraphPrinter.cpp @@ -0,0 +1,173 @@ +/* + * 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. + */ +#include "arm_compute/graph/printers/DotGraphPrinter.h" + +#include "arm_compute/core/Error.h" +#include "arm_compute/graph/Graph.h" +#include "arm_compute/graph/Tensor.h" +#include "arm_compute/graph/TypePrinter.h" +#include "arm_compute/graph/nodes/Nodes.h" + +namespace arm_compute +{ +namespace graph +{ +void DotGraphVisitor::visit(ActivationLayerNode &n) +{ + std::stringstream ss; + ss << n.activation_info().activation(); + _info = ss.str(); +} + +void DotGraphVisitor::visit(BatchNormalizationLayerNode &n) +{ + std::stringstream ss; + ss << (n.fused_activation().enabled() ? to_string(n.fused_activation().activation()) : ""); + _info = ss.str(); +} + +void DotGraphVisitor::visit(ConvolutionLayerNode &n) +{ + std::stringstream ss; + ss << n.convolution_method(); + _info = ss.str(); +} + +void DotGraphVisitor::visit(DepthConcatenateLayerNode &n) +{ + std::stringstream ss; + ss << "Enabled: " << n.is_enabled(); + _info = ss.str(); +} + +void DotGraphVisitor::visit(DepthwiseConvolutionLayerNode &n) +{ + std::stringstream ss; + ss << n.depthwise_convolution_method(); + _info = ss.str(); +} + +void DotGraphVisitor::visit(EltwiseLayerNode &n) +{ + std::stringstream ss; + ss << n.eltwise_operation(); + _info = ss.str(); +} + +void DotGraphVisitor::visit(NormalizationLayerNode &n) +{ + std::stringstream ss; + ss << n.normalization_info().type(); + _info = ss.str(); +} + +void DotGraphVisitor::visit(PoolingLayerNode &n) +{ + std::stringstream ss; + ss << n.pooling_info().pool_type(); + ss << R"( \n )"; + ss << n.pooling_info().pool_size(); + ss << R"( \n )"; + ss << n.pooling_info().pad_stride_info(); + _info = ss.str(); +} + +void DotGraphVisitor::default_visit() +{ + _info.clear(); +} + +const std::string &DotGraphVisitor::info() const +{ + return _info; +} + +void DotGraphPrinter::print(const Graph &g, std::ostream &os) +{ + // Print header + print_header(g, os); + + // Print nodes + print_nodes(g, os); + + // Print edges + print_edges(g, os); + + // Print footer + print_footer(g, os); +} + +void DotGraphPrinter::print_header(const Graph &g, std::ostream &os) +{ + // Print graph name + std::string graph_name = (g.name().empty()) ? "Graph" : g.name(); + os << "digraph " << graph_name << "{\n"; +} + +void DotGraphPrinter::print_footer(const Graph &g, std::ostream &os) +{ + ARM_COMPUTE_UNUSED(g); + os << "}\n"; +} + +void DotGraphPrinter::print_nodes(const Graph &g, std::ostream &os) +{ + for(const auto &n : g.nodes()) + { + if(n) + { + // Output node id + std::string node_id = std::string("n") + support::cpp11::to_string(n->id()); + os << node_id << " "; + + // Output label + n->accept(_dot_node_visitor); + + std::string name = n->name().empty() ? node_id : n->name(); + auto node_description = _dot_node_visitor.info(); + + os << R"([label = ")" << name << R"( \n )" << n->assigned_target() << R"( \n )" << node_description << R"("])"; + os << ";\n"; + } + } +} + +void DotGraphPrinter::print_edges(const Graph &g, std::ostream &os) +{ + for(const auto &e : g.edges()) + { + if(e) + { + std::string source_node_id = std::string("n") + support::cpp11::to_string(e->producer_id()); + std::string sink_node_id = std::string("n") + support::cpp11::to_string(e->consumer_id()); + os << source_node_id << " -> " << sink_node_id << " "; + const Tensor *t = e->tensor(); + ARM_COMPUTE_ERROR_ON(t == nullptr); + os << R"([label = ")" << t->desc().shape << R"( \n )" << t->desc().data_type << R"("])"; + os << ";\n"; + } + } +} +} // namespace graph +} // namespace arm_compute diff --git a/src/graph2/Graph.cpp b/src/graph2/Graph.cpp deleted file mode 100644 index ead67bc85a..0000000000 --- a/src/graph2/Graph.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/Graph.h" - -namespace arm_compute -{ -namespace graph2 -{ -Graph::Graph(GraphID id, std::string name) - : _id(id), _name(std::move(name)), _nodes(), _edges(), _tensors(), _tagged_nodes(), _mtx() -{ -} - -bool Graph::remove_node(NodeID nid) -{ - if(nid >= _nodes.size()) - { - return false; - } - - std::unique_ptr &node = _nodes[nid]; - - // Remove node connections - if(node) - { - for(auto &input_eid : node->_input_edges) - { - remove_connection(input_eid); - } - for(auto &outpud_eid : node->_output_edges) - { - remove_connection(outpud_eid); - } - } - - node = nullptr; - - return true; -} - -EdgeID Graph::add_connection(NodeID source, size_t source_idx, NodeID sink, size_t sink_idx) -{ - std::lock_guard lock(_mtx); - - // Check if node index is valid, if node exists and finally if the connection index is valid - ARM_COMPUTE_ERROR_ON((source >= _nodes.size()) || (_nodes[source] == nullptr) || (source_idx >= _nodes[source]->num_outputs())); - ARM_COMPUTE_ERROR_ON((sink >= _nodes.size()) || (_nodes[sink] == nullptr) || (sink_idx >= _nodes[sink]->num_inputs())); - - // Get nodes - std::unique_ptr &source_node = _nodes[source]; - std::unique_ptr &sink_node = _nodes[sink]; - - // Check for duplicate connections (Check only sink node) - Edge *sink_node_edge = sink_node->input_edge(sink_idx); - if((sink_node_edge != nullptr) && (sink_node_edge->producer_id() == source) && (sink_node_edge->producer_idx() == source_idx) - && (sink_node_edge->consumer_id() == sink) && (sink_node_edge->consumer_idx() == sink_idx)) - { - return sink_node_edge->id(); - } - - // Check if there is already a tensor associated with output if not create one - TensorID tid = source_node->output_id(source_idx); - if(tid == NullTensorID) - { - tid = create_tensor(); - } - std::unique_ptr &tensor = _tensors[tid]; - - // Create connections - EdgeID eid = _edges.size(); - auto connection = arm_compute::support::cpp14::make_unique(eid, source_node.get(), source_idx, sink_node.get(), sink_idx, tensor.get()); - _edges.push_back(std::move(connection)); - - // Add connections to source and sink nodes - source_node->_output_edges.insert(eid); - sink_node->_input_edges[sink_idx] = eid; - - // Set tensor output node - source_node->_outputs[source_idx] = tid; - - // Bind tensor to the edge - tensor->bind_edge(eid); - - // Try and propagate shapes in sink node - sink_node->forward_descriptors(); - - return eid; -} - -bool Graph::remove_connection(EdgeID eid) -{ - if(eid >= _edges.size()) - { - return false; - } - - std::unique_ptr &edge = _edges[eid]; - - // Remove node connections - if(edge != nullptr) - { - // Get tensor bound to the edge - if(edge->tensor() != nullptr) - { - edge->tensor()->unbind_edge(eid); - } - - // Remove edges from source node - if(edge->producer() != nullptr) - { - edge->producer()->_output_edges.erase(eid); - } - - // Remove edges from sink node - if((edge->consumer() != nullptr) && (edge->consumer_idx() < edge->consumer()->_input_edges.size())) - { - edge->consumer()->_input_edges[edge->consumer_idx()] = EmptyEdgeID; - } - } - - // Clear edge - edge = nullptr; - - return true; -} - -TensorID Graph::create_tensor(TensorDescriptor desc) -{ - TensorID tid = _tensors.size(); - auto tensor = support::cpp14::make_unique(tid, desc); - _tensors.push_back(std::move(tensor)); - - return tid; -} - -std::string Graph::name() const -{ - return _name; -} - -GraphID Graph::id() const -{ - return _id; -} - -const std::vector &Graph::inputs() -{ - return _tagged_nodes[NodeType::Input]; -} - -std::vector> &Graph::nodes() -{ - return _nodes; -} - -const std::vector> &Graph::nodes() const -{ - return _nodes; -} - -const std::vector> &Graph::edges() const -{ - return _edges; -} - -std::vector> &Graph::tensors() -{ - return _tensors; -} - -const std::vector> &Graph::tensors() const -{ - return _tensors; -} - -const INode *Graph::node(NodeID id) const -{ - return (id >= _nodes.size()) ? nullptr : _nodes[id].get(); -} - -INode *Graph::node(NodeID id) -{ - return (id >= _nodes.size()) ? nullptr : _nodes[id].get(); -} - -const Edge *Graph::edge(EdgeID id) const -{ - return (id >= _edges.size()) ? nullptr : _edges[id].get(); -} - -Edge *Graph::edge(EdgeID id) -{ - return (id >= _edges.size()) ? nullptr : _edges[id].get(); -} - -const Tensor *Graph::tensor(TensorID id) const -{ - return (id >= _tensors.size()) ? nullptr : _tensors[id].get(); -} - -Tensor *Graph::tensor(TensorID id) -{ - return (id >= _tensors.size()) ? nullptr : _tensors[id].get(); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/GraphBuilder.cpp b/src/graph2/GraphBuilder.cpp deleted file mode 100644 index e6fc2afe21..0000000000 --- a/src/graph2/GraphBuilder.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/GraphBuilder.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Utils.h" -#include "arm_compute/graph2/algorithms/BFS.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -#define CHECK_NODEIDX_PAIR(pair, g) \ - ARM_COMPUTE_ERROR_ON(((pair).node_id >= (g).nodes().size()) || ((g).node((pair).node_id) == nullptr) || ((pair).index >= (g).node((pair).node_id)->num_outputs())); - -namespace arm_compute -{ -namespace graph2 -{ -namespace -{ -Status set_node_params(Graph &g, NodeID nid, NodeParams ¶ms) -{ - INode *node = g.node(nid); - ARM_COMPUTE_RETURN_ERROR_ON(!node); - - node->set_common_node_parameters(params); - - return Status{}; -} - -Status set_accessor_on_node(Graph &g, NodeID nid, bool is_output, size_t idx, ITensorAccessorUPtr accessor) -{ - INode *node = g.node(nid); - ARM_COMPUTE_RETURN_ERROR_ON(!node); - - Tensor *tensor = is_output ? node->output(idx) : node->input(idx); - ARM_COMPUTE_RETURN_ERROR_ON(!tensor); - - tensor->set_accessor(std::move(accessor)); - - return Status{}; -} - -NodeID add_const_node_with_name(Graph &g, NodeParams params, const std::string &name, TensorDescriptor desc, ITensorAccessorUPtr accessor) -{ - params.name = params.name.empty() ? "" : params.name + name; - auto nid = GraphBuilder::add_const_node(g, params, desc, std::move(accessor)); - set_node_params(g, nid, params); - return nid; -} - -template -NodeID create_simple_single_input_output_node(Graph &g, NodeParams ¶ms, NodeIdxPair input, Args &&... args) -{ - CHECK_NODEIDX_PAIR(input, g); - - NodeID nid = g.add_node(std::forward(args)...); - g.add_connection(input.node_id, input.index, nid, 0); - set_node_params(g, nid, params); - - return nid; -} - -NodeID create_grouped_convolution(Graph &g, NodeParams ¶ms, NodeIdxPair input, NodeID weights, NodeID bias, - PadStrideInfo conv_info, ConvolutionMethod method, unsigned int num_groups) -{ - bool has_bias = (bias != EmptyNodeID); - - // Split input - NodeID input_split = GraphBuilder::add_split_node(g, params, input, num_groups, 2); - - // Split weights - NodeID weights_split = GraphBuilder::add_split_node(g, params, { weights, 0 }, num_groups, 3); - - // Split bias - NodeID bias_split = EmptyNodeID; - if(has_bias) - { - // Split bias - bias_split = GraphBuilder::add_split_node(g, params, { bias, 0 }, num_groups, 0); - } - - std::vector convolution_outputs; - for(unsigned int i = 0; i < num_groups; ++i) - { - NodeID conv_nid = g.add_node(conv_info, method); - g.add_connection(input_split, i, conv_nid, 0); - g.add_connection(weights_split, i, conv_nid, 1); - if(has_bias) - { - g.add_connection(bias_split, i, conv_nid, 2); - } - set_node_params(g, conv_nid, params); - convolution_outputs.push_back({ conv_nid, 0 }); - } - - // Depth concatenate output - return GraphBuilder::add_depth_concatenate_node(g, params, convolution_outputs); -} -} // namespace - -NodeID GraphBuilder::add_const_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor) -{ - auto nid = g.add_node(desc); - set_node_params(g, nid, params); - set_accessor_on_node(g, nid, true, 0, std::move(accessor)); - return nid; -} - -NodeID GraphBuilder::add_input_node(Graph &g, NodeParams params, TensorDescriptor desc, ITensorAccessorUPtr accessor) -{ - auto nid = g.add_node(desc); - set_node_params(g, nid, params); - set_accessor_on_node(g, nid, true, 0, std::move(accessor)); - return nid; -} - -NodeID GraphBuilder::add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor) -{ - CHECK_NODEIDX_PAIR(input, g); - - NodeID nid = g.add_node(); - g.add_connection(input.node_id, input.index, nid, 0); - set_node_params(g, nid, params); - set_accessor_on_node(g, nid, false, 0, std::move(accessor)); - - return nid; -} - -NodeID GraphBuilder::add_activation_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info) -{ - return create_simple_single_input_output_node(g, params, input, act_info); -} - -NodeID GraphBuilder::add_batch_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, float epsilon, - ITensorAccessorUPtr mean_accessor, ITensorAccessorUPtr var_accessor, - ITensorAccessorUPtr beta_accessor, ITensorAccessorUPtr gamma_accessor) -{ - CHECK_NODEIDX_PAIR(input, g); - - bool has_beta = (beta_accessor != nullptr); - bool has_gamma = (gamma_accessor != nullptr); - - // Get input tensor descriptor - const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); - - // Calculate Common Descriptor - TensorDescriptor common_desc = input_tensor_desc; - common_desc.shape = TensorShape(common_desc.shape.z()); - - // Create mean and nodes - auto mean_nid = add_const_node_with_name(g, params, "Mean", common_desc, std::move(mean_accessor)); - auto var_nid = add_const_node_with_name(g, params, "Variance", common_desc, std::move(var_accessor)); - - // Create beta node - NodeID beta_nid = EmptyNodeID; - if(has_beta) - { - beta_nid = add_const_node_with_name(g, params, "Beta", common_desc, std::move(beta_accessor)); - } - - // Create gamma node - NodeID gamma_nid = EmptyNodeID; - if(has_gamma) - { - gamma_nid = add_const_node_with_name(g, params, "Gamma", common_desc, std::move(gamma_accessor)); - } - - // Create batch normalization node and add connections - NodeID batch_norm_nid = g.add_node(epsilon); - g.add_connection(input.node_id, input.index, batch_norm_nid, 0); - g.add_connection(mean_nid, 0, batch_norm_nid, 1); - g.add_connection(var_nid, 0, batch_norm_nid, 2); - if(has_beta) - { - g.add_connection(beta_nid, 0, batch_norm_nid, 3); - } - if(has_gamma) - { - g.add_connection(gamma_nid, 0, batch_norm_nid, 4); - } - set_node_params(g, batch_norm_nid, params); - - return batch_norm_nid; -} - -NodeID GraphBuilder::add_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, - Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo conv_info, - unsigned int num_groups, ConvolutionMethod method, - ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor) -{ - CHECK_NODEIDX_PAIR(input, g); - ARM_COMPUTE_ERROR_ON(depth == 0); - ARM_COMPUTE_ERROR_ON((kernel_spatial_extend.width == 0) || (kernel_spatial_extend.height == 0)); - - bool has_bias = (bias_accessor != nullptr); - - // Get input tensor descriptor - const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); - - // Create weights node - TensorDescriptor w_desc = input_tensor_desc; - w_desc.shape = TensorShape(kernel_spatial_extend.width, kernel_spatial_extend.height, w_desc.shape.z() / num_groups, depth); - NodeID w_nid = add_const_node_with_name(g, params, "Weights", w_desc, std::move(weights_accessor)); - - // Create bias nodes - NodeID b_nid = EmptyNodeID; - if(has_bias) - { - TensorDescriptor b_desc = input_tensor_desc; - b_desc.shape = TensorShape(depth); - b_nid = add_const_node_with_name(g, params, "Bias", b_desc, std::move(bias_accessor)); - } - - if(num_groups == 1) - { - // Create convolution node and connect - NodeID conv_nid = g.add_node(conv_info, method); - g.add_connection(input.node_id, input.index, conv_nid, 0); - g.add_connection(w_nid, 0, conv_nid, 1); - if(has_bias) - { - g.add_connection(b_nid, 0, conv_nid, 2); - } - set_node_params(g, conv_nid, params); - - return conv_nid; - } - else - { - return create_grouped_convolution(g, params, input, w_nid, b_nid, conv_info, method, num_groups); - } -} - -NodeID GraphBuilder::add_depth_concatenate_node(Graph &g, NodeParams params, std::vector inputs) -{ - ARM_COMPUTE_ERROR_ON(inputs.size() == 0); - - NodeID nid = g.add_node(inputs.size()); - - unsigned int i = 0; - for(const auto &input : inputs) - { - CHECK_NODEIDX_PAIR(input, g); - g.add_connection(input.node_id, input.index, nid, i++); - } - set_node_params(g, nid, params); - - return nid; -} - -NodeID GraphBuilder::add_depthwise_convolution_node(Graph &g, NodeParams params, NodeIdxPair input, Size2D kernel_spatial_extend, PadStrideInfo conv_info, - DepthwiseConvolutionMethod method, - ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor) -{ - CHECK_NODEIDX_PAIR(input, g); - ARM_COMPUTE_ERROR_ON((kernel_spatial_extend.width == 0) || (kernel_spatial_extend.height == 0)); - - bool has_bias = (bias_accessor != nullptr); - - // Get input tensor descriptor - const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); - - // Create weights node - TensorDescriptor w_desc = input_tensor_desc; - w_desc.shape = TensorShape(kernel_spatial_extend.width, kernel_spatial_extend.height, w_desc.shape.z()); - NodeID w_nid = add_const_node_with_name(g, params, "Weights", w_desc, std::move(weights_accessor)); - - // Create bias nodes - NodeID b_nid = EmptyNodeID; - if(has_bias) - { - TensorDescriptor b_desc = input_tensor_desc; - b_desc.shape = TensorShape(b_desc.shape.z()); - b_nid = add_const_node_with_name(g, params, "Bias", b_desc, std::move(bias_accessor)); - } - - // Create convolution node and connect - NodeID conv_nid = g.add_node(conv_info, method); - g.add_connection(input.node_id, input.index, conv_nid, 0); - g.add_connection(w_nid, 0, conv_nid, 1); - if(has_bias) - { - g.add_connection(b_nid, 0, conv_nid, 2); - } - set_node_params(g, conv_nid, params); - - return conv_nid; -} - -NodeID GraphBuilder::add_elementwise_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation) -{ - CHECK_NODEIDX_PAIR(input0, g); - CHECK_NODEIDX_PAIR(input1, g); - - NodeID nid = g.add_node(operation); - - g.add_connection(input0.node_id, input0.index, nid, 0); - g.add_connection(input1.node_id, input1.index, nid, 1); - - set_node_params(g, nid, params); - - return nid; -} - -NodeID GraphBuilder::add_flatten_node(Graph &g, NodeParams params, NodeIdxPair input) -{ - return create_simple_single_input_output_node(g, params, input); -} - -NodeID GraphBuilder::add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs, - ITensorAccessorUPtr weights_accessor, ITensorAccessorUPtr bias_accessor) -{ - CHECK_NODEIDX_PAIR(input, g); - ARM_COMPUTE_ERROR_ON(num_outputs == 0); - - bool has_bias = (bias_accessor != nullptr); - - // Get input tensor descriptor - const TensorDescriptor input_tensor_desc = get_tensor_descriptor(g, g.node(input.node_id)->outputs()[0]); - - // Create weights node - TensorDescriptor w_desc = input_tensor_desc; - w_desc.shape = FullyConnectedLayerNode::compute_weights_shape(input_tensor_desc.shape, num_outputs); - NodeID w_nid = add_const_node_with_name(g, params, "Weights", w_desc, std::move(weights_accessor)); - - // Create bias nodes - NodeID b_nid = EmptyNodeID; - if(has_bias) - { - TensorDescriptor b_desc = input_tensor_desc; - b_desc.shape = TensorShape(num_outputs); - b_nid = add_const_node_with_name(g, params, "Bias", b_desc, std::move(bias_accessor)); - } - - // Create convolution node and connect - NodeID fc_nid = g.add_node(num_outputs); - g.add_connection(input.node_id, input.index, fc_nid, 0); - g.add_connection(w_nid, 0, fc_nid, 1); - if(has_bias) - { - g.add_connection(b_nid, 0, fc_nid, 2); - } - - set_node_params(g, fc_nid, params); - - return fc_nid; -} - -NodeID GraphBuilder::add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info) -{ - return create_simple_single_input_output_node(g, params, input, norm_info); -} - -NodeID GraphBuilder::add_pooling_node(Graph &g, NodeParams params, NodeIdxPair input, PoolingLayerInfo pool_info) -{ - return create_simple_single_input_output_node(g, params, input, pool_info); -} - -NodeID GraphBuilder::add_reshape_node(Graph &g, NodeParams params, NodeIdxPair input, TensorShape shape) -{ - return create_simple_single_input_output_node(g, params, input, shape); -} - -NodeID GraphBuilder::add_softmax_node(Graph &g, NodeParams params, NodeIdxPair input, float beta) -{ - return create_simple_single_input_output_node(g, params, input, beta); -} - -NodeID GraphBuilder::add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis) -{ - return create_simple_single_input_output_node(g, params, input, num_splits, axis); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/GraphContext.cpp b/src/graph2/GraphContext.cpp deleted file mode 100644 index 08a7b68dce..0000000000 --- a/src/graph2/GraphContext.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/GraphContext.h" -#include - -namespace arm_compute -{ -namespace graph2 -{ -GraphContext::GraphContext() - : _config(), _memory_managers() -{ -} - -const GraphConfig &GraphContext::config() const -{ - return _config; -} - -void GraphContext::set_config(const GraphConfig &config) -{ - _config = config; -} - -bool GraphContext::insert_memory_management_ctx(MemoryManagerContext &&memory_ctx) -{ - Target target = memory_ctx.target; - if(target == Target::UNSPECIFIED || _memory_managers.find(target) != std::end(_memory_managers)) - { - return false; - } - - _memory_managers[target] = std::move(memory_ctx); - return true; -} - -MemoryManagerContext *GraphContext::memory_management_ctx(Target target) -{ - return (_memory_managers.find(target) != std::end(_memory_managers)) ? &_memory_managers[target] : nullptr; -} - -void GraphContext::finalize() -{ - for(auto &mm_obj : _memory_managers) - { - if(mm_obj.second.mm != nullptr) - { - mm_obj.second.mm->finalize(); - } - } -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/GraphManager.cpp b/src/graph2/GraphManager.cpp deleted file mode 100644 index a51ba61104..0000000000 --- a/src/graph2/GraphManager.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/GraphManager.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/PassManager.h" -#include "arm_compute/graph2/Utils.h" -#include "arm_compute/graph2/detail/ExecutionHelpers.h" - -namespace arm_compute -{ -namespace graph2 -{ -GraphManager::GraphManager() - : _workloads() -{ - detail::default_initialize_backends(); -} - -void GraphManager::finalize_graph(Graph &graph, GraphContext &ctx, PassManager &pm, Target target) -{ - // Setup graph context if not done manually - setup_default_graph_context(ctx); - - // Check if graph has been registered - ARM_COMPUTE_ERROR_ON_MSG(_workloads.find(graph.id()) != std::end(_workloads), "Graph is already registered!"); - - // Force target to all graph construct - // TODO (geopin01) : Support heterogeneous execution - Target forced_target = is_target_supported(target) ? target : get_default_target(); - force_target_to_graph(graph, forced_target); - - // Configure all tensors - detail::configure_all_tensors(graph); - - // Apply all mutating passes - pm.run_all(graph); - - // TODO (geopin01): Perform a graph validation - - // Perform topological sort - // FIXME : Sort nodes and pass sorted indices in configure all nodes - - // Validate all nodes - detail::validate_all_nodes(graph); - - // Configure all nodes - auto workload = detail::configure_all_nodes(graph, ctx); - ARM_COMPUTE_ERROR_ON_MSG(workload.tasks.empty(), "Could not configure all nodes!"); - - // Allocate all tensors - detail::allocate_all_tensors(graph); - - // Call accessors on all Const nodes - detail::call_all_const_node_accessors(graph); - - _workloads.insert(std::make_pair(graph.id(), std::move(workload))); - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Created workload for graph with ID : " << graph.id().get() << std::endl); - - // Finalize Graph context - ctx.finalize(); - - // Make first run - execute_graph(graph); - - // Release all unused const nodes - detail::release_unused_tensors(graph); -} - -void GraphManager::execute_graph(Graph &graph) -{ - // Check if graph is finalized - auto it = _workloads.find(graph.id()); - ARM_COMPUTE_ERROR_ON_MSG(it == std::end(_workloads), "Graph is not registered!"); - - // Call input accessors - detail::call_all_input_node_accessors(it->second); - - // Run graph - detail::call_all_tasks(it->second); - - // Call output accessors - detail::call_all_output_node_accessors(it->second); -} - -void GraphManager::invalidate_graph(Graph &graph) -{ - auto it = _workloads.find(graph.id()); - ARM_COMPUTE_ERROR_ON_MSG(it == std::end(_workloads), "Graph is not registered!"); - - _workloads.erase(it); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/INode.cpp b/src/graph2/INode.cpp deleted file mode 100644 index 28be341396..0000000000 --- a/src/graph2/INode.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/INode.h" - -#include "arm_compute/core/Error.h" -#include "arm_compute/graph2/Edge.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Tensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -// *INDENT-OFF* -// clang-format off -INode::INode() - : _graph(nullptr), _id(EmptyNodeID), _common_params({ "", Target::UNSPECIFIED}), - _outputs(), _input_edges(), _output_edges(), _assigned_target(Target::UNSPECIFIED) -{ -} -// clang-format on -// *INDENT-ON* - -void INode::set_graph(Graph *g) -{ - ARM_COMPUTE_ERROR_ON(g == nullptr); - _graph = g; -} - -void INode::set_id(NodeID id) -{ - _id = id; -} - -void INode::set_common_node_parameters(NodeParams common_params) -{ - _common_params = std::move(common_params); -} - -void INode::set_requested_target(Target target) -{ - _common_params.target = target; -} - -void INode::set_assigned_target(Target target) -{ - _assigned_target = target; -} - -void INode::set_output_tensor(TensorID tid, size_t idx) -{ - if(tid != NullTensorID && (idx < _outputs.size()) && (_graph->tensor(tid) != nullptr)) - { - ARM_COMPUTE_ERROR_ON(_graph == nullptr); - Tensor *updated_tensor = _graph->tensor(tid); - _outputs[idx] = tid; - - // Set tensor to all output edges of the node - for(auto &output_edge_id : _output_edges) - { - auto output_edge = _graph->edge(output_edge_id); - if(output_edge != nullptr) - { - // Unbind edge from current tensor - auto current_output_tensor = output_edge->tensor(); - current_output_tensor->unbind_edge(output_edge->id()); - - // Update tensor to edge and rebind tensor - output_edge->update_bound_tensor(updated_tensor); - updated_tensor->bind_edge(output_edge->id()); - } - } - } -} - -NodeID INode::id() const -{ - return _id; -} - -std::string INode::name() const -{ - return _common_params.name; -} - -const Graph *INode::graph() const -{ - return _graph; -} - -Graph *INode::graph() -{ - return _graph; -} - -const std::vector &INode::outputs() const -{ - return _outputs; -} - -const std::vector &INode::input_edges() const -{ - return _input_edges; -} - -const std::set &INode::output_edges() const -{ - return _output_edges; -} - -TensorID INode::input_id(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); - Edge *e = _graph->edge(_input_edges[idx]); - return (e != nullptr) ? e->tensor_id() : NullTensorID; -} - -TensorID INode::output_id(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - return _outputs[idx]; -} - -Tensor *INode::input(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(_graph == nullptr); - ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); - Edge *e = _graph->edge(_input_edges[idx]); - return (e != nullptr) ? e->tensor() : nullptr; -} - -Tensor *INode::output(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(_graph == nullptr); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - return _graph->tensor(_outputs[idx]); -} - -EdgeID INode::input_edge_id(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); - return _input_edges[idx]; -} - -Edge *INode::input_edge(size_t idx) const -{ - ARM_COMPUTE_ERROR_ON(_graph == nullptr); - ARM_COMPUTE_ERROR_ON(idx >= _input_edges.size()); - return _graph->edge(_input_edges[idx]); -} - -size_t INode::num_inputs() const -{ - return _input_edges.size(); -} - -size_t INode::num_outputs() const -{ - return _outputs.size(); -} - -Target INode::requested_target() const -{ - return _common_params.target; -} - -Target INode::assigned_target() const -{ - return _assigned_target; -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/PassManager.cpp b/src/graph2/PassManager.cpp deleted file mode 100644 index 2fa937bd89..0000000000 --- a/src/graph2/PassManager.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/PassManager.h" - -#include "arm_compute/graph2/Logger.h" - -namespace arm_compute -{ -namespace graph2 -{ -PassManager::PassManager() - : _passes() -{ -} - -const std::vector> &PassManager::passes() const -{ - return _passes; -} - -IGraphMutator *PassManager::pass(size_t index) -{ - return (index >= _passes.size()) ? nullptr : _passes.at(index).get(); -} - -void PassManager::append(std::unique_ptr pass) -{ - if(pass) - { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Appending mutating pass : " << pass->name() << std::endl); - _passes.push_back(std::move(pass)); - } -} - -void PassManager::clear() -{ - _passes.clear(); -} - -void PassManager::run_all(Graph &g) -{ - for(auto &pass : _passes) - { - if(pass) - { - ARM_COMPUTE_LOG_GRAPH_INFO("Running mutating pass : " << pass->name() << std::endl); - pass->mutate(g); - } - } -} - -void PassManager::run(Graph &g, size_t index) -{ - if(index >= _passes.size()) - { - return; - } - - auto &pass = _passes.at(index); - - if(pass != nullptr) - { - pass->mutate(g); - } -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/Tensor.cpp b/src/graph2/Tensor.cpp deleted file mode 100644 index c6054d716d..0000000000 --- a/src/graph2/Tensor.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/Tensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -Tensor::Tensor(TensorID id, TensorDescriptor desc) - : _id(id), _desc(desc), _handle(nullptr), _accessor(nullptr), _bound_edges() -{ -} - -TensorID Tensor::id() const -{ - return _id; -} - -TensorDescriptor &Tensor::desc() -{ - return _desc; -} - -const TensorDescriptor &Tensor::desc() const -{ - return _desc; -} - -void Tensor::set_handle(std::unique_ptr backend_tensor) -{ - _handle = std::move(backend_tensor); -} - -ITensorHandle *Tensor::handle() -{ - return _handle.get(); -} - -void Tensor::set_accessor(std::unique_ptr accessor) -{ - _accessor = std::move(accessor); -} - -ITensorAccessor *Tensor::accessor() -{ - return _accessor.get(); -} - -bool Tensor::call_accessor() -{ - // Early exit guard - if(!_accessor || !_handle) - { - return false; - } - - // Map tensor - _handle->map(true); - - // Return in case of null backend buffer - if(_handle->tensor().buffer() == nullptr) - { - return false; - } - - // Call accessor - _accessor->access_tensor(_handle->tensor()); - - // Unmap tensor - _handle->unmap(); - - return true; -} - -void Tensor::bind_edge(EdgeID eid) -{ - _bound_edges.insert(eid); -} - -void Tensor::unbind_edge(EdgeID eid) -{ - _bound_edges.erase(eid); -} - -const std::set Tensor::bound_edges() const -{ - return _bound_edges; -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/Utils.cpp b/src/graph2/Utils.cpp deleted file mode 100644 index a3e90f43bc..0000000000 --- a/src/graph2/Utils.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/Utils.h" - -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/backends/BackendRegistry.h" -#include "arm_compute/graph2/mutators/GraphMutators.h" - -namespace arm_compute -{ -namespace graph2 -{ -bool is_target_supported(Target target) -{ - return backends::BackendRegistry::get().contains(target); -} - -Target get_default_target() -{ - if(is_target_supported(Target::NEON)) - { - return Target::NEON; - } - if(is_target_supported(Target::CL)) - { - return Target::CL; - } - if(is_target_supported(Target::GC)) - { - return Target::GC; - } - ARM_COMPUTE_ERROR("No backend exists!"); -} - -void force_target_to_graph(Graph &g, Target target) -{ - auto &nodes = g.nodes(); - for(auto &node : nodes) - { - if(node) - { - node->set_assigned_target(target); - } - } - - auto &tensors = g.tensors(); - for(auto &tensor : tensors) - { - if(tensor) - { - tensor->desc().target = target; - } - } -} - -PassManager create_default_pass_manager(Target target) -{ - PassManager pm; - - if(target != Target::GC) - { - pm.append(support::cpp14::make_unique()); - pm.append(support::cpp14::make_unique()); - pm.append(support::cpp14::make_unique()); - pm.append(support::cpp14::make_unique()); - } - - return pm; -} - -/** Default setups a graph Context - * - * @param[in] ctx Context to default initialize - */ -void setup_default_graph_context(GraphContext &ctx) -{ - for(const auto &backend : backends::BackendRegistry::get().backends()) - { - backend.second->setup_backend_context(ctx); - } -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/Workload.cpp b/src/graph2/Workload.cpp deleted file mode 100644 index 3fd36fabc7..0000000000 --- a/src/graph2/Workload.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/Workload.h" - -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/ITensorHandle.h" - -namespace arm_compute -{ -namespace graph2 -{ -void ExecutionTask::operator()() -{ - if(task) - { - task->run(); - } -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/BackendRegistry.cpp b/src/graph2/backends/BackendRegistry.cpp deleted file mode 100644 index 5f1218f335..0000000000 --- a/src/graph2/backends/BackendRegistry.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/BackendRegistry.h" - -using namespace arm_compute::graph2::backends; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -BackendRegistry::BackendRegistry() - : _registered_backends() -{ -} - -BackendRegistry &BackendRegistry::get() -{ - static BackendRegistry instance; - return instance; -} - -IDeviceBackend *BackendRegistry::find_backend(Target target) -{ - ARM_COMPUTE_ERROR_ON(!contains(target)); - return _registered_backends[target].get(); -} - -bool BackendRegistry::contains(Target target) const -{ - auto it = _registered_backends.find(target); - return (it != _registered_backends.end()); -} - -const std::map> &BackendRegistry::backends() const -{ - return _registered_backends; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/backends/CL/CLDeviceBackend.cpp b/src/graph2/backends/CL/CLDeviceBackend.cpp deleted file mode 100644 index 71566d2f1f..0000000000 --- a/src/graph2/backends/CL/CLDeviceBackend.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/CL/CLDeviceBackend.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/backends/BackendRegistrar.h" -#include "arm_compute/graph2/backends/CL/CLFunctionFactory.h" -#include "arm_compute/graph2/backends/CL/CLNodeValidator.h" -#include "arm_compute/graph2/backends/CL/CLSubTensorHandle.h" -#include "arm_compute/graph2/backends/CL/CLTensorHandle.h" - -#include "arm_compute/core/TensorInfo.h" -#include "arm_compute/runtime/BlobLifetimeManager.h" -#include "arm_compute/runtime/CL/CLBufferAllocator.h" -#include "arm_compute/runtime/CL/CLScheduler.h" -#include "arm_compute/runtime/MemoryManagerOnDemand.h" -#include "arm_compute/runtime/PoolManager.h" - -#include "support/ToolchainSupport.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -namespace -{ -bool file_exists(const std::string &filename) -{ - std::ifstream file(filename); - return file.good(); -} -} // namespace - -/** Register CL backend */ -static detail::BackendRegistrar CLDeviceBackend_registrar(Target::CL); - -/** Tuner export file */ -static const std::string tuner_data_filename = "acl_tuner.csv"; - -CLDeviceBackend::CLDeviceBackend() - : _tuner(), _allocator(cl::Context::getDefault()) -{ -} - -CLDeviceBackend::~CLDeviceBackend() -{ - // TODO (geopin01) : Shouldn't call non exception safe stuff here - if(_tuner.tune_new_kernels() && !_tuner.lws_table().empty()) - { - _tuner.save_to_file(tuner_data_filename); - } -} - -void CLDeviceBackend::set_kernel_tuning(bool enable_tuning) -{ - _tuner.set_tune_new_kernels(enable_tuning); -} - -void CLDeviceBackend::initialize_backend() -{ - // Load tuner data if available - if(_tuner.lws_table().empty() && file_exists(tuner_data_filename)) - { - _tuner.load_from_file(tuner_data_filename); - } - - // Setup Scheduler - CLScheduler::get().default_init(&_tuner); - - // Create allocator with new context - _allocator = CLBufferAllocator(); -} - -void CLDeviceBackend::setup_backend_context(GraphContext &ctx) -{ - // Setup tuner - set_kernel_tuning(ctx.config().use_tuner); - - // Setup a management backend - if(ctx.memory_management_ctx(Target::CL) == nullptr) - { - MemoryManagerContext mm_ctx; - mm_ctx.target = Target::CL; - mm_ctx.mm = create_memory_manager(MemoryManagerAffinity::Buffer); - - ctx.insert_memory_management_ctx(std::move(mm_ctx)); - } -} - -std::unique_ptr CLDeviceBackend::create_tensor(const Tensor &tensor) -{ - // Get tensor descriptor - const TensorDescriptor &tensor_desc = tensor.desc(); - ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::CL); - - // Create backend tensor handle - TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type); - auto backend_tensor_handle = support::cpp14::make_unique(info); - - return std::move(backend_tensor_handle); -} - -std::unique_ptr CLDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) -{ - if(parent == nullptr) - { - return nullptr; - } - - return support::cpp14::make_unique(parent, shape, coords, extend_parent); -} - -std::unique_ptr CLDeviceBackend::configure_node(INode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring CL node with ID : " << node.id() << std::endl); - ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::CL); - - // Configure node - return CLFunctionFactory::create(&node, ctx); -} - -arm_compute::Status CLDeviceBackend::validate_node(INode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating CL node with ID : " << node.id() << std::endl); - ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::CL); - - return CLNodeValidator::validate(&node); -} - -std::shared_ptr CLDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity) -{ - if(affinity == MemoryManagerAffinity::Offset) - { - ARM_COMPUTE_LOG_GRAPH_WARNING("CL Backend does not support offset affinity memory management!"); - return nullptr; - } - - auto lifetime_mgr = std::make_shared(); - auto pool_mgr = std::make_shared(); - auto mm = std::make_shared(lifetime_mgr, pool_mgr); - - mm->set_allocator(&_allocator); - - return mm; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/CL/CLFunctionsFactory.cpp b/src/graph2/backends/CL/CLFunctionsFactory.cpp deleted file mode 100644 index 5a51b19e18..0000000000 --- a/src/graph2/backends/CL/CLFunctionsFactory.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/CL/CLFunctionFactory.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/TypePrinter.h" -#include "arm_compute/graph2/Types.h" -#include "arm_compute/graph2/backends/Utils.h" -#include "arm_compute/graph2/nodes/Nodes.h" -#include "arm_compute/runtime/CL/CLFunctions.h" - -#include "support/ToolchainSupport.h" - -using namespace arm_compute::utils::cast; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -namespace -{ -/** Returns backing tensor of a given tensor - * - * @param[in] tensor Tensor to extract the backing tensor from - * - * @return Backing tensor if present else nullptr - */ -arm_compute::ICLTensor *get_backing_tensor(arm_compute::graph2::Tensor *tensor) -{ - arm_compute::ICLTensor *backing_tensor = nullptr; - if(tensor != nullptr) - { - ARM_COMPUTE_ERROR_ON(tensor->desc().target != arm_compute::graph2::Target::CL); - // Get backing tensor handle - ITensorHandle *tensor_handle = tensor->handle(); - // Get backing tensor - backing_tensor = (tensor_handle != nullptr) ? polymorphic_cast(&tensor_handle->tensor()) : nullptr; - } - - return backing_tensor; -} - -/** Create a backend activation layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend activation layer function - */ -std::unique_ptr create_activation_layer(ActivationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL ActivationLayerNode node with ID : " << node.id() << " and Name: " << node.name() - << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const ActivationLayerInfo act_info = node.activation_info(); - - // Create function - auto func = support::cpp14::make_unique(); - func->configure(input, output, act_info); - - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLActivationLayer" - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return std::move(func); -} - -/** Create a backend batch normalization layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend batch normalization layer function - */ -std::unique_ptr create_batch_normalization_layer(BatchNormalizationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating CL BatchNormalization node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - - // TODO (geopin01) : Var and mean are compulsory, switch function to accept nullptr as beta and/or gamma - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 5); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *mean = get_backing_tensor(node.input(1)); - ICLTensor *var = get_backing_tensor(node.input(2)); - ICLTensor *beta = get_backing_tensor(node.input(3)); - ICLTensor *gamma = get_backing_tensor(node.input(4)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const float epsilon = node.epsilon(); - const ActivationLayerInfo fused_act = node.fused_activation(); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLBatchNormalizationLayer" - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Epsilon: " << epsilon << " " - << (fused_act.enabled() ? to_string(fused_act.activation()) : "") - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return std::move(func); -} - -/** Create a backend convolution layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend convolution layer function - */ -std::unique_ptr create_convolution_layer(ConvolutionLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating CL ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *weights = get_backing_tensor(node.input(1)); - ICLTensor *biases = get_backing_tensor(node.input(2)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const PadStrideInfo conv_info = node.convolution_info(); - const ConvolutionMethod conv_algorithm = node.convolution_method(); - - // Create and configure function (we assume that functions have been validated before creation) - std::shared_ptr mm = get_memory_manager(ctx, Target::CL); - std::unique_ptr func; - std::string func_name; - - if(conv_algorithm == ConvolutionMethod::WINOGRAD) - { - std::tie(func, func_name) = create_named_function( - std::string("CLWinogradConvolutionLayer"), input, weights, biases, output, conv_info); - } - else if(conv_algorithm == ConvolutionMethod::DIRECT) - { - std::tie(func, func_name) = create_named_function( - std::string("CLDirectConvolutionLayer"), input, weights, biases, output, conv_info); - } - else if(conv_algorithm == ConvolutionMethod::GEMM) - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("CLGEMMConvolutionLayer"), mm, - input, weights, biases, output, conv_info); - } - else - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("CLConvolutionLayer"), mm, - input, weights, biases, output, conv_info); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - return func; -} - -/** Create a backend layer depth concatenate function - * - * @param[in] node Node to create the backend function for - * - * @return Backend depth concatenate layer function - */ -std::unique_ptr create_depth_concatenate_layer(DepthConcatenateLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating CL DepthConcatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Return nullptr if depth concatenate is switched off - if(!node.is_enabled()) - { - return nullptr; - } - - // Extract IO and info - std::vector inputs; - for(unsigned int i = 0; i < node.num_inputs(); ++i) - { - inputs.push_back(get_backing_tensor(node.input(i))); - } - ICLTensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(inputs, output); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLDepthConcatenateLayer" - << " Data Type: " << output->info()->data_type() - << " Shape: " << output->info()->tensor_shape() - << " Num Inputs: " << inputs.size() - << std::endl); - - return std::move(func); -} - -/** Create a backend layer depth-wise convolution function - * - * @param[in] node Node to create the backend function for - * - * @return Backend depth-wise convolution layer function - */ -std::unique_ptr create_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() - << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *weights = get_backing_tensor(node.input(1)); - ICLTensor *biases = get_backing_tensor(node.input(2)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const PadStrideInfo conv_info = node.convolution_info(); - const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); - - // Create and configure function (we assume that functions have been validated before creation) - std::unique_ptr func; - std::string func_name; - if(dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) - { - std::tie(func, func_name) = create_named_function( - std::string("CLDepthwiseConvolutionLayer3x3"), input, weights, biases, output, conv_info); - } - else - { - std::tie(func, func_name) = create_named_function( - std::string("CLDepthwiseConvolutionLayer"), input, weights, biases, output, conv_info); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - return func; -} - -/** Create a backend element-wise operation layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend element-wise operation layer function - */ -std::unique_ptr create_eltwise_layer(EltwiseLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 2); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input1 = get_backing_tensor(node.input(0)); - ICLTensor *input2 = get_backing_tensor(node.input(1)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const EltwiseOperation eltwise_op = node.eltwise_operation(); - ARM_COMPUTE_ERROR_ON(input1 == nullptr); - ARM_COMPUTE_ERROR_ON(input2 == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - std::unique_ptr func = nullptr; - std::string func_name; - if(eltwise_op == EltwiseOperation::ADD) - { - std::tie(func, func_name) = create_named_function(std::string("CLArithmeticAddition"), - input1, input2, output, - ConvertPolicy::SATURATE); - } - else if(eltwise_op == EltwiseOperation::SUB) - { - std::tie(func, func_name) = create_named_function( - std::string("CLArithmeticSubtraction"), input1, input2, output, ConvertPolicy::SATURATE); - } - else if(eltwise_op == EltwiseOperation::MUL) - { - std::tie(func, func_name) = create_named_function( - std::string("CLPixelWiseMultiplication"), input1, input2, output, 1.f, ConvertPolicy::SATURATE, - RoundingPolicy::TO_NEAREST_EVEN); - } - else - { - ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input1->info()->data_type() - << " Shape : " << input1->info()->tensor_shape() - << std::endl); - - return func; -} - -/** Create a backend flatten layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend flatten layer function - */ -std::unique_ptr create_flatten_layer(FlattenLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL FlattenLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLFlattenLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend fully connected layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend fully connected layer function - */ -std::unique_ptr create_fully_connected_layer(FullyConnectedLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL FullyConnectedLayer node with ID : " << node.id() << " and Name: " << node.name() - << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *weights = get_backing_tensor(node.input(1)); - ICLTensor *biases = get_backing_tensor(node.input(2)); - ICLTensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::CL)); - func->configure(input, weights, biases, output); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(weights == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLFullyConnectedLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Biases Shape: " << biases->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend normalization layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend normalization layer function - */ -std::unique_ptr create_normalization_layer(NormalizationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL NormalizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const NormalizationLayerInfo norm_info = node.normalization_info(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, norm_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLNormalizationLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Normalization info: " << norm_info.type() - << std::endl); - - return std::move(func); -} - -/** Create a backend pooling layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend pooling layer function - */ -std::unique_ptr create_pooling_layer(PoolingLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL PoolingLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const PoolingLayerInfo pool_info = node.pooling_info(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, pool_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLPoolingLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Pooling info: " << pool_info.pool_type() - << std::endl); - - return std::move(func); -} - -/** Create a backend reshape layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend reshape layer function - */ -std::unique_ptr create_reshape_layer(ReshapeLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL ReshapeLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *output = get_backing_tensor(node.output(0)); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLReshapeLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend softmax layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend softmax layer function - */ -std::unique_ptr create_softmax_layer(SoftmaxLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating CL SoftmaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ICLTensor *input = get_backing_tensor(node.input(0)); - ICLTensor *output = get_backing_tensor(node.output(0)); - const float beta = node.beta(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::CL)); - func->configure(input, output, beta); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated CLSoftmaxLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} -} // namespace - -std::unique_ptr CLFunctionFactory::create(INode *node, GraphContext &ctx) -{ - if(node == nullptr) - { - return nullptr; - } - - NodeType type = node->type(); - switch(type) - { - case NodeType::ActivationLayer: - return create_activation_layer(*polymorphic_downcast(node)); - case NodeType::BatchNormalizationLayer: - return create_batch_normalization_layer(*polymorphic_downcast(node)); - case NodeType::ConvolutionLayer: - return create_convolution_layer(*polymorphic_downcast(node), ctx); - case NodeType::DepthConcatenateLayer: - return create_depth_concatenate_layer(*polymorphic_downcast(node)); - case NodeType::DepthwiseConvolutionLayer: - return create_depthwise_convolution_layer(*polymorphic_downcast(node)); - case NodeType::EltwiseLayer: - return create_eltwise_layer(*polymorphic_downcast(node)); - case NodeType::FlattenLayer: - return create_flatten_layer(*polymorphic_downcast(node)); - case NodeType::FullyConnectedLayer: - return create_fully_connected_layer(*polymorphic_downcast(node), ctx); - case NodeType::NormalizationLayer: - return create_normalization_layer(*polymorphic_downcast(node)); - case NodeType::PoolingLayer: - return create_pooling_layer(*polymorphic_downcast(node)); - case NodeType::ReshapeLayer: - return create_reshape_layer(*polymorphic_downcast(node)); - case NodeType::SoftmaxLayer: - return create_softmax_layer(*polymorphic_downcast(node), ctx); - default: - return nullptr; - } -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/CL/CLNodeValidator.cpp b/src/graph2/backends/CL/CLNodeValidator.cpp deleted file mode 100644 index 851285630e..0000000000 --- a/src/graph2/backends/CL/CLNodeValidator.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/CL/CLNodeValidator.h" - -#include "arm_compute/graph2/backends/ValidateHelpers.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/runtime/CL/CLFunctions.h" - -using namespace arm_compute::utils::cast; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -Status CLNodeValidator::validate(INode *node) -{ - if(node == nullptr) - { - return Status{}; - } - - NodeType type = node->type(); - switch(type) - { - case NodeType::ConvolutionLayer: - return detail::validate_convolution_layer(*polymorphic_downcast(node)); - case NodeType::DepthwiseConvolutionLayer: - return detail::validate_depthwise_convolution_layer(*polymorphic_downcast(node)); - default: - return Status{}; - } -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/CL/CLSubTensorHandle.cpp b/src/graph2/backends/CL/CLSubTensorHandle.cpp deleted file mode 100644 index 65a1ba4d5f..0000000000 --- a/src/graph2/backends/CL/CLSubTensorHandle.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/CL/CLSubTensorHandle.h" - -#include "arm_compute/core/utils/misc/Cast.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -CLSubTensorHandle::CLSubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent) - : _sub_tensor() -{ - ARM_COMPUTE_ERROR_ON(!parent_handle); - auto parent_tensor = arm_compute::utils::cast::polymorphic_downcast(&parent_handle->tensor()); - _sub_tensor = arm_compute::CLSubTensor(parent_tensor, shape, coords, extend_parent); -} - -void CLSubTensorHandle::allocate() -{ - // noop -} - -const arm_compute::ITensor &CLSubTensorHandle::tensor() const -{ - return _sub_tensor; -} - -arm_compute::ITensor &CLSubTensorHandle::tensor() -{ - return _sub_tensor; -} - -void CLSubTensorHandle::map(bool blocking) -{ - _sub_tensor.map(blocking); -} - -void CLSubTensorHandle::unmap() -{ - _sub_tensor.unmap(); -} - -void CLSubTensorHandle::release_if_unused() -{ - // noop -} - -bool CLSubTensorHandle::is_subtensor() const -{ - return true; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/CL/CLTensorHandle.cpp b/src/graph2/backends/CL/CLTensorHandle.cpp deleted file mode 100644 index 89678fb280..0000000000 --- a/src/graph2/backends/CL/CLTensorHandle.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/CL/CLTensorHandle.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -CLTensorHandle::CLTensorHandle(const ITensorInfo &info) - : _tensor() -{ - _tensor.allocator()->init(info); -} - -void CLTensorHandle::allocate() -{ - _tensor.allocator()->allocate(); -} - -const arm_compute::ITensor &CLTensorHandle::tensor() const -{ - return _tensor; -} - -arm_compute::ITensor &CLTensorHandle::tensor() -{ - return _tensor; -} - -void CLTensorHandle::map(bool blocking) -{ - _tensor.map(blocking); -} - -void CLTensorHandle::unmap() -{ - _tensor.unmap(); -} - -void CLTensorHandle::release_if_unused() -{ - // TODO (geopin01): Release tensor only if all sub-tensors are marked as not used - if(!_tensor.is_used()) - { - _tensor.allocator()->free(); - } -} - -bool CLTensorHandle::is_subtensor() const -{ - return false; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/GLES/GCDeviceBackend.cpp b/src/graph2/backends/GLES/GCDeviceBackend.cpp deleted file mode 100644 index 7dab422a82..0000000000 --- a/src/graph2/backends/GLES/GCDeviceBackend.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/GLES/GCDeviceBackend.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/backends/BackendRegistrar.h" -#include "arm_compute/graph2/backends/GLES/GCFunctionFactory.h" -#include "arm_compute/graph2/backends/GLES/GCNodeValidator.h" -#include "arm_compute/graph2/backends/GLES/GCTensorHandle.h" - -#include "arm_compute/core/TensorInfo.h" -#include "arm_compute/runtime/BlobLifetimeManager.h" -#include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h" -#include "arm_compute/runtime/GLES_COMPUTE/GCScheduler.h" -#include "arm_compute/runtime/MemoryManagerOnDemand.h" -#include "arm_compute/runtime/PoolManager.h" - -#include "support/ToolchainSupport.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -/** Register GLES backend */ -static detail::BackendRegistrar GCDeviceBackend_registrar(Target::GC); - -GCDeviceBackend::GCDeviceBackend() - : _allocator() -{ -} - -void GCDeviceBackend::initialize_backend() -{ - // Setup Scheduler - GCScheduler::get().default_init(); -} - -void GCDeviceBackend::setup_backend_context(GraphContext &ctx) -{ - // Setup a management backend - if(ctx.memory_management_ctx(Target::GC) == nullptr) - { - MemoryManagerContext mm_ctx; - mm_ctx.target = Target::GC; - mm_ctx.mm = create_memory_manager(MemoryManagerAffinity::Buffer); - - ctx.insert_memory_management_ctx(std::move(mm_ctx)); - } -} - -std::unique_ptr GCDeviceBackend::create_tensor(const Tensor &tensor) -{ - // Get tensor descriptor - const TensorDescriptor &tensor_desc = tensor.desc(); - ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::GC); - - // Create backend tensor handle - TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type); - auto backend_tensor_handle = support::cpp14::make_unique(info); - - return std::move(backend_tensor_handle); -} - -std::unique_ptr GCDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) -{ - ARM_COMPUTE_UNUSED(parent, shape, coords, extend_parent); - ARM_COMPUTE_ERROR("GLES backend has no sub-tensor support!"); - return nullptr; -} - -std::unique_ptr GCDeviceBackend::configure_node(INode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring GC node with ID : " << node.id() << std::endl); - ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::GC); - - // Configure node - return GCFunctionFactory::create(&node, ctx); -} - -arm_compute::Status GCDeviceBackend::validate_node(INode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GC node with ID : " << node.id() << std::endl); - ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::GC); - - return GCNodeValidator::validate(&node); -} - -std::shared_ptr GCDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity) -{ - if(affinity == MemoryManagerAffinity::Offset) - { - ARM_COMPUTE_LOG_GRAPH_WARNING("GC Backend does not support offset affinity memory management!"); - return nullptr; - } - - auto lifetime_mgr = std::make_shared(); - auto pool_mgr = std::make_shared(); - auto mm = std::make_shared(lifetime_mgr, pool_mgr); - - mm->set_allocator(&_allocator); - - return mm; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/GLES/GCFunctionsFactory.cpp b/src/graph2/backends/GLES/GCFunctionsFactory.cpp deleted file mode 100644 index 24ab2bce37..0000000000 --- a/src/graph2/backends/GLES/GCFunctionsFactory.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/GLES/GCFunctionFactory.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/TypePrinter.h" -#include "arm_compute/graph2/Types.h" -#include "arm_compute/graph2/backends/Utils.h" -#include "arm_compute/graph2/nodes/Nodes.h" -#include "arm_compute/runtime/GLES_COMPUTE/GCFunctions.h" - -#include "support/ToolchainSupport.h" - -using namespace arm_compute::utils::cast; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -namespace -{ -/** Returns backing tensor of a given tensor - * - * @param[in] tensor Tensor to extract the backing tensor from - * - * @return Backing tensor if present else nullptr - */ -arm_compute::IGCTensor *get_backing_tensor(arm_compute::graph2::Tensor *tensor) -{ - arm_compute::IGCTensor *backing_tensor = nullptr; - if(tensor != nullptr) - { - ARM_COMPUTE_ERROR_ON(tensor->desc().target != arm_compute::graph2::Target::GC); - // Get backing tensor handle - ITensorHandle *tensor_handle = tensor->handle(); - // Get backing tensor - backing_tensor = (tensor_handle != nullptr) ? polymorphic_cast(&tensor_handle->tensor()) : nullptr; - } - - return backing_tensor; -} - -/** Create a backend activation layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend activation layer function - */ -std::unique_ptr create_activation_layer(ActivationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC ActivationLayerNode node with ID : " << node.id() << " and Name: " << node.name() - << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const ActivationLayerInfo act_info = node.activation_info(); - - // Create function - auto func = support::cpp14::make_unique(); - func->configure(input, output, act_info); - - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCActivationLayer" - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return std::move(func); -} - -/** Create a backend batch normalization layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend batch normalization layer function - */ -std::unique_ptr create_batch_normalization_layer(BatchNormalizationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating GC BatchNormalization node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - - // TODO (geopin01) : Var and mean are compulsory, switch function to accept nullptr as beta and/or gamma - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 5); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *mean = get_backing_tensor(node.input(1)); - IGCTensor *var = get_backing_tensor(node.input(2)); - IGCTensor *beta = get_backing_tensor(node.input(3)); - IGCTensor *gamma = get_backing_tensor(node.input(4)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const float epsilon = node.epsilon(); - const ActivationLayerInfo fused_act = node.fused_activation(); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCBatchNormalizationLayer" - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Epsilon: " << epsilon << " " - << (fused_act.enabled() ? to_string(fused_act.activation()) : "") - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return std::move(func); -} - -/** Create a backend convolution layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend convolution layer function - */ -std::unique_ptr create_convolution_layer(ConvolutionLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating GC ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *weights = get_backing_tensor(node.input(1)); - IGCTensor *biases = get_backing_tensor(node.input(2)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const PadStrideInfo conv_info = node.convolution_info(); - const ConvolutionMethod conv_algorithm = node.convolution_method(); - - // Create and configure function (we assume that functions have been validated before creation) - std::shared_ptr mm = get_memory_manager(ctx, Target::GC); - std::unique_ptr func; - std::string func_name; - - if(conv_algorithm == ConvolutionMethod::DIRECT) - { - std::tie(func, func_name) = create_named_function( - std::string("GCDirectConvolutionLayer"), input, weights, biases, output, conv_info); - } - else - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("GCConvolutionLayer"), mm, - input, weights, biases, output, conv_info); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - return func; -} - -/** Create a backend layer depth concatenate function - * - * @param[in] node Node to create the backend function for - * - * @return Backend depth concatenate layer function - */ -std::unique_ptr create_depth_concatenate_layer(DepthConcatenateLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating GC DepthConcatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Return nullptr if depth concatenate is switched off - if(!node.is_enabled()) - { - return nullptr; - } - - // Extract IO and info - std::vector inputs; - for(unsigned int i = 0; i < node.num_inputs(); ++i) - { - inputs.push_back(get_backing_tensor(node.input(i))); - } - IGCTensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(inputs, output); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCDepthConcatenateLayer" - << " Data Type: " << output->info()->data_type() - << " Shape: " << output->info()->tensor_shape() - << " Num Inputs: " << inputs.size() - << std::endl); - - return std::move(func); -} - -/** Create a backend layer depth-wise convolution function - * - * @param[in] node Node to create the backend function for - * - * @return Backend depth-wise convolution layer function - */ -std::unique_ptr create_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() - << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *weights = get_backing_tensor(node.input(1)); - IGCTensor *biases = get_backing_tensor(node.input(2)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const PadStrideInfo conv_info = node.convolution_info(); - const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); - - // Create and configure function (we assume that functions have been validated before creation) - std::unique_ptr func; - std::string func_name; - if(dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) - { - std::tie(func, func_name) = create_named_function( - std::string("GCDepthwiseConvolutionLayer3x3"), input, weights, biases, output, conv_info); - } - else - { - ARM_COMPUTE_ERROR("Generic DepthwiseConvolutionLayer is not supported in GLES backend"); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - return func; -} - -/** Create a backend element-wise operation layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend element-wise operation layer function - */ -std::unique_ptr create_eltwise_layer(EltwiseLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 2); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input1 = get_backing_tensor(node.input(0)); - IGCTensor *input2 = get_backing_tensor(node.input(1)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const EltwiseOperation eltwise_op = node.eltwise_operation(); - ARM_COMPUTE_ERROR_ON(input1 == nullptr); - ARM_COMPUTE_ERROR_ON(input2 == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - std::unique_ptr func = nullptr; - std::string func_name; - if(eltwise_op == EltwiseOperation::ADD) - { - std::tie(func, func_name) = create_named_function(std::string("GCArithmeticAddition"), - input1, input2, output, - ConvertPolicy::SATURATE); - } - else if(eltwise_op == EltwiseOperation::SUB) - { - ARM_COMPUTE_ERROR("Arithmetic subtraction is not supported in GLES backend"); - } - else if(eltwise_op == EltwiseOperation::MUL) - { - std::tie(func, func_name) = create_named_function( - std::string("GCPixelWiseMultiplication"), input1, input2, output, 1.f); - } - else - { - ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input1->info()->data_type() - << " Shape : " << input1->info()->tensor_shape() - << std::endl); - - return func; -} - -/** Create a backend fully connected layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend fully connected layer function - */ -std::unique_ptr create_fully_connected_layer(FullyConnectedLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC FullyConnectedLayer node with ID : " << node.id() << " and Name: " << node.name() - << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *weights = get_backing_tensor(node.input(1)); - IGCTensor *biases = get_backing_tensor(node.input(2)); - IGCTensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::GC)); - func->configure(input, weights, biases, output); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(weights == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCFullyConnectedLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Biases Shape: " << biases->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend normalization layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend normalization layer function - */ -std::unique_ptr create_normalization_layer(NormalizationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC NormalizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const NormalizationLayerInfo norm_info = node.normalization_info(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, norm_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCNormalizationLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Normalization info: " << norm_info.type() - << std::endl); - - return std::move(func); -} - -/** Create a backend pooling layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend pooling layer function - */ -std::unique_ptr create_pooling_layer(PoolingLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC PoolingLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const PoolingLayerInfo pool_info = node.pooling_info(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, pool_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCPoolingLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Pooling info: " << pool_info.pool_type() - << std::endl); - - return std::move(func); -} - -/** Create a backend softmax layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend softmax layer function - */ -std::unique_ptr create_softmax_layer(SoftmaxLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE( - "Creating GC SoftmaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - IGCTensor *input = get_backing_tensor(node.input(0)); - IGCTensor *output = get_backing_tensor(node.output(0)); - const float beta = node.beta(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::CL)); - func->configure(input, output, beta); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated GCSoftmaxLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} -} // namespace - -std::unique_ptr GCFunctionFactory::create(INode *node, GraphContext &ctx) -{ - if(node == nullptr) - { - return nullptr; - } - - NodeType type = node->type(); - switch(type) - { - case NodeType::ActivationLayer: - return create_activation_layer(*polymorphic_downcast(node)); - case NodeType::BatchNormalizationLayer: - return create_batch_normalization_layer(*polymorphic_downcast(node)); - case NodeType::ConvolutionLayer: - return create_convolution_layer(*polymorphic_downcast(node), ctx); - case NodeType::DepthConcatenateLayer: - return create_depth_concatenate_layer(*polymorphic_downcast(node)); - case NodeType::DepthwiseConvolutionLayer: - return create_depthwise_convolution_layer(*polymorphic_downcast(node)); - case NodeType::EltwiseLayer: - return create_eltwise_layer(*polymorphic_downcast(node)); - case NodeType::FullyConnectedLayer: - return create_fully_connected_layer(*polymorphic_downcast(node), ctx); - case NodeType::NormalizationLayer: - return create_normalization_layer(*polymorphic_downcast(node)); - case NodeType::PoolingLayer: - return create_pooling_layer(*polymorphic_downcast(node)); - case NodeType::SoftmaxLayer: - return create_softmax_layer(*polymorphic_downcast(node), ctx); - default: - return nullptr; - } -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/GLES/GCNodeValidator.cpp b/src/graph2/backends/GLES/GCNodeValidator.cpp deleted file mode 100644 index b8daae566d..0000000000 --- a/src/graph2/backends/GLES/GCNodeValidator.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/GLES/GCNodeValidator.h" - -#include "arm_compute/graph2/backends/ValidateHelpers.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/runtime/GLES_COMPUTE/GCFunctions.h" - -using namespace arm_compute::utils::cast; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -namespace -{ -/** Validates a Depthwise Convolution layer node - * - * @param[in] node Node to validate - * - * @return Status - */ -Status validate_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GCDepthwiseConvolutionLayer 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)); - ARM_COMPUTE_ERROR_ON(weights == nullptr); - - // TODO (geopin01) : Switch when validation is implemented - // Validate function - ARM_COMPUTE_RETURN_ERROR_ON_MSG(weights->tensor_shape().x() != 3 && weights->tensor_shape().y() != 3, "Unsupported depthwise convolution"); - node.set_depthwise_convolution_method(DepthwiseConvolutionMethod::OPTIMIZED_3x3); - - return Status{}; -} -/** Validates a Convolution layer node - * - * @param[in] node Node to validate - * - * @return Status - */ -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 *weights = detail::get_backing_tensor_info(node.input(1)); - const PadStrideInfo conv_info = node.convolution_info(); - const ConvolutionMethod conv_algorithm = node.convolution_method(); - - // Validate function - if(conv_algorithm == ConvolutionMethod::DIRECT) - { - bool is_square = weights->tensor_shape().x() == weights->tensor_shape().y(); - bool is_direct = (weights->tensor_shape().x() == 1) || (weights->tensor_shape().x() == 3) || (weights->tensor_shape().x() == 5); - bool is_correct_stride = (conv_info.stride().first) <= 2 && (conv_info.stride().second <= 2); - if(!(is_square && is_direct && is_correct_stride)) - { - node.set_convolution_method(ConvolutionMethod::DEFAULT); - } - } - - return Status{}; -} -} // namespace - -Status GCNodeValidator::validate(INode *node) -{ - if(node == nullptr) - { - return Status{}; - } - - NodeType type = node->type(); - switch(type) - { - case NodeType::ConvolutionLayer: - return validate_convolution_layer(*polymorphic_downcast(node)); - case NodeType::DepthwiseConvolutionLayer: - return validate_depthwise_convolution_layer(*polymorphic_downcast(node)); - case NodeType::FlattenLayer: - return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation"); - case NodeType::ReshapeLayer: - return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported operation"); - default: - return Status{}; - } -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/GLES/GCTensorHandle.cpp b/src/graph2/backends/GLES/GCTensorHandle.cpp deleted file mode 100644 index 2165cd2de6..0000000000 --- a/src/graph2/backends/GLES/GCTensorHandle.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/GLES/GCTensorHandle.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -GCTensorHandle::GCTensorHandle(const ITensorInfo &info) - : _tensor() -{ - _tensor.allocator()->init(info); -} - -void GCTensorHandle::allocate() -{ - _tensor.allocator()->allocate(); -} - -const arm_compute::ITensor &GCTensorHandle::tensor() const -{ - return _tensor; -} - -arm_compute::ITensor &GCTensorHandle::tensor() -{ - return _tensor; -} - -void GCTensorHandle::map(bool blocking) -{ - _tensor.map(blocking); -} - -void GCTensorHandle::unmap() -{ - _tensor.unmap(); -} - -void GCTensorHandle::release_if_unused() -{ - // TODO (geopin01): Release tensor only if all sub-tensors are marked as not used - if(!_tensor.is_used()) - { - _tensor.allocator()->free(); - } -} - -bool GCTensorHandle::is_subtensor() const -{ - return false; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/NEON/NEDeviceBackend.cpp b/src/graph2/backends/NEON/NEDeviceBackend.cpp deleted file mode 100644 index 6cb507b4f1..0000000000 --- a/src/graph2/backends/NEON/NEDeviceBackend.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/NEON/NEDeviceBackend.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/INode.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/backends/BackendRegistrar.h" -#include "arm_compute/graph2/backends/NEON/NEFunctionFactory.h" -#include "arm_compute/graph2/backends/NEON/NENodeValidator.h" -#include "arm_compute/graph2/backends/NEON/NESubTensorHandle.h" -#include "arm_compute/graph2/backends/NEON/NETensorHandle.h" - -#include "arm_compute/core/TensorInfo.h" -#include "arm_compute/runtime/Allocator.h" -#include "arm_compute/runtime/BlobLifetimeManager.h" -#include "arm_compute/runtime/MemoryManagerOnDemand.h" -#include "arm_compute/runtime/OffsetLifetimeManager.h" -#include "arm_compute/runtime/PoolManager.h" -#include "arm_compute/runtime/Scheduler.h" - -#include "support/ToolchainSupport.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -/** Register NEON backend */ -static detail::BackendRegistrar NEDeviceBackend_registrar(Target::NEON); - -NEDeviceBackend::NEDeviceBackend() - : _allocator() -{ -} - -void NEDeviceBackend::initialize_backend() -{ -} - -void NEDeviceBackend::setup_backend_context(GraphContext &ctx) -{ - // Set number of threads - Scheduler::get().set_num_threads(ctx.config().num_threads); - - // Create function level memory manager - if(ctx.memory_management_ctx(Target::NEON) == nullptr) - { - MemoryManagerContext mm_ctx; - mm_ctx.target = Target::NEON; - mm_ctx.mm = create_memory_manager(MemoryManagerAffinity::Buffer); - - ctx.insert_memory_management_ctx(std::move(mm_ctx)); - } -} - -std::unique_ptr NEDeviceBackend::create_tensor(const Tensor &tensor) -{ - // Get tensor descriptor - const TensorDescriptor &tensor_desc = tensor.desc(); - ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::NEON); - - // Create backend tensor handle - TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type); - auto backend_tensor_handle = support::cpp14::make_unique(info); - - return std::move(backend_tensor_handle); -} - -std::unique_ptr NEDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) -{ - if(parent == nullptr) - { - return nullptr; - } - - return support::cpp14::make_unique(parent, shape, coords, extend_parent); -} - -std::unique_ptr NEDeviceBackend::configure_node(INode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring NEON node with ID : " << node.id() << std::endl); - ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::NEON); - - // Configure node - return NEFunctionFactory::create(&node, ctx); -} - -arm_compute::Status NEDeviceBackend::validate_node(INode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating NEON node with ID : " << node.id() << std::endl); - ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::NEON); - - return NENodeValidator::validate(&node); -} - -std::shared_ptr NEDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity) -{ - std::shared_ptr lifetime_mgr = nullptr; - if(affinity == MemoryManagerAffinity::Buffer) - { - lifetime_mgr = std::make_shared(); - } - else - { - lifetime_mgr = std::make_shared(); - } - auto pool_mgr = std::make_shared(); - auto mm = std::make_shared(lifetime_mgr, pool_mgr); - - mm->set_allocator(&_allocator); - - return mm; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/NEON/NEFunctionFactory.cpp b/src/graph2/backends/NEON/NEFunctionFactory.cpp deleted file mode 100644 index 933210377d..0000000000 --- a/src/graph2/backends/NEON/NEFunctionFactory.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/NEON/NEFunctionFactory.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/TypePrinter.h" -#include "arm_compute/graph2/backends/Utils.h" -#include "arm_compute/graph2/nodes/Nodes.h" -#include "arm_compute/runtime/NEON/NEFunctions.h" -#include "support/ToolchainSupport.h" - -using namespace arm_compute::utils::cast; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -namespace -{ -/** Returns backing tensor of a given tensor - * - * @param[in] tensor Tensor to extract the backing tensor from - * - * @return Backing tensor if present else nullptr - */ -arm_compute::ITensor *get_backing_tensor(arm_compute::graph2::Tensor *tensor) -{ - return ((tensor == nullptr) || (tensor->handle() == nullptr)) ? nullptr : &tensor->handle()->tensor(); -} - -/** Create a backend activation layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend activation layer function - */ -std::unique_ptr create_activation_layer(ActivationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON ActivationLayerNode node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *output = get_backing_tensor(node.output(0)); - const ActivationLayerInfo act_info = node.activation_info(); - - // Create function - auto func = support::cpp14::make_unique(); - func->configure(input, output, act_info); - - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEActivationLayer" - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Activation function: " << act_info.activation() - << " a: " << act_info.a() - << " b: " << act_info.b() - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return std::move(func); -} - -/** Create a backend batch normalization layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend batch normalization layer function - */ -std::unique_ptr create_batch_normalization_layer(BatchNormalizationLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON BatchNormalization node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - - // TODO (geopin01) : Var and mean are compulsory, switch function to accept nullptr as beta and/or gamma - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 5); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *mean = get_backing_tensor(node.input(1)); - ITensor *var = get_backing_tensor(node.input(2)); - ITensor *beta = get_backing_tensor(node.input(3)); - ITensor *gamma = get_backing_tensor(node.input(4)); - ITensor *output = get_backing_tensor(node.output(0)); - const float epsilon = node.epsilon(); - const ActivationLayerInfo fused_act = node.fused_activation(); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, mean, var, beta, gamma, epsilon, fused_act); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEBatchNormalizationLayer" - << " Data Type: " << input->info()->data_type() - << " Shape: " << input->info()->tensor_shape() - << " Epsilon: " << epsilon << " " - << (fused_act.enabled() ? to_string(fused_act.activation()) : "") - << " InPlace : " << is_in_place_operation(input, output) - << std::endl); - - return std::move(func); -} - -/** Create a backend convolution layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend convolution layer function - */ -std::unique_ptr create_convolution_layer(ConvolutionLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON ConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *weights = get_backing_tensor(node.input(1)); - ITensor *biases = get_backing_tensor(node.input(2)); - ITensor *output = get_backing_tensor(node.output(0)); - const PadStrideInfo conv_info = node.convolution_info(); - const ConvolutionMethod conv_algorithm = node.convolution_method(); - - // Create and configure function (we assume that functions have been validated before creation) - std::shared_ptr mm = get_memory_manager(ctx, Target::NEON); - std::unique_ptr func; - std::string func_name; - if(conv_algorithm == ConvolutionMethod::DIRECT) - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEDirectConvolutionLayer"), mm, - input, weights, biases, output, conv_info); - } - else if(conv_algorithm == ConvolutionMethod::GEMM) - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEGEMMConvolutionLayer"), mm, - input, weights, biases, output, conv_info); - } - else if(conv_algorithm == ConvolutionMethod::WINOGRAD) - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEWinogradLayer"), mm, - input, weights, biases, output, conv_info); - } - else - { - std::tie(func, func_name) = create_named_memory_managed_function(std::string("NEConvolutionLayer"), mm, - input, weights, biases, output, conv_info); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - return func; -} - -/** Create a backend layer depth concatenate function - * - * @param[in] node Node to create the backend function for - * - * @return Backend depth concatenate layer function - */ -std::unique_ptr create_depth_concatenate_layer(DepthConcatenateLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON DepthConcatenate node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Return nullptr if depth concatenate is switched off - if(!node.is_enabled()) - { - return nullptr; - } - - // Extract IO and info - std::vector inputs; - for(unsigned int i = 0; i < node.num_inputs(); ++i) - { - inputs.push_back(get_backing_tensor(node.input(i))); - } - ITensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(inputs, output); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEDepthConcatenateLayer" - << " Data Type: " << output->info()->data_type() - << " Shape: " << output->info()->tensor_shape() - << " Num Inputs: " << inputs.size() - << std::endl); - - return std::move(func); -} - -/** Create a backend layer depth-wise convolution function - * - * @param[in] node Node to create the backend function for - * - * @return Backend depth-wise convolution layer function - */ -std::unique_ptr create_depthwise_convolution_layer(DepthwiseConvolutionLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON DepthwiseConvolutionLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *weights = get_backing_tensor(node.input(1)); - ITensor *biases = get_backing_tensor(node.input(2)); - ITensor *output = get_backing_tensor(node.output(0)); - const PadStrideInfo conv_info = node.convolution_info(); - const DepthwiseConvolutionMethod dwc_algorithm = node.depthwise_convolution_method(); - - // Create and configure function (we assume that functions have been validated before creation) - std::unique_ptr func; - std::string func_name; - if(dwc_algorithm == DepthwiseConvolutionMethod::OPTIMIZED_3x3) - { - std::tie(func, func_name) = create_named_function(std::string("NEDepthwiseConvolutionLayer3x3"), - input, weights, biases, output, conv_info); - } - else - { - std::tie(func, func_name) = create_named_function(std::string("NEDepthwiseConvolutionLayer"), - input, weights, biases, output, conv_info); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - return func; -} - -/** Create a backend element-wise operation layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend element-wise operation layer function - */ -std::unique_ptr create_eltwise_layer(EltwiseLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON EltwiseLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 2); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input1 = get_backing_tensor(node.input(0)); - ITensor *input2 = get_backing_tensor(node.input(1)); - ITensor *output = get_backing_tensor(node.output(0)); - const EltwiseOperation eltwise_op = node.eltwise_operation(); - ARM_COMPUTE_ERROR_ON(input1 == nullptr); - ARM_COMPUTE_ERROR_ON(input2 == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - std::unique_ptr func = nullptr; - std::string func_name; - if(eltwise_op == EltwiseOperation::ADD) - { - std::tie(func, func_name) = create_named_function(std::string("NEArithmeticAddition"), - input1, input2, output, ConvertPolicy::SATURATE); - } - else if(eltwise_op == EltwiseOperation::SUB) - { - std::tie(func, func_name) = create_named_function(std::string("NEArithmeticSubtraction"), - input1, input2, output, ConvertPolicy::SATURATE); - } - else if(eltwise_op == EltwiseOperation::MUL) - { - std::tie(func, func_name) = create_named_function(std::string("NEPixelWiseMultiplication"), - input1, input2, output, 1.f, - ConvertPolicy::SATURATE, RoundingPolicy::TO_NEAREST_EVEN); - } - else - { - ARM_COMPUTE_ERROR("Unsupported element-wise operation!"); - } - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated " << func_name - << " Data Type: " << input1->info()->data_type() - << " Shape : " << input1->info()->tensor_shape() - << std::endl); - - return func; -} - -/** Create a backend flatten layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend flatten layer function - */ -std::unique_ptr create_flatten_layer(FlattenLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON FlattenLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEFlattenLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend fully connected layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend fully connected layer function - */ -std::unique_ptr create_fully_connected_layer(FullyConnectedLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON FullyConnectedLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 3); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *weights = get_backing_tensor(node.input(1)); - ITensor *biases = get_backing_tensor(node.input(2)); - ITensor *output = get_backing_tensor(node.output(0)); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::NEON)); - func->configure(input, weights, biases, output); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(weights == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEFullyConnectedLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Weights shape: " << weights->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend normalization layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend normalization layer function - */ -std::unique_ptr create_normalization_layer(NormalizationLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON NormalizationLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *output = get_backing_tensor(node.output(0)); - const NormalizationLayerInfo norm_info = node.normalization_info(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::NEON)); - func->configure(input, output, norm_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NENormalizationLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Normalization info: " << norm_info.type() - << std::endl); - - return std::move(func); -} - -/** Create a backend pooling layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend pooling layer function - */ -std::unique_ptr create_pooling_layer(PoolingLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON PoolingLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *output = get_backing_tensor(node.output(0)); - const PoolingLayerInfo pool_info = node.pooling_info(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output, pool_info); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEPoolingLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << " Pooling info: " << pool_info.pool_type() - << std::endl); - - return std::move(func); -} - -/** Create a backend reshape layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend reshape layer function - */ -std::unique_ptr create_reshape_layer(ReshapeLayerNode &node) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON ReshapeLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *output = get_backing_tensor(node.output(0)); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(); - func->configure(input, output); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NEReshapeLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} - -/** Create a backend softmax layer function - * - * @param[in] node Node to create the backend function for - * - * @return Backend softmax layer function - */ -std::unique_ptr create_softmax_layer(SoftmaxLayerNode &node, GraphContext &ctx) -{ - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Creating NEON SoftmaxLayer node with ID : " << node.id() << " and Name: " << node.name() << std::endl); - ARM_COMPUTE_ERROR_ON(node.num_inputs() != 1); - ARM_COMPUTE_ERROR_ON(node.num_outputs() != 1); - - // Extract IO and info - ITensor *input = get_backing_tensor(node.input(0)); - ITensor *output = get_backing_tensor(node.output(0)); - const float beta = node.beta(); - ARM_COMPUTE_ERROR_ON(input == nullptr); - ARM_COMPUTE_ERROR_ON(output == nullptr); - - // Create and configure function - auto func = support::cpp14::make_unique(get_memory_manager(ctx, Target::NEON)); - func->configure(input, output, beta); - - // Log info - ARM_COMPUTE_LOG_GRAPH_INFO("Instantiated NESoftmaxLayer" - << " Data Type: " << input->info()->data_type() - << " Input shape: " << input->info()->tensor_shape() - << " Output shape: " << output->info()->tensor_shape() - << std::endl); - - return std::move(func); -} -} // namespace - -std::unique_ptr NEFunctionFactory::create(INode *node, GraphContext &ctx) -{ - if(node == nullptr) - { - return nullptr; - } - - NodeType type = node->type(); - switch(type) - { - case NodeType::ActivationLayer: - return create_activation_layer(*polymorphic_downcast(node)); - case NodeType::BatchNormalizationLayer: - return create_batch_normalization_layer(*polymorphic_downcast(node)); - case NodeType::ConvolutionLayer: - return create_convolution_layer(*polymorphic_downcast(node), ctx); - case NodeType::DepthConcatenateLayer: - return create_depth_concatenate_layer(*polymorphic_downcast(node)); - case NodeType::DepthwiseConvolutionLayer: - return create_depthwise_convolution_layer(*polymorphic_downcast(node)); - case NodeType::EltwiseLayer: - return create_eltwise_layer(*polymorphic_downcast(node)); - case NodeType::FlattenLayer: - return create_flatten_layer(*polymorphic_downcast(node)); - case NodeType::FullyConnectedLayer: - return create_fully_connected_layer(*polymorphic_downcast(node), ctx); - case NodeType::NormalizationLayer: - return create_normalization_layer(*polymorphic_downcast(node), ctx); - case NodeType::PoolingLayer: - return create_pooling_layer(*polymorphic_downcast(node)); - case NodeType::ReshapeLayer: - return create_reshape_layer(*polymorphic_downcast(node)); - case NodeType::SoftmaxLayer: - return create_softmax_layer(*polymorphic_downcast(node), ctx); - default: - return nullptr; - } -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/NEON/NENodeValidator.cpp b/src/graph2/backends/NEON/NENodeValidator.cpp deleted file mode 100644 index 4620f4cd87..0000000000 --- a/src/graph2/backends/NEON/NENodeValidator.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/NEON/NENodeValidator.h" - -#include "arm_compute/graph2/backends/ValidateHelpers.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/runtime/NEON/NEFunctions.h" - -using namespace arm_compute::utils::cast; - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -Status NENodeValidator::validate(INode *node) -{ - if(node == nullptr) - { - return Status{}; - } - - NodeType type = node->type(); - switch(type) - { - case NodeType::ConvolutionLayer: - return detail::validate_convolution_layer(*polymorphic_downcast(node)); - case NodeType::DepthwiseConvolutionLayer: - return detail::validate_depthwise_convolution_layer(*polymorphic_downcast(node)); - - default: - return Status{}; - } -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/NEON/NESubTensorHandle.cpp b/src/graph2/backends/NEON/NESubTensorHandle.cpp deleted file mode 100644 index 1cd15be29c..0000000000 --- a/src/graph2/backends/NEON/NESubTensorHandle.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/NEON/NESubTensorHandle.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -NESubTensorHandle::NESubTensorHandle(ITensorHandle *parent_handle, const TensorShape &shape, const Coordinates &coords, bool extend_parent) - : _sub_tensor() -{ - ARM_COMPUTE_ERROR_ON(!parent_handle); - _sub_tensor = arm_compute::SubTensor(&parent_handle->tensor(), shape, coords, extend_parent); -} - -void NESubTensorHandle::allocate() -{ - // noop -} - -const arm_compute::ITensor &NESubTensorHandle::tensor() const -{ - return _sub_tensor; -} - -arm_compute::ITensor &NESubTensorHandle::tensor() -{ - return _sub_tensor; -} - -void NESubTensorHandle::map(bool blocking) -{ - ARM_COMPUTE_UNUSED(blocking); -} - -void NESubTensorHandle::unmap() -{ - // noop -} - -void NESubTensorHandle::release_if_unused() -{ - // noop -} - -bool NESubTensorHandle::is_subtensor() const -{ - return true; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/backends/NEON/NETensorHandle.cpp b/src/graph2/backends/NEON/NETensorHandle.cpp deleted file mode 100644 index 0b901c3497..0000000000 --- a/src/graph2/backends/NEON/NETensorHandle.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/backends/NEON/NETensorHandle.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace backends -{ -NETensorHandle::NETensorHandle(const ITensorInfo &info) - : _tensor() -{ - _tensor.allocator()->init(info); -} - -void NETensorHandle::allocate() -{ - _tensor.allocator()->allocate(); -} - -const arm_compute::ITensor &NETensorHandle::tensor() const -{ - return _tensor; -} - -arm_compute::ITensor &NETensorHandle::tensor() -{ - return _tensor; -} - -void NETensorHandle::map(bool blocking) -{ - ARM_COMPUTE_UNUSED(blocking); -} - -void NETensorHandle::unmap() -{ -} - -void NETensorHandle::release_if_unused() -{ - // TODO (geopin01): Release tensor only if all sub-tensors are marked as not used - if(!_tensor.is_used()) - { - _tensor.allocator()->free(); - } -} - -bool NETensorHandle::is_subtensor() const -{ - return false; -} -} // namespace backends -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/detail/ExecutionHelpers.cpp b/src/graph2/detail/ExecutionHelpers.cpp deleted file mode 100644 index 3688d0b0dc..0000000000 --- a/src/graph2/detail/ExecutionHelpers.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/detail/ExecutionHelpers.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/GraphContext.h" -#include "arm_compute/graph2/GraphManager.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/backends/BackendRegistry.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace detail -{ -void default_initialize_backends() -{ - for(const auto &backend : backends::BackendRegistry::get().backends()) - { - backend.second->initialize_backend(); - } -} - -void configure_all_tensors(Graph &g) -{ - auto &tensors = g.tensors(); - - for(auto &tensor : tensors) - { - if(tensor) - { - Target target = tensor->desc().target; - auto backend = backends::BackendRegistry::get().find_backend(target); - ARM_COMPUTE_ERROR_ON_MSG(!backend, "Requested backend doesn't exist!"); - auto handle = backend->create_tensor(*tensor); - ARM_COMPUTE_ERROR_ON_MSG(!backend, "Couldn't create backend handle!"); - tensor->set_handle(std::move(handle)); - } - } -} - -void allocate_all_tensors(Graph &g) -{ - auto &tensors = g.tensors(); - - for(auto &tensor : tensors) - { - if(tensor && !tensor->bound_edges().empty()) - { - ARM_COMPUTE_ERROR_ON_MSG(!tensor->handle(), "Tensor handle is not configured!"); - tensor->handle()->allocate(); - } - } -} - -void validate_all_nodes(Graph &g) -{ - auto &nodes = g.nodes(); - - // Create tasks - for(auto &node : nodes) - { - if(node != nullptr) - { - Target assigned_target = node->assigned_target(); - auto backend = backends::BackendRegistry::get().find_backend(assigned_target); - ARM_COMPUTE_ERROR_ON_MSG(!backend, "Requested backend doesn't exist!"); - Status status = backend->validate_node(*node); - ARM_COMPUTE_ERROR_ON_MSG(!bool(status), status.error_description().c_str()); - } - } -} - -ExecutionWorkload configure_all_nodes(Graph &g, GraphContext &ctx) -{ - ExecutionWorkload workload; - auto &nodes = g.nodes(); - - // Create tasks - for(auto &node : nodes) - { - if(node != nullptr) - { - Target assigned_target = node->assigned_target(); - auto backend = backends::BackendRegistry::get().find_backend(assigned_target); - ARM_COMPUTE_ERROR_ON_MSG(!backend, "Requested backend doesn't exist!"); - auto func = backend->configure_node(*node, ctx); - if(func != nullptr) - { - ExecutionTask task; - task.task = std::move(func); - task.node = node.get(); - workload.tasks.push_back(std::move(task)); - } - } - } - - // Add inputs and outputs - for(auto &node : nodes) - { - if(node != nullptr && node->type() == NodeType::Input) - { - workload.inputs.push_back(node->output(0)); - } - - if(node != nullptr && node->type() == NodeType::Output) - { - workload.outputs.push_back(node->input(0)); - continue; - } - } - - return workload; -} - -void release_unused_tensors(Graph &g) -{ - for(auto &tensor : g.tensors()) - { - if(tensor != nullptr && tensor->handle() != nullptr) - { - tensor->handle()->release_if_unused(); - } - } -} - -void call_tensor_accessor(Tensor *tensor) -{ - ARM_COMPUTE_ERROR_ON(!tensor); - tensor->call_accessor(); -} - -void call_all_const_node_accessors(Graph &g) -{ - auto &nodes = g.nodes(); - - for(auto &node : nodes) - { - if(node != nullptr && node->type() == NodeType::Const) - { - call_tensor_accessor(node->output(0)); - } - } -} - -void call_all_input_node_accessors(ExecutionWorkload &workload) -{ - for(auto &input : workload.inputs) - { - if(input != nullptr) - { - input->call_accessor(); - } - } -} - -void call_all_tasks(ExecutionWorkload &workload) -{ - for(auto &task : workload.tasks) - { - task(); - } -} - -void call_all_output_node_accessors(ExecutionWorkload &workload) -{ - for(auto &output : workload.outputs) - { - if(output != nullptr) - { - output->call_accessor(); - } - } -} -} // namespace detail -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/frontend/Stream.cpp b/src/graph2/frontend/Stream.cpp deleted file mode 100644 index 4e794f28df..0000000000 --- a/src/graph2/frontend/Stream.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/frontend/Stream.h" - -#include "arm_compute/graph2/Utils.h" -#include "arm_compute/graph2/frontend/ILayer.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace frontend -{ -Stream::Stream(size_t id, std::string name) - : _manager(), _ctx(), _g(id, std::move(name)) -{ -} - -void Stream::finalize(Target target, const GraphConfig &config) -{ - PassManager pm = create_default_pass_manager(target); - _ctx.set_config(config); - _manager.finalize_graph(_g, _ctx, pm, target); -} - -void Stream::run() -{ - _manager.execute_graph(_g); -} - -void Stream::add_layer(ILayer &layer) -{ - auto nid = layer.create_layer(*this); - _tail_node = nid; -} - -const Graph &Stream::graph() const -{ - return _g; -} - -Graph &Stream::graph() -{ - return _g; -} -} // namespace frontend -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/frontend/SubStream.cpp b/src/graph2/frontend/SubStream.cpp deleted file mode 100644 index e6fa605ad1..0000000000 --- a/src/graph2/frontend/SubStream.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/frontend/SubStream.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/frontend/ILayer.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace frontend -{ -SubStream::SubStream(IStream &s) - : _s(s) -{ - _hints = s.hints(); - _tail_node = s.tail_node(); -} - -void SubStream::add_layer(ILayer &layer) -{ - auto nid = layer.create_layer(*this); - _tail_node = nid; -} - -const Graph &SubStream::graph() const -{ - return _s.graph(); -} - -Graph &SubStream::graph() -{ - return _s.graph(); -} -} // namespace frontend -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/mutators/DepthConcatSubTensorMutator.cpp b/src/graph2/mutators/DepthConcatSubTensorMutator.cpp deleted file mode 100644 index ea3743bf21..0000000000 --- a/src/graph2/mutators/DepthConcatSubTensorMutator.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/mutators/DepthConcatSubTensorMutator.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/backends/BackendRegistry.h" -#include "arm_compute/graph2/nodes/DepthConcatenateLayerNode.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/core/utils/misc/Iterable.h" - -namespace arm_compute -{ -namespace graph2 -{ -const char *DepthConcatSubTensorMutator::name() -{ - return "DepthConcatSubTensorMutator"; -} - -void DepthConcatSubTensorMutator::mutate(Graph &g) -{ - // Should be in reverse order of execution - for(auto &node : arm_compute::utils::iterable::reverse_iterate(g.nodes())) - { - if(node && node->type() == NodeType::DepthConcatenateLayer && node->output(0) != nullptr) - { - // Get output tensor - auto output_tensor = node->output(0); - - // Check that all tensor have the same target and valid inputs - bool is_valid = std::all_of(node->input_edges().cbegin(), node->input_edges().cend(), - [&](const EdgeID & eid) - { - return (g.edge(eid) != nullptr) && (g.edge(eid)->tensor() != nullptr) && (g.edge(eid)->tensor()->desc().target == output_tensor->desc().target); - }); - - // Create subtensors - if(is_valid && backends::BackendRegistry::get().find_backend(output_tensor->desc().target) != nullptr) - { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Using sub-tensors for the node with ID : " - << node->id() << " and name : " << node->name() << std::endl); - // Create sub-tensor handles - unsigned depth = 0; - for(unsigned int i = 0; i < node->input_edges().size(); ++i) - { - auto input_tensor = node->input(i); - const auto input_shape = input_tensor->desc().shape; - - auto backend = backends::BackendRegistry::get().find_backend(input_tensor->desc().target); - auto handle = backend->create_subtensor(output_tensor->handle(), input_shape, Coordinates(0, 0, depth), false); - input_tensor->set_handle(std::move(handle)); - - depth += input_shape.z(); - } - - auto *dc_node = arm_compute::utils::cast::polymorphic_downcast(node.get()); - dc_node->set_enabled(false); - } - } - } -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/mutators/InPlaceOperationMutator.cpp b/src/graph2/mutators/InPlaceOperationMutator.cpp deleted file mode 100644 index bb13e98999..0000000000 --- a/src/graph2/mutators/InPlaceOperationMutator.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/mutators/InPlaceOperationMutator.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Logger.h" - -namespace arm_compute -{ -namespace graph2 -{ -const char *InPlaceOperationMutator::name() -{ - return "InPlaceOperationMutator"; -} - -void InPlaceOperationMutator::mutate(Graph &g) -{ - std::set in_place_nodes = { NodeType::BatchNormalizationLayer, NodeType::ActivationLayer }; - - // Not interested in the order of nodes - for(auto &node : g.nodes()) - { - if(node && in_place_nodes.find(node->type()) != std::end(in_place_nodes)) - { - // Get input edge - Edge *input_edge = node->input_edge(0); - - // Check if parent has a single output if yes then force in place calculation else not - if((input_edge != nullptr) && (input_edge->producer() != nullptr) && (input_edge->producer()->output_edges().size() == 1)) - { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Switching to in-place computation for the node with ID : " - << node->id() << " and name : " << node->name() << std::endl); - // Update output - auto tensor = input_edge->tensor(); - node->set_output_tensor(tensor->id(), 0); - } - } - } -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/mutators/NodeFusionMutator.cpp b/src/graph2/mutators/NodeFusionMutator.cpp deleted file mode 100644 index d0ab3e7e6b..0000000000 --- a/src/graph2/mutators/NodeFusionMutator.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/mutators/NodeFusionMutator.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -#include "arm_compute/core/utils/misc/Cast.h" - -namespace arm_compute -{ -namespace graph2 -{ -namespace detail -{ -void fuse_batch_norm_with_activation(Graph &g) -{ - // Not interested in the order of nodes - for(auto &node : g.nodes()) - { - // Check if the node is batch norm and not a branching node - if(node && node->type() == NodeType::BatchNormalizationLayer && node->output_edges().size() == 1) - { - auto output_edge_id = *node->output_edges().begin(); - auto output_edge = g.edge(output_edge_id); - // Check if following node is an activation layer node - if((output_edge != nullptr) && (output_edge->consumer() != nullptr) && (output_edge->consumer()->type() == NodeType::ActivationLayer)) - { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Fusing Batch Normalization node with ID : " << output_edge->producer_id() - << " with Activation Layer node with ID : " << output_edge->consumer_id() << std::endl); - - auto *bn_node = arm_compute::utils::cast::polymorphic_downcast(output_edge->producer()); - auto *act_node = arm_compute::utils::cast::polymorphic_downcast(output_edge->consumer()); - - // Get driving nodes of activation node - std::vector act_driving_nodes; - for(auto &act_output_edge_id : act_node->output_edges()) - { - auto act_output_edge = g.edge(act_output_edge_id); - if(act_output_edge != nullptr) - { - ARM_COMPUTE_ERROR_ON(act_output_edge->consumer() == nullptr); - act_driving_nodes.push_back({ act_output_edge->consumer_id(), act_output_edge->consumer_idx() }); - } - } - - // Set activation info to batch normalization - bn_node->set_fused_activation(act_node->activation_info()); - - // Remove activation node - g.remove_node(act_node->id()); - - // Update batch normalization node outputs - for(auto &driving_node : act_driving_nodes) - { - g.add_connection(bn_node->id(), 0, driving_node.node_id, driving_node.index); - } - } - } - } -} -} // namespace detail - -const char *NodeFusionMutator::name() -{ - return "NodeFusionMutator"; -} - -void NodeFusionMutator::mutate(Graph &g) -{ - detail::fuse_batch_norm_with_activation(g); -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/mutators/SplitLayerSubTensorMutator.cpp b/src/graph2/mutators/SplitLayerSubTensorMutator.cpp deleted file mode 100644 index 33494ba6bc..0000000000 --- a/src/graph2/mutators/SplitLayerSubTensorMutator.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/mutators/SplitLayerSubTensorMutator.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Logger.h" -#include "arm_compute/graph2/backends/BackendRegistry.h" -#include "arm_compute/graph2/nodes/SplitLayerNode.h" - -#include "arm_compute/core/utils/misc/Cast.h" -#include "arm_compute/core/utils/misc/Iterable.h" - -namespace arm_compute -{ -namespace graph2 -{ -const char *SplitLayerSubTensorMutator::name() -{ - return "SplitLayerSubTensorMutator"; -} - -void SplitLayerSubTensorMutator::mutate(Graph &g) -{ - // Should be in reverse order of execution - for(auto &node : arm_compute::utils::iterable::reverse_iterate(g.nodes())) - { - if(node && node->type() == NodeType::SplitLayer && node->input(0) != nullptr) - { - // Get output tensor - Tensor *input_tensor = node->input(0); - - // Check that all tensor have the same target and are valid - bool is_valid = std::all_of(node->outputs().cbegin(), node->outputs().cend(), - [&](const TensorID & tid) - { - return (g.tensor(tid) != nullptr) && (g.tensor(tid)->desc().target == input_tensor->desc().target); - }); - - // Create subtensors - if(is_valid && backends::BackendRegistry::get().find_backend(input_tensor->desc().target) != nullptr) - { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Using sub-tensors for the node with ID : " - << node->id() << " and name : " << node->name() << std::endl); - - auto *split_node = arm_compute::utils::cast::polymorphic_downcast(node.get()); - - const unsigned int axis = split_node->axis(); - const unsigned int num_splits = split_node->num_splits(); - const bool extend_parent = (axis < 2); - - // Create sub-tensor handles - for(unsigned int i = 0; i < node->outputs().size(); ++i) - { - Tensor *output_tensor = node->output(i); - const TensorShape output_shape = output_tensor->desc().shape; - Coordinates coords; - std::tie(std::ignore, coords) = SplitLayerNode::compute_output_shape(input_tensor->desc().shape, num_splits, axis, i); - - backends::IDeviceBackend *backend = backends::BackendRegistry::get().find_backend(output_tensor->desc().target); - std::unique_ptr handle = backend->create_subtensor(input_tensor->handle(), output_shape, coords, extend_parent); - output_tensor->set_handle(std::move(handle)); - } - } - } - } -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/nodes/ActivationLayerNode.cpp b/src/graph2/nodes/ActivationLayerNode.cpp deleted file mode 100644 index c7c36e9bbd..0000000000 --- a/src/graph2/nodes/ActivationLayerNode.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/ActivationLayerNode.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -ActivationLayerNode::ActivationLayerNode(ActivationLayerInfo info) - : _info(info) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -ActivationLayerInfo ActivationLayerNode::activation_info() const -{ - return _info; -} - -bool ActivationLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor ActivationLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - return src->desc(); -} - -Status ActivationLayerNode::validate() -{ - return Status{}; -} - -NodeType ActivationLayerNode::type() const -{ - return NodeType::ActivationLayer; -} - -void ActivationLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/BatchNormalizationLayerNode.cpp b/src/graph2/nodes/BatchNormalizationLayerNode.cpp deleted file mode 100644 index b9f634210c..0000000000 --- a/src/graph2/nodes/BatchNormalizationLayerNode.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/BatchNormalizationLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -BatchNormalizationLayerNode::BatchNormalizationLayerNode(float epsilon, ActivationLayerInfo fused_activation) - : _epsilon(epsilon), _fused_activation(fused_activation) -{ - _input_edges.resize(5, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -float BatchNormalizationLayerNode::epsilon() const -{ - return _epsilon; -} - -ActivationLayerInfo BatchNormalizationLayerNode::fused_activation() const -{ - return _fused_activation; -} - -void BatchNormalizationLayerNode::set_fused_activation(ActivationLayerInfo fused_activation) -{ - _fused_activation = fused_activation; -} - -bool BatchNormalizationLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor BatchNormalizationLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - return src->desc(); -} - -Status BatchNormalizationLayerNode::validate() -{ - return Status{}; -} - -NodeType BatchNormalizationLayerNode::type() const -{ - return NodeType::BatchNormalizationLayer; -} - -void BatchNormalizationLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/ConstNode.cpp b/src/graph2/nodes/ConstNode.cpp deleted file mode 100644 index 5bd6a8180c..0000000000 --- a/src/graph2/nodes/ConstNode.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/ConstNode.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -ConstNode::ConstNode(TensorDescriptor desc) - : _desc(desc) -{ - _outputs.resize(1, NullTensorID); -} - -bool ConstNode::forward_descriptors() -{ - if(output_id(0) != NullTensorID) - { - Tensor *t = output(0); - ARM_COMPUTE_ERROR_ON(t == nullptr); - t->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor ConstNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - return _desc; -} - -Status ConstNode::validate() -{ - return Status{}; -} - -NodeType ConstNode::type() const -{ - return NodeType::Const; -} - -void ConstNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/nodes/ConvolutionLayerNode.cpp b/src/graph2/nodes/ConvolutionLayerNode.cpp deleted file mode 100644 index 499b3520b2..0000000000 --- a/src/graph2/nodes/ConvolutionLayerNode.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/ConvolutionLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -ConvolutionLayerNode::ConvolutionLayerNode(PadStrideInfo info, ConvolutionMethod method) - : _info(std::move(info)), _method(method) -{ - _input_edges.resize(3, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -void ConvolutionLayerNode::set_convolution_method(ConvolutionMethod method) -{ - _method = method; -} - -ConvolutionMethod ConvolutionLayerNode::convolution_method() const -{ - return _method; -} - -PadStrideInfo ConvolutionLayerNode::convolution_info() const -{ - return _info; -} - -TensorShape ConvolutionLayerNode::compute_output_shape(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo info) -{ - unsigned int output_width = 0; - unsigned int output_height = 0; - std::tie(output_width, output_height) = scaled_dimensions(input_shape.x(), input_shape.y(), weights_shape.x(), weights_shape.y(), info); - - TensorShape output_shape{ input_shape }; - output_shape.set(0, output_width); - output_shape.set(1, output_height); - output_shape.set(2, weights_shape[3]); - - return output_shape; -} - -bool ConvolutionLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (input_id(1) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor ConvolutionLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - const Tensor *src = input(0); - const Tensor *weights = input(1); - - ARM_COMPUTE_ERROR_ON(src == nullptr || weights == nullptr); - - TensorDescriptor output_info = src->desc(); - TensorShape output_shape = compute_output_shape(src->desc().shape, weights->desc().shape, _info); - output_info.shape = output_shape; - return output_info; -} - -Status ConvolutionLayerNode::validate() -{ - return Status{}; -} - -NodeType ConvolutionLayerNode::type() const -{ - return NodeType::ConvolutionLayer; -} - -void ConvolutionLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/DepthConcatenateLayerNode.cpp b/src/graph2/nodes/DepthConcatenateLayerNode.cpp deleted file mode 100644 index dcd66517b6..0000000000 --- a/src/graph2/nodes/DepthConcatenateLayerNode.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/DepthConcatenateLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -DepthConcatenateLayerNode::DepthConcatenateLayerNode(unsigned int total_nodes) - : _total_nodes(total_nodes), _is_enabled(true) -{ - _input_edges.resize(total_nodes, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -void DepthConcatenateLayerNode::set_enabled(bool is_enabled) -{ - _is_enabled = is_enabled; -} - -bool DepthConcatenateLayerNode::is_enabled() const -{ - return _is_enabled; -} - -TensorShape DepthConcatenateLayerNode::compute_output_shape(const std::vector &input_shapes) -{ - ARM_COMPUTE_ERROR_ON(input_shapes.size() == 0); - - TensorShape output_shape = input_shapes[0]; - - size_t max_x = 0; - size_t max_y = 0; - size_t depth = 0; - - for(const auto &shape : input_shapes) - { - max_x = std::max(shape.x(), max_x); - max_y = std::max(shape.y(), max_y); - depth += shape.z(); - } - - output_shape.set(0, max_x); - output_shape.set(1, max_y); - output_shape.set(2, depth); - - return output_shape; -} - -bool DepthConcatenateLayerNode::forward_descriptors() -{ - if(_outputs[0] != NullTensorID) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor DepthConcatenateLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - // Check if all input tensors are set - bool are_all_inputs_set = std::all_of(std::begin(_input_edges), std::end(_input_edges), [](const EdgeID & eid) - { - return eid != EmptyEdgeID; - }); - - TensorDescriptor output_info = {}; - - if(are_all_inputs_set) - { - std::vector inputs_shapes; - for(unsigned int i = 0; i < _input_edges.size(); ++i) - { - const Tensor *t = _graph->tensor(input_id(i)); - ARM_COMPUTE_ERROR_ON(t == nullptr); - inputs_shapes.push_back(t->desc().shape); - } - output_info = input(0)->desc(); - TensorShape output_shape = compute_output_shape(inputs_shapes); - output_info.shape = output_shape; - } - - return output_info; -} - -Status DepthConcatenateLayerNode::validate() -{ - ARM_COMPUTE_UNUSED(_total_nodes); - return Status{}; -} - -NodeType DepthConcatenateLayerNode::type() const -{ - return NodeType::DepthConcatenateLayer; -} - -void DepthConcatenateLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/DepthwiseConvolutionLayerNode.cpp b/src/graph2/nodes/DepthwiseConvolutionLayerNode.cpp deleted file mode 100644 index b030e8b7ca..0000000000 --- a/src/graph2/nodes/DepthwiseConvolutionLayerNode.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/DepthwiseConvolutionLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -DepthwiseConvolutionLayerNode::DepthwiseConvolutionLayerNode(PadStrideInfo info, DepthwiseConvolutionMethod method) - : _info(std::move(info)), _method(method) -{ - _input_edges.resize(3, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -void DepthwiseConvolutionLayerNode::set_depthwise_convolution_method(DepthwiseConvolutionMethod method) -{ - _method = method; -} - -DepthwiseConvolutionMethod DepthwiseConvolutionLayerNode::depthwise_convolution_method() const -{ - return _method; -} - -PadStrideInfo DepthwiseConvolutionLayerNode::convolution_info() const -{ - return _info; -} - -TensorShape DepthwiseConvolutionLayerNode::compute_output_shape(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo info) -{ - unsigned int output_width = 0; - unsigned int output_height = 0; - std::tie(output_width, output_height) = scaled_dimensions(input_shape.x(), input_shape.y(), weights_shape.x(), weights_shape.y(), info); - - TensorShape output_shape{ input_shape }; - output_shape.set(0, output_width); - output_shape.set(1, output_height); - - return output_shape; -} - -bool DepthwiseConvolutionLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (input_id(1) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor DepthwiseConvolutionLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - const Tensor *src = input(0); - const Tensor *weights = input(1); - - ARM_COMPUTE_ERROR_ON(src == nullptr || weights == nullptr); - - TensorDescriptor output_info = src->desc(); - TensorShape output_shape = compute_output_shape(src->desc().shape, weights->desc().shape, _info); - output_info.shape = output_shape; - return output_info; -} - -Status DepthwiseConvolutionLayerNode::validate() -{ - return Status{}; -} - -NodeType DepthwiseConvolutionLayerNode::type() const -{ - return NodeType::DepthwiseConvolutionLayer; -} - -void DepthwiseConvolutionLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/EltwiseLayerNode.cpp b/src/graph2/nodes/EltwiseLayerNode.cpp deleted file mode 100644 index 149d926d29..0000000000 --- a/src/graph2/nodes/EltwiseLayerNode.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/EltwiseLayerNode.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -EltwiseLayerNode::EltwiseLayerNode(EltwiseOperation op) - : _op(op) -{ - _input_edges.resize(2, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -EltwiseOperation EltwiseLayerNode::eltwise_operation() const -{ - return _op; -} - -bool EltwiseLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor EltwiseLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_UNUSED(_op); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - return src->desc(); -} - -Status EltwiseLayerNode::validate() -{ - return Status{}; -} - -NodeType EltwiseLayerNode::type() const -{ - return NodeType::EltwiseLayer; -} - -void EltwiseLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/nodes/FlattenLayerNode.cpp b/src/graph2/nodes/FlattenLayerNode.cpp deleted file mode 100644 index 7c4059f3ed..0000000000 --- a/src/graph2/nodes/FlattenLayerNode.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/FlattenLayerNode.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -FlattenLayerNode::FlattenLayerNode() -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -bool FlattenLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor FlattenLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - TensorDescriptor output_desc = src->desc(); - output_desc.shape.collapse(src->desc().shape.num_dimensions()); - - return output_desc; -} - -Status FlattenLayerNode::validate() -{ - return Status{}; -} - -NodeType FlattenLayerNode::type() const -{ - return NodeType::FlattenLayer; -} - -void FlattenLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/FullyConnectedLayer.cpp b/src/graph2/nodes/FullyConnectedLayer.cpp deleted file mode 100644 index 195adc40fe..0000000000 --- a/src/graph2/nodes/FullyConnectedLayer.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/FullyConnectedLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -FullyConnectedLayerNode::FullyConnectedLayerNode(unsigned int num_outputs) - : _num_outputs(num_outputs) -{ - _input_edges.resize(3, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -TensorShape FullyConnectedLayerNode::compute_weights_shape(TensorShape input_shape, unsigned int num_outputs) -{ - unsigned int num_weights = 1; - unsigned int num_dimensions = input_shape.num_dimensions(); - // Ignore the batch dimension if there is one: - if(num_dimensions == 2 || num_dimensions == 4) - { - num_dimensions--; - } - for(unsigned int i = 0; i < num_dimensions; i++) - { - num_weights *= input_shape[i]; - } - return TensorShape(num_weights, num_outputs); -} - -TensorShape FullyConnectedLayerNode::compute_output_shape(TensorShape input_shape, unsigned int num_outputs) -{ - // Note: Only 1D batch space is supported at the moment - unsigned int batches = input_shape[1]; - if(input_shape.num_dimensions() > 2) - { - batches = input_shape[3]; - } - return TensorShape(num_outputs, batches); -} - -bool FullyConnectedLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor FullyConnectedLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - TensorDescriptor output_info = src->desc(); - TensorShape output_shape = compute_output_shape(src->desc().shape, _num_outputs); - output_info.shape = output_shape; - return output_info; -} - -Status FullyConnectedLayerNode::validate() -{ - return Status{}; -} - -NodeType FullyConnectedLayerNode::type() const -{ - return NodeType::FullyConnectedLayer; -} - -void FullyConnectedLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/InputNode.cpp b/src/graph2/nodes/InputNode.cpp deleted file mode 100644 index 84cce2acdb..0000000000 --- a/src/graph2/nodes/InputNode.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/InputNode.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -InputNode::InputNode(TensorDescriptor desc) - : _desc(desc) -{ - _outputs.resize(1, NullTensorID); -} - -bool InputNode::forward_descriptors() -{ - if(output_id(0) != NullTensorID) - { - Tensor *t = output(0); - ARM_COMPUTE_ERROR_ON(t == nullptr); - t->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor InputNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - return _desc; -} - -Status InputNode::validate() -{ - return Status{}; -} - -NodeType InputNode::type() const -{ - return NodeType::Input; -} - -void InputNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/nodes/NormalizationLayerNode.cpp b/src/graph2/nodes/NormalizationLayerNode.cpp deleted file mode 100644 index a394879a3e..0000000000 --- a/src/graph2/nodes/NormalizationLayerNode.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/NormalizationLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -NormalizationLayerNode::NormalizationLayerNode(NormalizationLayerInfo norm_info) - : _info(norm_info) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -NormalizationLayerInfo NormalizationLayerNode::normalization_info() const -{ - return _info; -} - -bool NormalizationLayerNode::forward_descriptors() -{ - if(input_id(0) != NullTensorID && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor NormalizationLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - return src->desc(); -} - -Status NormalizationLayerNode::validate() -{ - return Status{}; -} - -NodeType NormalizationLayerNode::type() const -{ - return NodeType::NormalizationLayer; -} - -void NormalizationLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/OutputNode.cpp b/src/graph2/nodes/OutputNode.cpp deleted file mode 100644 index 1daebb1cc8..0000000000 --- a/src/graph2/nodes/OutputNode.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/OutputNode.h" - -#include "arm_compute/core/Error.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" -#include "arm_compute/graph2/Tensor.h" - -namespace arm_compute -{ -namespace graph2 -{ -OutputNode::OutputNode() -{ - _input_edges.resize(1, EmptyEdgeID); -} - -bool OutputNode::forward_descriptors() -{ - return true; -} - -TensorDescriptor OutputNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - return TensorDescriptor(); -} - -Status OutputNode::validate() -{ - return Status{}; -} - -NodeType OutputNode::type() const -{ - return NodeType::Output; -} - -void OutputNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/graph2/nodes/PoolingLayerNode.cpp b/src/graph2/nodes/PoolingLayerNode.cpp deleted file mode 100644 index 2c2cf5387a..0000000000 --- a/src/graph2/nodes/PoolingLayerNode.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/PoolingLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -PoolingLayerNode::PoolingLayerNode(PoolingLayerInfo pool_info) - : _info(std::move(pool_info)) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -PoolingLayerInfo PoolingLayerNode::pooling_info() const -{ - return _info; -} - -TensorShape PoolingLayerNode::compute_output_shape(TensorShape input_shape, PoolingLayerInfo info) -{ - const int pool_size_x = info.is_global_pooling() ? input_shape.x() : info.pool_size().width; - const int pool_size_y = info.is_global_pooling() ? input_shape.y() : info.pool_size().height; - - unsigned int pooled_width = 0; - unsigned int pooled_height = 0; - std::tie(pooled_width, pooled_height) = scaled_dimensions(input_shape.x(), input_shape.y(), pool_size_x, pool_size_y, info.pad_stride_info()); - - TensorShape output_shape{ input_shape }; - output_shape.set(0, pooled_width); - output_shape.set(1, pooled_height); - - return output_shape; -} - -bool PoolingLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor PoolingLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - TensorDescriptor output_info = src->desc(); - TensorShape output_shape = compute_output_shape(src->desc().shape, _info); - output_info.shape = output_shape; - return output_info; -} - -Status PoolingLayerNode::validate() -{ - return Status{}; -} - -NodeType PoolingLayerNode::type() const -{ - return NodeType::PoolingLayer; -} - -void PoolingLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/ReshapeLayer.cpp b/src/graph2/nodes/ReshapeLayer.cpp deleted file mode 100644 index 6280eea75c..0000000000 --- a/src/graph2/nodes/ReshapeLayer.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/ReshapeLayerNode.h" - -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -ReshapeLayerNode::ReshapeLayerNode(TensorShape shape) - : _shape(shape) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -bool ReshapeLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor ReshapeLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - TensorDescriptor output_desc = src->desc(); - output_desc.shape = _shape; - - return output_desc; -} - -Status ReshapeLayerNode::validate() -{ - return Status{}; -} - -NodeType ReshapeLayerNode::type() const -{ - return NodeType::ReshapeLayer; -} - -void ReshapeLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/SoftmaxLayerNode.cpp b/src/graph2/nodes/SoftmaxLayerNode.cpp deleted file mode 100644 index 83bc978981..0000000000 --- a/src/graph2/nodes/SoftmaxLayerNode.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/SoftmaxLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -SoftmaxLayerNode::SoftmaxLayerNode(float beta) - : _beta(beta) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(1, NullTensorID); -} - -float SoftmaxLayerNode::beta() const -{ - return _beta; -} - -bool SoftmaxLayerNode::forward_descriptors() -{ - if((input_id(0) != NullTensorID) && (output_id(0) != NullTensorID)) - { - Tensor *dst = output(0); - ARM_COMPUTE_ERROR_ON(dst == nullptr); - dst->desc() = configure_output(0); - return true; - } - return false; -} - -TensorDescriptor SoftmaxLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - return src->desc(); -} - -Status SoftmaxLayerNode::validate() -{ - return Status{}; -} - -NodeType SoftmaxLayerNode::type() const -{ - return NodeType::SoftmaxLayer; -} - -void SoftmaxLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/nodes/SplitLayerNode.cpp b/src/graph2/nodes/SplitLayerNode.cpp deleted file mode 100644 index c34a7ff176..0000000000 --- a/src/graph2/nodes/SplitLayerNode.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/nodes/SplitLayerNode.h" - -#include "arm_compute/core/Utils.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/INodeVisitor.h" - -namespace arm_compute -{ -namespace graph2 -{ -SplitLayerNode::SplitLayerNode(unsigned int num_splits, unsigned int axis) - : _num_splits(num_splits), _axis(axis) -{ - _input_edges.resize(1, EmptyEdgeID); - _outputs.resize(num_splits, NullTensorID); -} - -unsigned int SplitLayerNode::num_splits() const -{ - return _num_splits; -} - -unsigned int SplitLayerNode::axis() const -{ - return _axis; -} - -std::pair SplitLayerNode::compute_output_shape(TensorShape input_shape, unsigned int num_splits, unsigned int axis, unsigned int idx) -{ - ARM_COMPUTE_ERROR_ON(axis >= input_shape.num_dimensions()); - ARM_COMPUTE_ERROR_ON_MSG(input_shape[axis] % num_splits, "Split should be exact"); - - const unsigned int split_size = input_shape[axis] / num_splits; - - TensorShape output_shape = input_shape; - output_shape.set(axis, split_size); - - Coordinates coords; - coords.set(axis, idx * split_size); - - return std::make_pair(output_shape, coords); -} - -bool SplitLayerNode::forward_descriptors() -{ - if(input_id(0) != NullTensorID) - { - for(unsigned int i = 0; i < _outputs.size(); ++i) - { - if(output_id(i) != NullTensorID) - { - Tensor *dst_i = output(i); - ARM_COMPUTE_ERROR_ON(dst_i == nullptr); - dst_i->desc() = configure_output(i); - } - } - return true; - } - return false; -} - -TensorDescriptor SplitLayerNode::configure_output(size_t idx) const -{ - ARM_COMPUTE_UNUSED(idx); - ARM_COMPUTE_ERROR_ON(idx >= _outputs.size()); - - const Tensor *src = input(0); - ARM_COMPUTE_ERROR_ON(src == nullptr); - - TensorShape output_shape; - - TensorDescriptor output_info = src->desc(); - std::tie(output_shape, std::ignore) = compute_output_shape(src->desc().shape, _num_splits, _axis, idx); - output_info.shape = output_shape; - - return output_info; -} - -Status SplitLayerNode::validate() -{ - return Status{}; -} - -NodeType SplitLayerNode::type() const -{ - return NodeType::SplitLayer; -} - -void SplitLayerNode::accept(INodeVisitor &v) -{ - v.visit(*this); -} -} // namespace graph2 -} // namespace arm_compute \ No newline at end of file diff --git a/src/graph2/printers/DotGraphPrinter.cpp b/src/graph2/printers/DotGraphPrinter.cpp deleted file mode 100644 index 04987eebe0..0000000000 --- a/src/graph2/printers/DotGraphPrinter.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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. - */ -#include "arm_compute/graph2/printers/DotGraphPrinter.h" - -#include "arm_compute/core/Error.h" -#include "arm_compute/graph2/Graph.h" -#include "arm_compute/graph2/Tensor.h" -#include "arm_compute/graph2/TypePrinter.h" -#include "arm_compute/graph2/nodes/Nodes.h" - -namespace arm_compute -{ -namespace graph2 -{ -void DotGraphVisitor::visit(ActivationLayerNode &n) -{ - std::stringstream ss; - ss << n.activation_info().activation(); - _info = ss.str(); -} - -void DotGraphVisitor::visit(BatchNormalizationLayerNode &n) -{ - std::stringstream ss; - ss << (n.fused_activation().enabled() ? to_string(n.fused_activation().activation()) : ""); - _info = ss.str(); -} - -void DotGraphVisitor::visit(ConvolutionLayerNode &n) -{ - std::stringstream ss; - ss << n.convolution_method(); - _info = ss.str(); -} - -void DotGraphVisitor::visit(DepthConcatenateLayerNode &n) -{ - std::stringstream ss; - ss << "Enabled: " << n.is_enabled(); - _info = ss.str(); -} - -void DotGraphVisitor::visit(DepthwiseConvolutionLayerNode &n) -{ - std::stringstream ss; - ss << n.depthwise_convolution_method(); - _info = ss.str(); -} - -void DotGraphVisitor::visit(EltwiseLayerNode &n) -{ - std::stringstream ss; - ss << n.eltwise_operation(); - _info = ss.str(); -} - -void DotGraphVisitor::visit(NormalizationLayerNode &n) -{ - std::stringstream ss; - ss << n.normalization_info().type(); - _info = ss.str(); -} - -void DotGraphVisitor::visit(PoolingLayerNode &n) -{ - std::stringstream ss; - ss << n.pooling_info().pool_type(); - ss << R"( \n )"; - ss << n.pooling_info().pool_size(); - ss << R"( \n )"; - ss << n.pooling_info().pad_stride_info(); - _info = ss.str(); -} - -void DotGraphVisitor::default_visit() -{ - _info.clear(); -} - -const std::string &DotGraphVisitor::info() const -{ - return _info; -} - -void DotGraphPrinter::print(const Graph &g, std::ostream &os) -{ - // Print header - print_header(g, os); - - // Print nodes - print_nodes(g, os); - - // Print edges - print_edges(g, os); - - // Print footer - print_footer(g, os); -} - -void DotGraphPrinter::print_header(const Graph &g, std::ostream &os) -{ - // Print graph name - std::string graph_name = (g.name().empty()) ? "Graph" : g.name(); - os << "digraph " << graph_name << "{\n"; -} - -void DotGraphPrinter::print_footer(const Graph &g, std::ostream &os) -{ - ARM_COMPUTE_UNUSED(g); - os << "}\n"; -} - -void DotGraphPrinter::print_nodes(const Graph &g, std::ostream &os) -{ - for(const auto &n : g.nodes()) - { - if(n) - { - // Output node id - std::string node_id = std::string("n") + support::cpp11::to_string(n->id()); - os << node_id << " "; - - // Output label - n->accept(_dot_node_visitor); - - std::string name = n->name().empty() ? node_id : n->name(); - auto node_description = _dot_node_visitor.info(); - - os << R"([label = ")" << name << R"( \n )" << n->assigned_target() << R"( \n )" << node_description << R"("])"; - os << ";\n"; - } - } -} - -void DotGraphPrinter::print_edges(const Graph &g, std::ostream &os) -{ - for(const auto &e : g.edges()) - { - if(e) - { - std::string source_node_id = std::string("n") + support::cpp11::to_string(e->producer_id()); - std::string sink_node_id = std::string("n") + support::cpp11::to_string(e->consumer_id()); - os << source_node_id << " -> " << sink_node_id << " "; - const Tensor *t = e->tensor(); - ARM_COMPUTE_ERROR_ON(t == nullptr); - os << R"([label = ")" << t->desc().shape << R"( \n )" << t->desc().data_type << R"("])"; - os << ";\n"; - } - } -} -} // namespace graph2 -} // namespace arm_compute diff --git a/src/runtime/NEON/functions/NEWinogradLayer.cpp b/src/runtime/NEON/functions/NEWinogradLayer.cpp index 0ac6d0966d..0a344f0cae 100644 --- a/src/runtime/NEON/functions/NEWinogradLayer.cpp +++ b/src/runtime/NEON/functions/NEWinogradLayer.cpp @@ -248,7 +248,7 @@ void NEWinogradLayer::run() Status NEWinogradLayer::validate(const ITensorInfo *input, const ITensorInfo *weights, const ITensorInfo *biases, const ITensorInfo *output, const PadStrideInfo &conv_info) { ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, biases, output); - ARM_COMPUTE_RETURN_ERROR_ON(validate_arguments(input, weights, biases, output, conv_info)); + ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, weights, biases, output, conv_info)); return Status{}; } diff --git a/tests/SConscript b/tests/SConscript index 4a4f1bf5dc..20095e56fb 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -74,7 +74,6 @@ if env['internal_only']: test_env.Append(CPPPATH = ["#3rdparty/include"]) test_env.Append(LIBPATH = ["#3rdparty/%s/%s" % (env['os'], env['arch'])]) test_env.Append(LIBPATH = ["#build/%s" % env['build_dir']]) -test_env.Append(LIBPATH = ["#build/%s/opencl-1.2-stubs" % env['build_dir']]) common_files = Glob('*.cpp') common_objects = [test_env.StaticObject(f) for f in common_files] @@ -94,11 +93,9 @@ filter_pattern = test_env['test_filter'] files_validation += Glob('validation/CPP/' + filter_pattern) if env['opencl']: - Import('opencl') filter_pattern = test_env['test_filter'] test_env.Append(CPPDEFINES=['ARM_COMPUTE_CL']) - test_env.Append(LIBS = ["OpenCL"]) files_benchmark += Glob('benchmark/CL/*/' + filter_pattern) files_benchmark += Glob('benchmark/CL/' + filter_pattern) @@ -115,17 +112,6 @@ if env['neon']: files_validation += Glob('validation/NEON/' + filter_pattern) if env['gles_compute']: - if env['os'] != 'android': - Import('egl') - Import('glesv2') - - test_env.Append(LIBS = ["EGL", "GLESv2"]) - else: - if env['arch'] != 'armv7a': - test_env.Append(LIBS = ["EGL", "GLESv3"]) - else: - test_env.Append(LIBS = ["EGL", "GLESv2"]) - test_env.Append(CPPDEFINES=['ARM_COMPUTE_GC']) files_benchmark += Glob('benchmark/GLES_COMPUTE/*/*.cpp') @@ -143,13 +129,6 @@ if test_env['benchmark_tests']: arm_compute_benchmark = test_env.Program('arm_compute_benchmark', files_benchmark + common_objects) Depends(arm_compute_benchmark, arm_compute_test_framework) Depends(arm_compute_benchmark, arm_compute_lib) - - if env['opencl']: - Depends(arm_compute_benchmark, opencl) - if env['gles_compute'] and env['os'] != 'android': - Depends(arm_compute_benchmark, egl) - Depends(arm_compute_benchmark, glesv2) - Default(arm_compute_benchmark) Export('arm_compute_benchmark') @@ -158,12 +137,6 @@ if test_env['validation_tests']: Depends(arm_compute_validation, arm_compute_test_framework) Depends(arm_compute_validation, arm_compute_lib) - if env['opencl']: - Depends(arm_compute_validation, opencl) - if env['gles_compute'] and env['os'] != 'android': - Depends(arm_compute_validation, egl) - Depends(arm_compute_validation, glesv2) - Default(arm_compute_validation) Export('arm_compute_validation') @@ -182,29 +155,26 @@ if test_env['validation_tests']: files += Glob("validate_examples/neoncl_*.cpp") for file in files: example = "validate_" + os.path.basename(os.path.splitext(str(file))[0]) - cl_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_validate_examples, CPPDEFINES=['ARM_COMPUTE_CL'], LIBS = test_env["LIBS"] + ["OpenCL"]) ] - Depends(cl_examples, opencl) + cl_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_validate_examples, LIBS = test_env["LIBS"]) ] arm_compute_validate_examples += cl_examples if test_env['opencl'] and test_env['neon']: if env['os'] == 'android': Import('arm_compute_graph_a') - Import("arm_compute_graph2_a") - graph_dependency = [ arm_compute_graph_a, arm_compute_graph2_a] + graph_dependency = [ arm_compute_graph_a] else: Import('arm_compute_graph_so') - Import("arm_compute_graph2_so") - graph_dependency = [ arm_compute_graph_so, arm_compute_graph2_so] + graph_dependency = [ arm_compute_graph_so] graph_utils = test_env.Object(source="../utils/GraphUtils.cpp", target="GraphUtils") for file in Glob("validate_examples/graph_*.cpp"): example = "validate_" + os.path.basename(os.path.splitext(str(file))[0]) if env['os'] == 'android': - prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"] + ["OpenCL"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive']) - Depends(prog, [graph_dependency, opencl]) + prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive']) + Depends(prog, graph_dependency) arm_compute_validate_examples += [ prog ] else: #-Wl,--allow-shlib-undefined: Ignore dependencies of dependencies - prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph", "arm_compute_graph2"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] ) + prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_validate_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] ) Depends(prog, graph_dependency) arm_compute_validate_examples += [ prog ] Depends(arm_compute_validate_examples, arm_compute_test_framework) @@ -227,31 +197,28 @@ if test_env['benchmark_examples']: files += Glob("../examples/neoncl_*.cpp") for file in files: example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0]) - cl_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_benchmark_examples, CPPDEFINES=['ARM_COMPUTE_CL'], LIBS = test_env["LIBS"] + ["OpenCL"]) ] - Depends(cl_examples, opencl) + cl_examples += [ test_env.Program(example, [ test_env.Object(source=file, target=example) ] + files_benchmark_examples, LIBS = test_env["LIBS"]) ] arm_compute_benchmark_examples += cl_examples - if test_env['opencl'] and test_env['neon']: - if env['os'] == 'android': - Import('arm_compute_graph_a') - Import("arm_compute_graph2_a") - graph_dependency = [arm_compute_graph_a, arm_compute_graph2_a] - else: - Import('arm_compute_graph_so') - Import('arm_compute_graph2_so') - graph_dependency = [arm_compute_graph_so, arm_compute_graph2_so] - - graph_utils = test_env.Object(source="../utils/GraphUtils.cpp", target="GraphUtils") - for file in Glob("../examples/graph_*.cpp"): - example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0]) - if env['os'] == 'android': - prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_benchmark_examples, LIBS = test_env["LIBS"] + ["OpenCL"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive']) - Depends(prog, [graph_dependency, opencl]) - arm_compute_benchmark_examples += [ prog ] - else: - #-Wl,--allow-shlib-undefined: Ignore dependencies of dependencies - prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_benchmark_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph", "arm_compute_graph2"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] ) - Depends(prog, graph_dependency) - arm_compute_benchmark_examples += [ prog ] + + # Graph examples + if env['os'] == 'android': + Import('arm_compute_graph_a') + graph_dependency = [arm_compute_graph_a] + else: + Import('arm_compute_graph_so') + graph_dependency = [arm_compute_graph_so] + graph_utils = test_env.Object(source="../utils/GraphUtils.cpp", target="GraphUtils") + for file in Glob("../examples/graph_*.cpp"): + example = "benchmark_" + os.path.basename(os.path.splitext(str(file))[0]) + if env['os'] == 'android': + prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_benchmark_examples, LIBS = test_env["LIBS"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--whole-archive',graph_dependency,'-Wl,--no-whole-archive']) + Depends(prog, [graph_dependency]) + arm_compute_benchmark_examples += [ prog ] + else: + #-Wl,--allow-shlib-undefined: Ignore dependencies of dependencies + prog = test_env.Program(example, [ test_env.Object(source=file, target=example), graph_utils]+ files_benchmark_examples, LIBS = test_env["LIBS"] + ["arm_compute_graph"], LINKFLAGS=test_env["LINKFLAGS"]+['-Wl,--allow-shlib-undefined'] ) + Depends(prog, graph_dependency) + arm_compute_benchmark_examples += [ prog ] Depends(arm_compute_benchmark_examples, arm_compute_test_framework) Depends(arm_compute_benchmark_examples, arm_compute_lib) Default(arm_compute_benchmark_examples) diff --git a/utils/GraphTypePrinter.h b/utils/GraphTypePrinter.h deleted file mode 100644 index 4ff1019cce..0000000000 --- a/utils/GraphTypePrinter.h +++ /dev/null @@ -1,88 +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_TEST_GRAPH_TYPE_PRINTER_H__ -#define __ARM_COMPUTE_TEST_GRAPH_TYPE_PRINTER_H__ - -#include "arm_compute/graph/Types.h" - -#include -#include -#include - -namespace arm_compute -{ -namespace graph -{ -/** Formatted output of the @ref ConvolutionMethodHint type. */ -inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethodHint &conv_method) -{ - switch(conv_method) - { - case ConvolutionMethodHint::DIRECT: - os << "DIRECT"; - break; - case ConvolutionMethodHint::GEMM: - os << "GEMM"; - break; - default: - ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); - } - - return os; -} - -inline std::string to_string(const ConvolutionMethodHint &conv_method) -{ - std::stringstream str; - str << conv_method; - return str.str(); -} - -/** Formatted output of the @ref TargetHint type. */ -inline ::std::ostream &operator<<(::std::ostream &os, const TargetHint &target_hint) -{ - switch(target_hint) - { - case TargetHint::NEON: - os << "NEON"; - break; - case TargetHint::OPENCL: - os << "OPENCL"; - break; - default: - ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); - } - - return os; -} - -inline std::string to_string(const TargetHint &target_hint) -{ - std::stringstream str; - str << target_hint; - return str.str(); -} -} // namespace graph -} // namespace arm_compute -#endif /* __ARM_COMPUTE_TEST_GRAPH_TYPE_PRINTER_H__ */ diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp index 448343a977..7912fd6b7d 100644 --- a/utils/GraphUtils.cpp +++ b/utils/GraphUtils.cpp @@ -27,11 +27,6 @@ #include "arm_compute/runtime/SubTensor.h" #include "utils/Utils.h" -#ifdef ARM_COMPUTE_CL -#include "arm_compute/core/CL/OpenCL.h" -#include "arm_compute/runtime/CL/CLTensor.h" -#endif /* ARM_COMPUTE_CL */ - #include using namespace arm_compute::graph_utils; diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h index e70a1a275f..11f1e0590a 100644 --- a/utils/GraphUtils.h +++ b/utils/GraphUtils.h @@ -29,10 +29,6 @@ #include "arm_compute/graph/ITensorAccessor.h" #include "arm_compute/graph/Types.h" -#include "arm_compute/core/CL/OpenCL.h" - -#include "arm_compute/graph2/Types.h" - #include #include #include @@ -276,26 +272,6 @@ inline std::unique_ptr get_input_accessor(const std::str } } -/** Utility function to return the TargetHint - * - * @param[in] target Integer value which expresses the selected target. Must be 0 for NEON, 1 for OpenCL or 2 for OpenCL with Tuner - * - * @return the TargetHint - */ -inline graph::TargetHint set_target_hint(int target) -{ - ARM_COMPUTE_ERROR_ON_MSG(target > 2, "Invalid target. Target must be 0 (NEON), 1 (OpenCL) or 2 (OpenCL with Tuner)"); - if((target == 1 || target == 2) && graph::Graph::opencl_is_available()) - { - // If type of target is OpenCL, check if OpenCL is available and initialize the scheduler - return graph::TargetHint::OPENCL; - } - else - { - return graph::TargetHint::NEON; - } -} - /** Generates appropriate output accessor according to the specified labels_path * * @note If labels_path is empty will generate a DummyAccessor else will generate a TopNPredictionsAccessor @@ -324,21 +300,20 @@ inline std::unique_ptr get_output_accessor(const std::st * * @return the TargetHint */ -inline graph2::Target set_target_hint2(int target) +inline graph::Target set_target_hint(int target) { ARM_COMPUTE_ERROR_ON_MSG(target > 3, "Invalid target. Target must be 0 (NEON), 1 (OpenCL), 2 (OpenCL + Tuner), 3 (GLES)"); - if((target == 1 || target == 2) && arm_compute::opencl_is_available()) + if((target == 1 || target == 2)) { - // If type of target is OpenCL, check if OpenCL is available and initialize the scheduler - return graph2::Target::CL; + return graph::Target::CL; } else if(target == 3) { - return graph2::Target::GC; + return graph::Target::GC; } else { - return graph2::Target::NEON; + return graph::Target::NEON; } } } // namespace graph_utils -- cgit v1.2.1