From d1628bffe27db398ff5c67c2e20f89e729f8bc31 Mon Sep 17 00:00:00 2001 From: Teresa Charlin Date: Tue, 30 Aug 2022 14:27:10 +0100 Subject: IVGCVSW-7006 Remove deprecated code due to be removed in 22.08 * AddConv and AddDWConv with weights and bias * ResizeBilinearDescriptor * b,blacklist option in accuracy tool !android-nn-driver:8172 Signed-off-by: Teresa Charlin Change-Id: Ibbc04fd18be7f938b11590bf67cd7af103cb4d99 --- include/armnn/Descriptors.hpp | 37 ----------------- include/armnn/DescriptorsFwd.hpp | 1 - include/armnn/INetwork.hpp | 36 ---------------- include/armnn/backends/WorkloadData.hpp | 10 ----- .../src/pyarmnn/swig/modules/armnn_network.i | 26 +----------- python/pyarmnn/test/test_network.py | 14 +------ shim/sl/canonical/Converter.cpp | 14 +++++-- src/armnn/Network.cpp | 25 ----------- src/armnn/layers/Convolution2dLayer.hpp | 1 - src/armnn/test/GraphTests.cpp | 14 +++---- src/armnnSerializer/test/SerializerTests.cpp | 30 +++++++------- src/backends/backendsCommon/WorkloadData.cpp | 48 ---------------------- .../ModelAccuracyTool-Armnn.cpp | 5 --- 13 files changed, 35 insertions(+), 226 deletions(-) diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp index 493ce65976..2540073090 100644 --- a/include/armnn/Descriptors.hpp +++ b/include/armnn/Descriptors.hpp @@ -921,43 +921,6 @@ struct GatherDescriptor : BaseDescriptor int32_t m_Axis; }; -/// A ResizeBilinearDescriptor for the ResizeBilinearLayer. -struct ARMNN_DEPRECATED_MSG_REMOVAL_DATE( - "ResizeBilinearDescriptor is not supported anymore. Use ResizeDescriptor instead.", - "22.08") - ResizeBilinearDescriptor : BaseDescriptor -{ - ResizeBilinearDescriptor() - : m_TargetWidth(0) - , m_TargetHeight(0) - , m_DataLayout(DataLayout::NCHW) - , m_AlignCorners(false) - , m_HalfPixelCenters(false) - {} - - ARMNN_NO_DEPRECATE_WARN_BEGIN - bool operator ==(const ResizeBilinearDescriptor& rhs) const - { - return m_TargetWidth == rhs.m_TargetWidth && - m_TargetHeight == rhs.m_TargetHeight && - m_DataLayout == rhs.m_DataLayout && - m_AlignCorners == rhs.m_AlignCorners && - m_HalfPixelCenters == rhs.m_HalfPixelCenters; - } - ARMNN_NO_DEPRECATE_WARN_END - - /// Target width value. - uint32_t m_TargetWidth; - /// Target height value. - uint32_t m_TargetHeight; - /// The data layout to be used (NCHW, NHWC). - DataLayout m_DataLayout; - /// Aligned corners - bool m_AlignCorners; - /// Half Pixel Centers - bool m_HalfPixelCenters; -}; - /// A ResizeDescriptor for the ResizeLayer. struct ResizeDescriptor : BaseDescriptor { diff --git a/include/armnn/DescriptorsFwd.hpp b/include/armnn/DescriptorsFwd.hpp index c0c1cc238d..08833504bb 100644 --- a/include/armnn/DescriptorsFwd.hpp +++ b/include/armnn/DescriptorsFwd.hpp @@ -39,7 +39,6 @@ struct Pooling3dDescriptor; struct PreCompiledDescriptor; struct QLstmDescriptor; struct ReshapeDescriptor; -struct ResizeBilinearDescriptor; struct ResizeDescriptor; struct ReduceDescriptor; struct SliceDescriptor; diff --git a/include/armnn/INetwork.hpp b/include/armnn/INetwork.hpp index ecc888d9c1..fefb2ebc2d 100644 --- a/include/armnn/INetwork.hpp +++ b/include/armnn/INetwork.hpp @@ -295,29 +295,6 @@ public: IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor, const char* name = nullptr); - /// Adds a 2D convolution layer to the network. - /// @param convolution2dDescriptor - Description of the 2D convolution layer. - /// @param weights - Tensor for the weights data. - /// @param biases - Optional tensor for the bias data. If specified, must match the output tensor shape. - /// @param name - Optional name for the layer. - /// @return - Interface for configuring the layer. - ARMNN_DEPRECATED_MSG_REMOVAL_DATE("This AddConvolution2dLayer overload is deprecated", "22.08") - IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const Optional& biases, - const char* name = nullptr); - - ARMNN_DEPRECATED_MSG_REMOVAL_DATE("This AddConvolution2dLayer overload is deprecated", "22.08") - IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const char* name = nullptr); - - ARMNN_DEPRECATED_MSG_REMOVAL_DATE("This AddConvolution2dLayer overload is deprecated", "22.08") - IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const ConstTensor& biases, - const char* name = nullptr); - /// Adds a 3D convolution layer to the network. /// @param convolution3dDescriptor - Description of the 3D convolution layer. /// @param name - Optional name for the layer. @@ -339,19 +316,6 @@ public: IConnectableLayer* AddDepthwiseConvolution2dLayer(const DepthwiseConvolution2dDescriptor& convolution2dDescriptor, const char* name = nullptr); - /// Adds a 2D depthwise convolution layer to the network. - /// @param convolution2dDescriptor - Description of the 2D depthwise convolution layer. - /// @param weights - Tensor for the weights. Expected format: [channelMultiplier, inputChannels, height, width]. - /// @param biases Optional tensor for the bias data. If specified, must match the output tensor shape. - /// @param name - Optional name for the layer. - /// @return - Interface for configuring the layer. - ARMNN_DEPRECATED_MSG("This AddDepthwiseConvolution2dLayer overload is deprecated") - IConnectableLayer* AddDepthwiseConvolution2dLayer( - const DepthwiseConvolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const Optional& biases, - const char* name = nullptr); - /// Adds a Dequantize layer to the network. /// @return - Interface for configuring the layer. IConnectableLayer* AddDequantizeLayer(const char* name = nullptr); diff --git a/include/armnn/backends/WorkloadData.hpp b/include/armnn/backends/WorkloadData.hpp index 00962ed52c..214ea7b060 100644 --- a/include/armnn/backends/WorkloadData.hpp +++ b/include/armnn/backends/WorkloadData.hpp @@ -353,16 +353,6 @@ struct RankQueueDescriptor : QueueDescriptor void Validate(const WorkloadInfo& workloadInfo) const; }; -ARMNN_NO_DEPRECATE_WARN_BEGIN -struct -ARMNN_DEPRECATED_MSG_REMOVAL_DATE("ResizeBilinearQueueDescriptor is deprecated use ResizeQueueDescriptor instead", - "22.08") -ResizeBilinearQueueDescriptor : QueueDescriptorWithParameters -{ - void Validate(const WorkloadInfo& workloadInfo) const; -}; -ARMNN_NO_DEPRECATE_WARN_END - struct ResizeQueueDescriptor : QueueDescriptorWithParameters { void Validate(const WorkloadInfo& workloadInfo) const; diff --git a/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i b/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i index 55b6795c90..f91bccc449 100644 --- a/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i +++ b/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i @@ -1179,25 +1179,15 @@ public: Args: convolution2dDescriptor (Convolution2dDescriptor): Description of the 2D convolution layer. - weights (ConstTensor): Tensor for the weights data. - biases (ConstTensor): Optional tensor for the bias data. If specified, must match the output tensor shape. name (str): Optional name for the layer. Returns: IConnectableLayer: Interface for configuring the layer. ") AddConvolution2dLayer; armnn::IConnectableLayer* AddConvolution2dLayer(const armnn::Convolution2dDescriptor& convolution2dDescriptor, - const armnn::ConstTensor& weights, - armnn::ConstTensor* biases = nullptr, const char* name = nullptr) { - if (biases) { - return $self->AddConvolution2dLayer(convolution2dDescriptor, weights, - armnn::Optional(*biases), name); - } else { - return $self->AddConvolution2dLayer(convolution2dDescriptor, weights, - armnn::Optional(), name); - } + return $self->AddConvolution2dLayer(convolution2dDescriptor, name); } %feature("docstring", @@ -1206,8 +1196,6 @@ public: Args: convolution2dDescriptor (DepthwiseConvolution2dDescriptor): Description of the 2D depthwise convolution layer. - weights (ConstTensor): Tensor for the weights. Expected format: [channelMultiplier, inputChannels, height, width]. - biases (ConstTensor): Optional tensor for the bias data. If specified, must match the output tensor shape. name (str): Optional name for the layer. Returns: @@ -1216,19 +1204,9 @@ public: armnn::IConnectableLayer* AddDepthwiseConvolution2dLayer( const armnn::DepthwiseConvolution2dDescriptor& convolution2dDescriptor, - const armnn::ConstTensor& weights, - const armnn::ConstTensor* biases = nullptr, const char* name = nullptr) { - ARMNN_NO_DEPRECATE_WARN_BEGIN - if (biases) { - return $self->AddDepthwiseConvolution2dLayer(convolution2dDescriptor, weights, - armnn::Optional(*biases), name); - } else { - return $self->AddDepthwiseConvolution2dLayer(convolution2dDescriptor, weights, - armnn::Optional(), name); - } - ARMNN_NO_DEPRECATE_WARN_END + return $self->AddDepthwiseConvolution2dLayer(convolution2dDescriptor, name); } } diff --git a/python/pyarmnn/test/test_network.py b/python/pyarmnn/test/test_network.py index ce1dffb86b..88be5a8e7f 100644 --- a/python/pyarmnn/test/test_network.py +++ b/python/pyarmnn/test/test_network.py @@ -253,17 +253,7 @@ def test_network_method_exists(method): def test_Convolution2d_layer_optional_none(): net = ann.INetwork() - layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(), - weights=ann.ConstTensor()) - - assert layer - - -def test_Convolution2d_layer_optional_provided(): - net = ann.INetwork() - layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(), - weights=ann.ConstTensor(), - biases=ann.ConstTensor()) + layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor()) assert layer @@ -271,8 +261,6 @@ def test_Convolution2d_layer_optional_provided(): def test_Convolution2d_layer_all_args(): net = ann.INetwork() layer = net.AddConvolution2dLayer(convolution2dDescriptor=ann.Convolution2dDescriptor(), - weights=ann.ConstTensor(), - biases=ann.ConstTensor(), name='NAME1') assert layer diff --git a/shim/sl/canonical/Converter.cpp b/shim/sl/canonical/Converter.cpp index b50b0a9397..5d52b4a779 100644 --- a/shim/sl/canonical/Converter.cpp +++ b/shim/sl/canonical/Converter.cpp @@ -2233,16 +2233,22 @@ bool Converter::ConvertGroupedConv2d(const Operation& operation, const Model& mo { return false; } - ARMNN_NO_DEPRECATE_WARN_BEGIN - IConnectableLayer* convLayer = - data.m_Network->AddConvolution2dLayer(desc, groupWeights, Optional(groupBiases)); - ARMNN_NO_DEPRECATE_WARN_END + + IConnectableLayer* weightsLayer = data.m_Network->AddConstantLayer(groupWeights); + IConnectableLayer* biasLayer = data.m_Network->AddConstantLayer(groupBiases); + IConnectableLayer* convLayer = data.m_Network->AddConvolution2dLayer(desc); + if (!convLayer) { return Fail("%s: AddConvolution2dLayer failed", __func__); } splitterLayer->GetOutputSlot(group).Connect(convLayer->GetInputSlot(0)); + weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1)); + biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2)); + + weightsLayer->GetOutputSlot(0).SetTensorInfo(groupWeightsInfo); + biasLayer->GetOutputSlot(0).SetTensorInfo(groupBiasesInfo); convLayer->GetOutputSlot(0).SetTensorInfo(groupOutputInfo); if(isDynamic) diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp index c4869fae04..3508ee882e 100644 --- a/src/armnn/Network.cpp +++ b/src/armnn/Network.cpp @@ -88,19 +88,6 @@ IConnectableLayer* INetwork::AddConvolution2dLayer(const Convolution2dDescriptor return pNetworkImpl->AddConvolution2dLayer(convolution2dDescriptor, name); } -ARMNN_NO_DEPRECATE_WARN_BEGIN -IConnectableLayer* INetwork::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const Optional& biases, - const char* name) -{ - return pNetworkImpl->AddConvolution2dLayer(convolution2dDescriptor, - weights, - armnn::Optional(biases), - name); -} -ARMNN_NO_DEPRECATE_WARN_END - IConnectableLayer* INetwork::AddConvolution3dLayer(const Convolution3dDescriptor& convolution3dDescriptor, const char* name) { @@ -123,18 +110,6 @@ IConnectableLayer* INetwork::AddDepthwiseConvolution2dLayer( } -ARMNN_NO_DEPRECATE_WARN_BEGIN -IConnectableLayer* INetwork::AddDepthwiseConvolution2dLayer( - const DepthwiseConvolution2dDescriptor& convolution2dDescriptor, - const ConstTensor& weights, - const Optional& biases, - const char* name) -{ - return pNetworkImpl->AddDepthwiseConvolution2dLayer(convolution2dDescriptor, weights, biases, name); -} -ARMNN_NO_DEPRECATE_WARN_END - - IConnectableLayer* INetwork::AddDequantizeLayer(const char* name) { return pNetworkImpl->AddDequantizeLayer(name); diff --git a/src/armnn/layers/Convolution2dLayer.hpp b/src/armnn/layers/Convolution2dLayer.hpp index 57999709cd..185a67252d 100644 --- a/src/armnn/layers/Convolution2dLayer.hpp +++ b/src/armnn/layers/Convolution2dLayer.hpp @@ -44,7 +44,6 @@ public: /// @return A vector to the inferred output shape. std::vector InferOutputShapes(const std::vector& inputShapes) const override; - void ExecuteStrategy(IStrategy& strategy) const override; void SerializeLayerParameters(ParameterStringifyFunction& fn) const override; diff --git a/src/armnn/test/GraphTests.cpp b/src/armnn/test/GraphTests.cpp index 95421c5683..eea7ae824a 100644 --- a/src/armnn/test/GraphTests.cpp +++ b/src/armnn/test/GraphTests.cpp @@ -632,13 +632,13 @@ TEST_CASE("IConnectableLayerConstantTensorsByRef") TensorInfo weightsInfo = constInfo; ConstTensor weights(weightsInfo, weightData); DepthwiseConvolution2dDescriptor desc; - ARMNN_NO_DEPRECATE_WARN_BEGIN - // GetConstantTensorsByRef() returns {m_Weights, m_Bias} so we need to use the old AddDepthwiseConvolution2dLayer() - const auto depthwiseLayer = net->AddDepthwiseConvolution2dLayer(desc, weights, EmptyOptional(), "Depthwise"); - ARMNN_NO_DEPRECATE_WARN_END - const void* resultData = depthwiseLayer->GetConstantTensorsByRef()[0].get()->GetConstTensor(); - auto resultValue = reinterpret_cast(resultData); - CHECK(resultValue[0] == 3); + + const auto weightsLayer = net->AddConstantLayer(weights); + + const void* resultDataWeights = weightsLayer->GetConstantTensorsByRef()[0].get()->GetConstTensor(); + auto resultValueWeights = reinterpret_cast(resultDataWeights); + CHECK(resultValueWeights[0] == 3); + } } diff --git a/src/armnnSerializer/test/SerializerTests.cpp b/src/armnnSerializer/test/SerializerTests.cpp index a568bf15c9..3573a8195c 100644 --- a/src/armnnSerializer/test/SerializerTests.cpp +++ b/src/armnnSerializer/test/SerializerTests.cpp @@ -436,19 +436,19 @@ TEST_CASE("SerializeConvolution2d") armnn::INetworkPtr network = armnn::INetwork::Create(); armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0); - ARMNN_NO_DEPRECATE_WARN_BEGIN - armnn::IConnectableLayer* const convLayer = - network->AddConvolution2dLayer(descriptor, - weights, - armnn::Optional(biases), - layerName.c_str()); - ARMNN_NO_DEPRECATE_WARN_END + armnn::IConnectableLayer* const weightsLayer = network->AddConstantLayer(weights, "weights"); + armnn::IConnectableLayer* const biasLayer = network->AddConstantLayer(biases, "bias"); + armnn::IConnectableLayer* const convLayer = network->AddConvolution2dLayer(descriptor, layerName.c_str()); armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0); inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0)); + weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1)); + biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2)); convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo); + weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo); + biasLayer->GetOutputSlot(0).SetTensorInfo(biasesInfo); convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo); armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network)); @@ -458,7 +458,7 @@ TEST_CASE("SerializeConvolution2d") deserializedNetwork->ExecuteStrategy(verifier); } -TEST_CASE("SerializeConvolution2dWithPerAxisParamsTestDeprecatedMethod") +TEST_CASE("SerializeConvolution2dWithPerAxisParams") { using namespace armnn; @@ -491,19 +491,19 @@ TEST_CASE("SerializeConvolution2dWithPerAxisParamsTestDeprecatedMethod") armnn::INetworkPtr network = armnn::INetwork::Create(); armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0); - ARMNN_NO_DEPRECATE_WARN_BEGIN - armnn::IConnectableLayer* const convLayer = - network->AddConvolution2dLayer(descriptor, - weights, - armnn::Optional(biases), - layerName.c_str()); - ARMNN_NO_DEPRECATE_WARN_END + armnn::IConnectableLayer* const weightsLayer = network->AddConstantLayer(weights, "weights"); + armnn::IConnectableLayer* const biasLayer = network->AddConstantLayer(weights, "bias"); + armnn::IConnectableLayer* const convLayer = network->AddConvolution2dLayer(descriptor, layerName.c_str()); armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0); inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0)); + weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1)); + biasLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(2)); convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo); + weightsLayer->GetOutputSlot(0).SetTensorInfo(kernelInfo); + biasLayer->GetOutputSlot(0).SetTensorInfo(biasInfo); convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo); armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network)); diff --git a/src/backends/backendsCommon/WorkloadData.cpp b/src/backends/backendsCommon/WorkloadData.cpp index f4afbd9a84..753fe06edb 100644 --- a/src/backends/backendsCommon/WorkloadData.cpp +++ b/src/backends/backendsCommon/WorkloadData.cpp @@ -1596,54 +1596,6 @@ void Pooling3dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output"); } - -void ResizeBilinearQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const -{ - const std::string descriptorName{"ResizeBilinearQueueDescriptor"}; - - ValidateNumInputs(workloadInfo, descriptorName, 1); - ValidateNumOutputs(workloadInfo, descriptorName, 1); - - const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0]; - const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0]; - - ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 4, "input"); - ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output"); - - std::vector supportedTypes = - { - DataType::BFloat16, - DataType::Float16, - DataType::Float32, - DataType::QAsymmS8, - DataType::QAsymmU8, - DataType::QSymmS16 - }; - - ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName); - ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output"); - - // ResizeBilinear only changes width and height: batch and channel count must match. - const unsigned int inputBatchSize = inputTensorInfo.GetShape()[0]; - const unsigned int outputBatchSize = outputTensorInfo.GetShape()[0]; - if (inputBatchSize != outputBatchSize) - { - throw InvalidArgumentException( - fmt::format("{}: Input batch size ({}) does not match output batch size ({})", - descriptorName, inputBatchSize, outputBatchSize)); - } - - DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout); - const unsigned int inputChannelCount = inputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()]; - const unsigned int outputChannelCount = outputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()]; - if (inputChannelCount != outputChannelCount) - { - throw InvalidArgumentException( - fmt::format("{}: Input channel count ({}) does not match output channel count ({})", - descriptorName, inputChannelCount, outputChannelCount)); - } -} - void ResizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const { const std::string descriptorName{"ResizeQueueDescriptor"}; diff --git a/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp b/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp index 49efbbf928..9e5507b9c2 100644 --- a/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp +++ b/tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp @@ -110,11 +110,6 @@ int main(int argc, char* argv[]) "Path to a excludelist file where each line denotes the index of an image to be " "excluded from evaluation.", cxxopts::value(excludelistPath)->default_value("")); - ARMNN_DEPRECATED_MSG_REMOVAL_DATE("This b,blacklist-path command is deprecated", "22.08") - ("b,blacklist-path", - "Path to a blacklist file where each line denotes the index of an image to be " - "excluded from evaluation. This command will be deprecated in favor of: --excludelist-path ", - cxxopts::value(excludelistPath)->default_value("")); auto result = options.parse(argc, argv); -- cgit v1.2.1