}
return inputShapes;
}
+
+void Layer::SerializeLayerParameters(ParameterStringifyFunction& fn) const
+{
+ std::string layerType = GetLayerTypeAsCString(m_Type);
+ std::string backendId = std::string(m_BackendId);
+ if(!(m_LayerName.compare("") == 0) && !m_LayerName.empty())
+ {
+ fn("LayerName",m_LayerName);
+ }
+ if(!(layerType.compare("") == 0) && !layerType.empty())
+ {
+ fn("LayerType",layerType);
+ }
+ if(!(backendId.compare("") == 0) && !backendId.empty())
+ {
+ fn("BackendID",backendId);
+ }
+}
+
} // namespace armnn
/// Helper to serialize the layer parameters to string.
/// (currently used in DotSerializer and company).
- virtual void SerializeLayerParameters(ParameterStringifyFunction &) const {}
+ virtual void SerializeLayerParameters(ParameterStringifyFunction& fn) const;
// Free up the constant source data
virtual void ReleaseConstantData();
}
fn("BiasEnabled",(desc.m_BiasEnabled?"true":"false"));
+ fn("DataLayout",GetDataLayoutName(desc.m_DataLayout));
}
void
}
fn("BiasEnabled",(desc.m_BiasEnabled?"true":"false"));
+ fn("DataLayout",std::to_string(int(desc.m_DataLayout)));
}
void
#include <armnn/TypesUtils.hpp>
#include <backendsCommon/CpuTensorHandle.hpp>
#include <backendsCommon/WorkloadFactory.hpp>
-
+#include <string>
#include <DataLayoutIndexed.hpp>
using namespace armnnUtils;
Convolution2dLayer::Convolution2dLayer(const Convolution2dDescriptor& param, const char* name)
: LayerWithParameters(1, 1, LayerType::Convolution2d, param, name)
{
+
+}
+
+void Convolution2dLayer::SerializeLayerParameters(ParameterStringifyFunction& fn) const
+{
+ //using DescriptorType = Parameters;
+ const std::vector<TensorShape>& inputShapes =
+ {
+ GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(),
+ m_Weight->GetTensorInfo().GetShape()
+ };
+ const TensorShape filterShape = inputShapes[1];
+ DataLayoutIndexed dataLayoutIndex(m_Param.m_DataLayout);
+ unsigned int filterWidth = filterShape[dataLayoutIndex.GetWidthIndex()];
+ unsigned int filterHeight = filterShape[dataLayoutIndex.GetHeightIndex()];
+ unsigned int outChannels = filterShape[0];
+
+ fn("OutputChannels",std::to_string(outChannels));
+ fn("FilterWidth",std::to_string(filterWidth));
+ fn("FilterHeight",std::to_string(filterHeight));
+ LayerWithParameters<Convolution2dDescriptor>::SerializeLayerParameters(fn);
}
std::unique_ptr<IWorkload> Convolution2dLayer::CreateWorkload(const Graph& graph, const IWorkloadFactory& factory) const
class Convolution2dLayer : public LayerWithParameters<Convolution2dDescriptor>
{
public:
+
/// A unique pointer to store Weight values.
std::unique_ptr<ScopedCpuTensorHandle> m_Weight;
/// A unique pointer to store Bias values.
void Accept(ILayerVisitor& visitor) const override;
+ void SerializeLayerParameters(ParameterStringifyFunction& fn) const override;
+
protected:
/// Constructor to create a Convolution2dLayer.
/// @param [in] param Convolution2dDescriptor to configure the convolution2d operation.
#include <backendsCommon/CpuTensorHandle.hpp>
#include <backendsCommon/WorkloadFactory.hpp>
-
+#include <string>
#include <DataLayoutIndexed.hpp>
using namespace armnnUtils;
{
}
+void DepthwiseConvolution2dLayer::SerializeLayerParameters(ParameterStringifyFunction& fn) const
+{
+ const std::vector<TensorShape>& inputShapes =
+ {
+ GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(),
+ m_Weight->GetTensorInfo().GetShape()
+ };
+ const TensorShape filterShape = inputShapes[1];
+ DataLayoutIndexed dataLayoutIndex(m_Param.m_DataLayout);
+ unsigned int inputChannels = filterShape[1];
+ unsigned int filterWidth = filterShape[3];
+ unsigned int filterHeight = filterShape[2];
+ unsigned int depthMultiplier = filterShape[0];
+
+ fn("FilterWidth",std::to_string(filterWidth));
+ fn("FilterHeight",std::to_string(filterHeight));
+ fn("DepthMultiplier",std::to_string(depthMultiplier));
+ fn("InputChannels",std::to_string(inputChannels));
+
+ LayerWithParameters<DepthwiseConvolution2dDescriptor>::SerializeLayerParameters(fn);
+}
+
std::unique_ptr<IWorkload> DepthwiseConvolution2dLayer::CreateWorkload(const Graph& graph,
const IWorkloadFactory& factory) const
{
void Accept(ILayerVisitor& visitor) const override;
+ void SerializeLayerParameters(ParameterStringifyFunction& fn) const override;
+
protected:
/// Constructor to create a DepthwiseConvolution2dLayer.
/// @param [in] param DepthwiseConvolution2dDescriptor to configure the depthwise convolution2d.
/// Helper to serialize the layer parameters to string
/// (currently used in DotSerializer and company).
- void SerializeLayerParameters(ParameterStringifyFunction & fn) const
+ void SerializeLayerParameters(ParameterStringifyFunction& fn) const override
{
StringifyLayerParameters<Parameters>::Serialize(fn, m_Param);
+ Layer::SerializeLayerParameters(fn);
}
protected:
"digraph Optimized {\n"
" node [shape=\"record\"];\n"
" edge [fontsize=8 fontcolor=\"blue\" fontname=\"arial-bold\"];\n"
- " " << inputId << " [label=\"{Input}\"];\n"
- " " << addId << " [label=\"{Addition}\"];\n"
- " " << outputId << " [label=\"{Output}\"];\n"
+ " " << inputId << " [label=\"{Input|LayerType : Input\\lBackendID : CpuRef\\l}\"];\n"
+ " " << addId << " [label=\"{Addition|LayerType : Addition\\lBackendID : CpuRef\\l}\"];\n"
+ " " << outputId << " [label=\"{Output|LayerType : Output\\lBackendID : CpuRef\\l}\"];\n"
" " << inputId << " -> " << addId << " [label=< [4] >];\n"
" " << inputId << " -> " << addId << " [label=< [4] >];\n"
" " << addId << " -> " << outputId << " [label=< [4] >];\n"
"digraph Optimized {\n"
" node [shape=\"record\"];\n"
" edge [fontsize=8 fontcolor=\"blue\" fontname=\"arial-bold\"];\n"
- " " << inputId << " [label=\"{Input}\"];\n"
- " " << floorId << " [label=\"{Floor}\"];\n"
- " " << outputId << " [label=\"{Output}\"];\n"
+ " " << inputId << " [label=\"{Input|LayerType : Input\\lBackendID : CpuRef\\l}\"];\n"
+ " " << floorId << " [label=\"{Floor|LayerType : Floor\\lBackendID : CpuRef\\l}\"];\n"
+ " " << outputId << " [label=\"{Output|LayerType : Output\\lBackendID : CpuRef\\l}\"];\n"
" " << inputId << " -> " << floorId << " [label=< [4] >];\n"
" " << floorId << " -> " << outputId << " [label=< [4] >];\n"
"}\n";
"If left empty (the default), the output tensors will not be written to a file.")
("event-based-profiling,e", po::bool_switch()->default_value(false),
"Enables built in profiler. If unset, defaults to off.")
+ ("visualize-optimized-model,v", po::bool_switch()->default_value(false),
+ "Enables built optimized model visualizer. If unset, defaults to off.")
("fp16-turbo-mode,h", po::bool_switch()->default_value(false), "If this option is enabled, FP32 layers, "
"weights and biases will be converted to FP16 where the backend supports it")
("threshold-time,r", po::value<double>(&thresholdTime)->default_value(0.0),
// Get the value of the switch arguments.
bool concurrent = vm["concurrent"].as<bool>();
bool enableProfiling = vm["event-based-profiling"].as<bool>();
+ bool enableLayerDetails = vm["visualize-optimized-model"].as<bool>();
bool enableFp16TurboMode = vm["fp16-turbo-mode"].as<bool>();
bool quantizeInput = vm["quantize-input"].as<bool>();
bool printIntermediate = vm["print-intermediate-layers"].as<bool>();
{
testCase.values.insert(testCase.values.begin(), executableName);
results.push_back(std::async(std::launch::async, RunCsvTest, std::cref(testCase), std::cref(runtime),
- enableProfiling, enableFp16TurboMode, thresholdTime, printIntermediate));
+ enableProfiling, enableFp16TurboMode, thresholdTime, printIntermediate,
+ enableLayerDetails));
}
// Check results
{
testCase.values.insert(testCase.values.begin(), executableName);
if (RunCsvTest(testCase, runtime, enableProfiling,
- enableFp16TurboMode, thresholdTime, printIntermediate) != EXIT_SUCCESS)
+ enableFp16TurboMode, thresholdTime, printIntermediate,
+ enableLayerDetails) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
return RunTest(modelFormat, inputTensorShapes, computeDevices, dynamicBackendsPath, modelPath, inputNames,
inputTensorDataFilePaths, inputTypes, quantizeInput, outputTypes, outputNames,
outputTensorFiles, enableProfiling, enableFp16TurboMode, thresholdTime, printIntermediate,
- subgraphId);
+ subgraphId, enableLayerDetails);
}
}
const double& thresholdTime,
bool printIntermediate,
const size_t subgraphId,
+ bool enableLayerDetails = false,
const std::shared_ptr<armnn::IRuntime>& runtime = nullptr)
{
using TContainer = boost::variant<std::vector<float>, std::vector<int>, std::vector<unsigned char>>;
params.m_ComputeDevices = computeDevices;
params.m_DynamicBackendsPath = dynamicBackendsPath;
params.m_PrintIntermediateLayers = printIntermediate;
+ params.m_VisualizePostOptimizationModel = enableLayerDetails;
for(const std::string& inputName: inputNames)
{
const double& thresholdTime,
bool printIntermediate,
const size_t subgraphId,
+ bool enableLayerDetails = false,
const std::shared_ptr<armnn::IRuntime>& runtime = nullptr)
{
std::string modelFormat = boost::trim_copy(format);
dynamicBackendsPath, inputNamesVector, inputTensorShapes,
inputTensorDataFilePathsVector, inputTypesVector, quantizeInput,
outputTypesVector, outputNamesVector, outputTensorFilesVector, enableProfiling,
- enableFp16TurboMode, thresholdTime, printIntermediate, subgraphId, runtime);
+ enableFp16TurboMode, thresholdTime, printIntermediate, subgraphId, enableLayerDetails, runtime);
#else
BOOST_LOG_TRIVIAL(fatal) << "Not built with serialization support.";
return EXIT_FAILURE;
quantizeInput, outputTypesVector, outputNamesVector,
outputTensorFilesVector, enableProfiling,
enableFp16TurboMode, thresholdTime,
- printIntermediate, subgraphId, runtime);
+ printIntermediate, subgraphId, enableLayerDetails,
+ runtime);
#else
BOOST_LOG_TRIVIAL(fatal) << "Not built with Caffe parser support.";
return EXIT_FAILURE;
inputNamesVector, inputTensorShapes,
inputTensorDataFilePathsVector, inputTypesVector,
quantizeInput, outputTypesVector, outputNamesVector,
- outputTensorFilesVector, enableProfiling,
- enableFp16TurboMode, thresholdTime,
- printIntermediate, subgraphId, runtime);
+ outputTensorFilesVector, enableProfiling, enableFp16TurboMode,
+ thresholdTime,printIntermediate, subgraphId,
+ enableLayerDetails, runtime);
#else
BOOST_LOG_TRIVIAL(fatal) << "Not built with Onnx parser support.";
return EXIT_FAILURE;
inputNamesVector, inputTensorShapes,
inputTensorDataFilePathsVector, inputTypesVector,
quantizeInput, outputTypesVector, outputNamesVector,
- outputTensorFilesVector, enableProfiling,
- enableFp16TurboMode, thresholdTime,
- printIntermediate, subgraphId, runtime);
+ outputTensorFilesVector, enableProfiling, enableFp16TurboMode,
+ thresholdTime,printIntermediate, subgraphId,
+ enableLayerDetails, runtime);
#else
BOOST_LOG_TRIVIAL(fatal) << "Not built with Tensorflow parser support.";
return EXIT_FAILURE;
inputTensorDataFilePathsVector, inputTypesVector,
quantizeInput, outputTypesVector, outputNamesVector,
outputTensorFilesVector, enableProfiling,
- enableFp16TurboMode, thresholdTime,
- printIntermediate, subgraphId, runtime);
+ enableFp16TurboMode, thresholdTime, printIntermediate,
+ subgraphId, enableLayerDetails, runtime);
#else
BOOST_LOG_TRIVIAL(fatal) << "Unknown model format: '" << modelFormat <<
"'. Please include 'caffe', 'tensorflow', 'tflite' or 'onnx'";
int RunCsvTest(const armnnUtils::CsvRow &csvRow, const std::shared_ptr<armnn::IRuntime>& runtime,
const bool enableProfiling, const bool enableFp16TurboMode, const double& thresholdTime,
- const bool printIntermediate)
+ const bool printIntermediate, bool enableLayerDetails = false)
{
std::string modelFormat;
std::string modelPath;
return RunTest(modelFormat, inputTensorShapes, computeDevices, dynamicBackendsPath, modelPath, inputNames,
inputTensorDataFilePaths, inputTypes, quantizeInput, outputTypes, outputNames, outputTensorFiles,
- enableProfiling, enableFp16TurboMode, thresholdTime, printIntermediate, subgraphId);
+ enableProfiling, enableFp16TurboMode, thresholdTime, printIntermediate, subgraphId,
+ enableLayerDetails);
}