arm_compute v19.02
Change-Id: I853a3ecf38f206da13c1b03640c8adf73c20477c
diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp
index 2f1df7a..ab2c753 100644
--- a/utils/GraphUtils.cpp
+++ b/utils/GraphUtils.cpp
@@ -420,6 +420,77 @@
_output_stream << "Accuracy : " << accuracy << std::endl;
}
+DetectionOutputAccessor::DetectionOutputAccessor(const std::string &labels_path, std::vector<TensorShape> &imgs_tensor_shapes, std::ostream &output_stream)
+ : _labels(), _tensor_shapes(std::move(imgs_tensor_shapes)), _output_stream(output_stream)
+{
+ _labels.clear();
+
+ std::ifstream ifs;
+
+ try
+ {
+ ifs.exceptions(std::ifstream::badbit);
+ ifs.open(labels_path, std::ios::in | std::ios::binary);
+
+ for(std::string line; !std::getline(ifs, line).fail();)
+ {
+ _labels.emplace_back(line);
+ }
+ }
+ catch(const std::ifstream::failure &e)
+ {
+ ARM_COMPUTE_ERROR("Accessing %s: %s", labels_path.c_str(), e.what());
+ }
+}
+
+template <typename T>
+void DetectionOutputAccessor::access_predictions_tensor(ITensor &tensor)
+{
+ const size_t num_detection = tensor.info()->valid_region().shape.y();
+ const auto output_prt = reinterpret_cast<T *>(tensor.buffer() + tensor.info()->offset_first_element_in_bytes());
+
+ if(num_detection > 0)
+ {
+ _output_stream << "---------------------- Detections ----------------------" << std::endl
+ << std::endl;
+
+ _output_stream << std::left << std::setprecision(4) << std::setw(8) << "Image | " << std::setw(8) << "Label | " << std::setw(12) << "Confidence | "
+ << "[ xmin, ymin, xmax, ymax ]" << std::endl;
+
+ for(size_t i = 0; i < num_detection; ++i)
+ {
+ auto im = static_cast<const int>(output_prt[i * 7]);
+ _output_stream << std::setw(8) << im << std::setw(8)
+ << _labels[output_prt[i * 7 + 1]] << std::setw(12) << output_prt[i * 7 + 2]
+ << " [" << (output_prt[i * 7 + 3] * _tensor_shapes[im].x())
+ << ", " << (output_prt[i * 7 + 4] * _tensor_shapes[im].y())
+ << ", " << (output_prt[i * 7 + 5] * _tensor_shapes[im].x())
+ << ", " << (output_prt[i * 7 + 6] * _tensor_shapes[im].y())
+ << "]" << std::endl;
+ }
+ }
+ else
+ {
+ _output_stream << "No detection found." << std::endl;
+ }
+}
+
+bool DetectionOutputAccessor::access_tensor(ITensor &tensor)
+{
+ ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::F32);
+
+ switch(tensor.info()->data_type())
+ {
+ case DataType::F32:
+ access_predictions_tensor<float>(tensor);
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT SUPPORTED!");
+ }
+
+ return false;
+}
+
TopNPredictionsAccessor::TopNPredictionsAccessor(const std::string &labels_path, size_t top_n, std::ostream &output_stream)
: _labels(), _output_stream(output_stream), _top_n(top_n)
{
diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h
index d7f24af..131378e 100644
--- a/utils/GraphUtils.h
+++ b/utils/GraphUtils.h
@@ -283,6 +283,36 @@
size_t _positive_samples_top5;
};
+/** Detection output accessor class */
+class DetectionOutputAccessor final : public graph::ITensorAccessor
+{
+public:
+ /** Constructor
+ *
+ * @param[in] labels_path Path to labels text file.
+ * @param[in] imgs_tensor_shapes Network input images tensor shapes.
+ * @param[out] output_stream (Optional) Output stream
+ */
+ DetectionOutputAccessor(const std::string &labels_path, std::vector<TensorShape> &imgs_tensor_shapes, std::ostream &output_stream = std::cout);
+ /** Allow instances of this class to be move constructed */
+ DetectionOutputAccessor(DetectionOutputAccessor &&) = default;
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ DetectionOutputAccessor(const DetectionOutputAccessor &) = delete;
+ /** Prevent instances of this class from being copied (As this class contains pointers) */
+ DetectionOutputAccessor &operator=(const DetectionOutputAccessor &) = delete;
+
+ // Inherited methods overriden:
+ bool access_tensor(ITensor &tensor) override;
+
+private:
+ template <typename T>
+ void access_predictions_tensor(ITensor &tensor);
+
+ std::vector<std::string> _labels;
+ std::vector<TensorShape> _tensor_shapes;
+ std::ostream &_output_stream;
+};
+
/** Result accessor class */
class TopNPredictionsAccessor final : public graph::ITensorAccessor
{
@@ -472,6 +502,39 @@
return arm_compute::support::cpp14::make_unique<TopNPredictionsAccessor>(graph_parameters.labels, top_n, output_stream);
}
}
+/** Generates appropriate output accessor according to the specified graph parameters
+ *
+ * @note If the output accessor is requested to validate the graph then ValidationOutputAccessor is generated
+ * else if output_accessor_file is empty will generate a DummyAccessor else will generate a TopNPredictionsAccessor
+ *
+ * @param[in] graph_parameters Graph parameters
+ * @param[in] tensor_shapes Network input images tensor shapes.
+ * @param[in] is_validation (Optional) Validation flag (default = false)
+ * @param[out] output_stream (Optional) Output stream (default = std::cout)
+ *
+ * @return An appropriate tensor accessor
+ */
+inline std::unique_ptr<graph::ITensorAccessor> get_detection_output_accessor(const arm_compute::utils::CommonGraphParams &graph_parameters,
+ std::vector<TensorShape> tensor_shapes,
+ bool is_validation = false,
+ std::ostream &output_stream = std::cout)
+{
+ if(!graph_parameters.validation_file.empty())
+ {
+ return arm_compute::support::cpp14::make_unique<ValidationOutputAccessor>(graph_parameters.validation_file,
+ output_stream,
+ graph_parameters.validation_range_start,
+ graph_parameters.validation_range_end);
+ }
+ else if(graph_parameters.labels.empty())
+ {
+ return arm_compute::support::cpp14::make_unique<DummyAccessor>(0);
+ }
+ else
+ {
+ return arm_compute::support::cpp14::make_unique<DetectionOutputAccessor>(graph_parameters.labels, tensor_shapes, output_stream);
+ }
+}
/** Generates appropriate npy output accessor according to the specified npy_path
*
* @note If npy_path is empty will generate a DummyAccessor else will generate a NpyAccessor
diff --git a/utils/TypePrinter.h b/utils/TypePrinter.h
index d089a5b..f2cf606 100644
--- a/utils/TypePrinter.h
+++ b/utils/TypePrinter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -882,6 +882,24 @@
return os;
}
+/** Formatted output of the Multiples type.
+ *
+ * @param[out] os Output stream.
+ * @param[in] multiples Type to output.
+ *
+ * @return Modified output stream.
+ */
+inline ::std::ostream &operator<<(::std::ostream &os, const Multiples &multiples)
+{
+ os << "(";
+ for(size_t i = 0; i < multiples.size() - 1; i++)
+ {
+ os << multiples[i] << ", ";
+ }
+ os << multiples.back() << ")";
+ return os;
+}
+
/** Formatted output of the InterpolationPolicy type.
*
* @param[out] os Output stream.
@@ -1234,6 +1252,19 @@
return str.str();
}
+/** Formatted output of the Multiples type.
+ *
+ * @param[in] multiples Type to output.
+ *
+ * @return Formatted string.
+ */
+inline std::string to_string(const Multiples &multiples)
+{
+ std::stringstream str;
+ str << multiples;
+ return str.str();
+}
+
/** Formatted output of the InterpolationPolicy type.
*
* @param[in] policy Type to output.
@@ -1291,6 +1322,55 @@
return str.str();
}
+/** Formatted output of the ArithmeticOperation type.
+ *
+ * @param[out] os Output stream.
+ * @param[in] op Operation to output.
+ *
+ * @return Modified output stream.
+ */
+inline ::std::ostream &operator<<(::std::ostream &os, const ArithmeticOperation &op)
+{
+ switch(op)
+ {
+ case ArithmeticOperation::ADD:
+ os << "ADD";
+ break;
+ case ArithmeticOperation::SUB:
+ os << "SUB";
+ break;
+ case ArithmeticOperation::DIV:
+ os << "DIV";
+ break;
+ case ArithmeticOperation::MAX:
+ os << "MAX";
+ break;
+ case ArithmeticOperation::MIN:
+ os << "MIN";
+ break;
+ case ArithmeticOperation::SQUARED_DIFF:
+ os << "SQUARED_DIFF";
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+ }
+
+ return os;
+}
+
+/** Formatted output of the Arithmetic Operation
+ *
+ * @param[in] op Type to output.
+ *
+ * @return Formatted string.
+ */
+inline std::string to_string(const ArithmeticOperation &op)
+{
+ std::stringstream str;
+ str << op;
+ return str.str();
+}
+
/** Formatted output of the Reduction Operations.
*
* @param[out] os Output stream.
@@ -1311,6 +1391,15 @@
case ReductionOperation::MEAN_SUM:
os << "MEAN_SUM";
break;
+ case ReductionOperation::ARG_IDX_MAX:
+ os << "ARG_IDX_MAX";
+ break;
+ case ReductionOperation::ARG_IDX_MIN:
+ os << "ARG_IDX_MIN";
+ break;
+ case ReductionOperation::PROD:
+ os << "PROD";
+ break;
default:
ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
}
@@ -1331,6 +1420,92 @@
return str.str();
}
+/** Formatted output of the Comparison Operations.
+ *
+ * @param[out] os Output stream.
+ * @param[in] op Type to output.
+ *
+ * @return Modified output stream.
+ */
+inline ::std::ostream &operator<<(::std::ostream &os, const ComparisonOperation &op)
+{
+ switch(op)
+ {
+ case ComparisonOperation::Equal:
+ os << "Equal";
+ break;
+ case ComparisonOperation::NotEqual:
+ os << "NotEqual";
+ break;
+ case ComparisonOperation::Greater:
+ os << "Greater";
+ break;
+ case ComparisonOperation::GreaterEqual:
+ os << "GreaterEqual";
+ break;
+ case ComparisonOperation::Less:
+ os << "Less";
+ break;
+ case ComparisonOperation::LessEqual:
+ os << "LessEqual";
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+ }
+
+ return os;
+}
+
+/** Formatted output of the Elementwise unary Operations.
+ *
+ * @param[out] os Output stream.
+ * @param[in] op Type to output.
+ *
+ * @return Modified output stream.
+ */
+inline ::std::ostream &operator<<(::std::ostream &os, const ElementWiseUnary &op)
+{
+ switch(op)
+ {
+ case ElementWiseUnary::RSQRT:
+ os << "RSQRT";
+ break;
+ case ElementWiseUnary::EXP:
+ os << "EXP";
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+ }
+
+ return os;
+}
+
+/** Formatted output of the Comparison Operations.
+ *
+ * @param[in] op Type to output.
+ *
+ * @return Formatted string.
+ */
+inline std::string to_string(const ComparisonOperation &op)
+{
+ std::stringstream str;
+ str << op;
+ return str.str();
+}
+
+/** Formatted output of the Elementwise unary Operations.
+ *
+ * @param[in] op Type to output.
+ *
+ * @return Formatted string.
+ */
+inline std::string to_string(const ElementWiseUnary &op)
+{
+ std::stringstream str;
+ str << op;
+ return str.str();
+}
+
/** Formatted output of the Norm Type.
*
* @param[in] type Type to output.
@@ -1729,6 +1904,85 @@
return os;
}
+/** Formatted output of the DetectionOutputLayerCodeType type.
+ *
+ * @param[out] os Output stream
+ * @param[in] detection_code Type to output
+ *
+ * @return Modified output stream.
+ */
+inline ::std::ostream &operator<<(::std::ostream &os, const DetectionOutputLayerCodeType &detection_code)
+{
+ switch(detection_code)
+ {
+ case DetectionOutputLayerCodeType::CENTER_SIZE:
+ os << "CENTER_SIZE";
+ break;
+ case DetectionOutputLayerCodeType::CORNER:
+ os << "CORNER";
+ break;
+ case DetectionOutputLayerCodeType::CORNER_SIZE:
+ os << "CORNER_SIZE";
+ break;
+ case DetectionOutputLayerCodeType::TF_CENTER:
+ os << "TF_CENTER";
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+ }
+
+ return os;
+}
+/** Formatted output of the DetectionOutputLayerCodeType type.
+ *
+ * @param[in] detection_code Type to output
+ *
+ * @return Formatted string.
+ */
+inline std::string to_string(const DetectionOutputLayerCodeType &detection_code)
+{
+ std::stringstream str;
+ str << detection_code;
+ return str.str();
+}
+
+/** Formatted output of the DetectionOutputLayerInfo type.
+ *
+ * @param[out] os Output stream
+ * @param[in] detection_info Type to output
+ *
+ * @return Modified output stream.
+ */
+inline ::std::ostream &operator<<(::std::ostream &os, const DetectionOutputLayerInfo &detection_info)
+{
+ os << "{Classes=" << detection_info.num_classes() << ","
+ << "ShareLocation=" << detection_info.share_location() << ","
+ << "CodeType=" << detection_info.code_type() << ","
+ << "VarianceEncodedInTarget=" << detection_info.variance_encoded_in_target() << ","
+ << "KeepTopK=" << detection_info.keep_top_k() << ","
+ << "NMSThreshold=" << detection_info.nms_threshold() << ","
+ << "Eta=" << detection_info.eta() << ","
+ << "BackgroundLabelId=" << detection_info.background_label_id() << ","
+ << "ConfidenceThreshold=" << detection_info.confidence_threshold() << ","
+ << "TopK=" << detection_info.top_k() << ","
+ << "NumLocClasses=" << detection_info.num_loc_classes()
+ << "}";
+
+ return os;
+}
+
+/** Formatted output of the DetectionOutputLayerInfo type.
+ *
+ * @param[in] detection_info Type to output
+ *
+ * @return Formatted string.
+ */
+inline std::string to_string(const DetectionOutputLayerInfo &detection_info)
+{
+ std::stringstream str;
+ str << detection_info;
+ return str.str();
+}
/** Formatted output of the DetectionWindow type.
*
* @param[in] detection_window Type to output
diff --git a/utils/Utils.h b/utils/Utils.h
index 8cac857..04ccc3e 100644
--- a/utils/Utils.h
+++ b/utils/Utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 ARM Limited.
+ * Copyright (c) 2016-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*