Zha0q1 commented on a change in pull request #15490: Utility to help developers debug operators: Tensor Inspector URL: https://github.com/apache/incubator-mxnet/pull/15490#discussion_r303189996
########## File path: src/common/tensor_inspector.h ########## @@ -0,0 +1,763 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/*! + * Copyright (c) 2019 by Contributors + * \file tensor_inspector.h + * \brief utility to inspect tensor objects + * \author Zhaoqi Zhu + */ + +#ifndef MXNET_COMMON_TENSOR_INSPECTOR_H_ +#define MXNET_COMMON_TENSOR_INSPECTOR_H_ + +#include <algorithm> +#include <cmath> +#include <string> +#include <vector> +#include <fstream> +#include "../../3rdparty/mshadow/mshadow/base.h" +#include "../../tests/cpp/include/test_util.h" + +namespace mxnet { + +/*! + * \brief this singleton struct mediates individual TensorInspector objects + * so that we can control the global behavior from each of them + */ +struct InspectorManager { + static InspectorManager* get() { + static std::mutex mtx; + static std::unique_ptr<InspectorManager> im = nullptr; + if (!im) { + std::unique_lock<std::mutex> lk(mtx); + if (!im) + im = std::make_unique<InspectorManager>(); + } + return im.get(); + } + /* !\brief mutex used to lock interactive_print() and check_value() */ + std::mutex mutex_; + /* !\brief skip all interactive prints */ + bool interactive_print_skip_all_ = false; + /* !\brief skip all value checks */ + bool check_value_skip_all_ = false; + /* !\brief visit count for interactive print tags */ + std::unordered_map<std::string, int> interactive_print_tag_counter_; + /* !\brief visit count for check value tags */ + std::unordered_map<std::string, int> check_value_tag_counter_; + /* !\brief visit count for dump value tags */ + std::unordered_map<std::string, int> dump_to_file_tag_counter_; +}; + +/*! + * \brief Enum for building value checkers for TensorInspector::check_value() + */ +enum CheckerType { + NegativeChecker, // check if is negative + PositiveChecker, // check if is positive + ZeroChecker, // check if is zero + NaNChecker, // check if is NaN, will always return false if DType is not a float type + InfChecker, // check if is infinity, will always return false if DType is not a float type + PositiveInfChecker, // check if is positive infinity, + // will always return false if DType is not a float type + NegativeInfChecker, // check if is nagative infinity, + // will always return false if DType is not a float type + FiniteChecker, // check if is finite, will always return false if DType is not a float type + NormalChecker, // check if is neither infinity nor NaN + AbnormalChecker, // chekck if is infinity or nan +}; + +/** + * _______ _____ _ + * |__ __| |_ _| | | + * | | ___ _ __ ___ ___ _ __| | _ __ ___ _ __ ___ ___| |_ ___ _ __ + * | |/ _ \ '_ \/ __|/ _ \| '__| | | '_ \/ __| '_ \ / _ \/ __| __/ _ \| '__| + * | | __/ | | \__ \ (_) | | _| |_| | | \__ \ |_) | __/ (__| || (_) | | + * |_|\___|_| |_|___/\___/|_||_____|_| |_|___/ .__/ \___|\___|\__\___/|_| + * | | + * |_| + */ + +/*! + * \brief This class provides a unified interface to inspect the value of all data types + * including Tensor, TBlob, and NDArray. If the tensor resides on GPU, then it will be + * copied from GPU memory back to CPU memory to be operated on. Internally, all data types + * are stored as a TBlob object tb_. + */ +class TensorInspector { + private: + /*! + * \brief generate the tensor info, including data type and shape + * \tparam DType the data type + * \tparam StreamType the type of the stream object + * \param os stream object to output to + */ + template<typename DType, typename StreamType> + void tensor_info_to_string(StreamType* os) { + const int dimension = tb_.ndim(); + *os << "<" << typeid(tb_.dptr<DType>()[0]).name() << " Tensor "; + *os << tb_.shape_[0]; + for (int i = 1; i < dimension; ++i) { + *os << 'x' << tb_.shape_[i]; + } + *os << ">" << std::endl; + } + + /*! + * \brief output the tensor info, including data type and shape + * \tparam DType the data type + * \tparam StreamType the type of the stream object + * \param os stream object to output to + * \param shape the shape of the tensor + */ + template<typename DType, typename StreamType> + void tensor_info_to_string(StreamType* os, const std::vector<int>& shape) { + const int dimension = shape.size(); + *os << "<" << typeid(tb_.dptr<DType>()[0]).name() << " Tensor "; + *os << shape[0]; + for (int i = 1; i < dimension; ++i) { + *os << 'x' << shape[i]; + } + *os << ">" << std::endl; + } + + /*! + * \brief output the tensor in a structed format Review comment: I will correct it along with other changes in the next commit ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services