diff options
-rw-r--r-- | src/graph/mutators/InPlaceOperationMutator.cpp | 10 | ||||
-rw-r--r-- | utils/GraphUtils.cpp | 14 | ||||
-rw-r--r-- | utils/GraphUtils.h | 46 |
3 files changed, 65 insertions, 5 deletions
diff --git a/src/graph/mutators/InPlaceOperationMutator.cpp b/src/graph/mutators/InPlaceOperationMutator.cpp index 1c2985dce..07e3ecf2c 100644 --- a/src/graph/mutators/InPlaceOperationMutator.cpp +++ b/src/graph/mutators/InPlaceOperationMutator.cpp @@ -57,7 +57,11 @@ void InPlaceOperationMutator::mutate(Graph &g) ARM_COMPUTE_ERROR_ON(current_output_tensor == nullptr || new_output_tensor == nullptr); // Prevent in-place operation if there is an accessor bound to the in-place tensor or quantization info are different - if(new_output_tensor->accessor() == nullptr || current_output_tensor->desc().quant_info == new_output_tensor->desc().quant_info) + if(new_output_tensor->accessor() != nullptr || current_output_tensor->desc().quant_info != new_output_tensor->desc().quant_info) + { + ARM_COMPUTE_LOG_GRAPH_VERBOSE("Prevented in-place operation as there is an accessor bound to the input tensor or the quantization info are different.\n"); + } + else { ARM_COMPUTE_LOG_GRAPH_VERBOSE("Switching to in-place computation for the node with ID : " << node->id() << " and name : " << node->name() << std::endl); @@ -66,10 +70,6 @@ void InPlaceOperationMutator::mutate(Graph &g) // Update output node->set_output_tensor(new_output_tensor->id(), 0); } - else - { - ARM_COMPUTE_LOG_GRAPH_VERBOSE("Prevented in-place operation as there is an accessor bound to the input tensor\n"); - } } } } diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp index 6be289a7e..dad9aed6a 100644 --- a/utils/GraphUtils.cpp +++ b/utils/GraphUtils.cpp @@ -184,6 +184,20 @@ bool NumPyAccessor::access_tensor(ITensor &tensor) return false; } +SaveNumPyAccessor::SaveNumPyAccessor(std::string npy_name, const bool is_fortran) + : _npy_name(std::move(npy_name)), _is_fortran(is_fortran) +{ +} + +bool SaveNumPyAccessor::access_tensor(ITensor &tensor) +{ + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::F32); + + utils::save_to_npy(tensor, _npy_name, _is_fortran); + + return false; +} + ImageAccessor::ImageAccessor(std::string filename, bool bgr, std::unique_ptr<IPreprocessor> preprocessor) : _already_loaded(false), _filename(std::move(filename)), _bgr(bgr), _preprocessor(std::move(preprocessor)) { diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h index 88221c7dc..fe19eb319 100644 --- a/utils/GraphUtils.h +++ b/utils/GraphUtils.h @@ -167,6 +167,31 @@ private: std::ostream &_output_stream; }; +/** SaveNumPy accessor class */ +class SaveNumPyAccessor final : public graph::ITensorAccessor +{ +public: + /** Constructor + * + * @param[in] npy_name Npy file name. + * @param[in] is_fortran (Optional) If true, save tensor in fortran order. + */ + SaveNumPyAccessor(const std::string npy_name, const bool is_fortran = false); + /** Allow instances of this class to be move constructed */ + SaveNumPyAccessor(SaveNumPyAccessor &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + SaveNumPyAccessor(const SaveNumPyAccessor &) = delete; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + SaveNumPyAccessor &operator=(const SaveNumPyAccessor &) = delete; + + // Inherited methods overriden: + bool access_tensor(ITensor &tensor) override; + +private: + const std::string _npy_name; + const bool _is_fortran; +}; + /** Image accessor class */ class ImageAccessor final : public graph::ITensorAccessor { @@ -558,6 +583,27 @@ inline std::unique_ptr<graph::ITensorAccessor> get_npy_output_accessor(const std } } +/** 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 SaveNpyAccessor + * + * @param[in] npy_name Npy filename. + * @param[in] is_fortran (Optional) If true, save tensor in fortran order. + * + * @return An appropriate tensor accessor + */ +inline std::unique_ptr<graph::ITensorAccessor> get_save_npy_output_accessor(const std::string &npy_name, const bool is_fortran = false) +{ + if(npy_name.empty()) + { + return arm_compute::support::cpp14::make_unique<DummyAccessor>(0); + } + else + { + return arm_compute::support::cpp14::make_unique<SaveNumPyAccessor>(npy_name, is_fortran); + } +} + /** Permutes a given tensor shape given the input and output data layout * * @param[in] tensor_shape Tensor shape to permute |