exception.h 6.5 KB
Newer Older
1 2 3 4
/**
 * \file src/core/include/megbrain/exception.h
 * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
 *
5
 * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
6 7 8
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
9 10
 * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
 */

#pragma once

#include "megbrain_build_config.h"

#include <memory>
#include <stdexcept>
#include <string>

#if MGB_ENABLE_EXCEPTION
#define MGB_IF_EXCEPTION(x...) x
#else
#define MGB_IF_EXCEPTION(x...)
#endif

#if (defined(__GNUC__) && !defined(__ANDROID__) && !defined(ANDROID) && \
     !defined(__APPLE__))
#include <cxxabi.h>  // for abi::__forced_unwind
#define __MGB_HANDLE_FORCED_UNWIND MGB_CATCH(abi::__forced_unwind&, { throw; })
#else
#define __MGB_HANDLE_FORCED_UNWIND
#endif

/*!
 * \brief catch all exceptions and store in an exception_ptr; usually used in
 *      worker threads
 *
 * This macro should be inserted after a try block
 * \param _scope_msg const char* type text to describe where this exception is
 *      caught
 */
#define MGB_CATCH_ALL_EXCEPTION(_scope_msg, _ptr)                       \
    MGB_CATCH(std::exception& _exc, {                                   \
        mgb_log_error("caught exception in %s; what(): %s", _scope_msg, \
                      _exc.what());                                     \
        _ptr = std::current_exception();                                \
    })                                                                  \
    __MGB_HANDLE_FORCED_UNWIND                                          \
    MGB_CATCH(..., {                                                    \
        mgb_log_error("caught unknown exception in %s", _scope_msg);    \
        _ptr = std::current_exception();                                \
    })                                                                  \
    do {                                                                \
    } while (0)

/*!
 * \brief catch all exceptions in a class destructor and log error and abort
 *
 * \param _scope_msg const char* type text to describe where this exception is
 *      caught
 */
#define MGB_HANDLE_EXCEPTION_DTOR(_scope_msg)                                 \
    MGB_CATCH(std::exception& _exc, {                                         \
        mgb_log_error("abort due to exception in %s; what(): %s", _scope_msg, \
                      _exc.what());                                           \
        abort();                                                              \
    })                                                                        \
    MGB_CATCH(..., {                                                          \
        mgb_log_error("abort due to unknown exception in %s", _scope_msg);    \
    })                                                                        \
    do {                                                                      \
    } while (0)

namespace mgb {

//! the most general MegBrain exception type; also base class for all megbrain
//! exceptions
79 80 81 82 83 84 85 86 87 88
class MegBrainError : public std::exception {
protected:
    std::string m_msg;

public:
    /*!
     * \brief base class for extra information to be associated with an
     *      exception
     */
    class ExtraInfo {
89
    public:
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
        virtual ~ExtraInfo() = default;
    };

    MegBrainError(const std::string& msg) : m_msg(msg) { init(); }

    const char* what() const noexcept override { return m_msg.c_str(); }

    /*!
     * \brief get associated extra info, or nullptr
     */
    const ExtraInfo* extra_info() const { return m_extra_info.get(); }

    /*!
     * \brief set extra info
     */
    template <typename T>
    MegBrainError& extra_info(T&& ptr) {
        m_extra_info = ptr;
        return *this;
    }
110

111 112 113 114 115
    ~MegBrainError() noexcept = default;

private:
    std::shared_ptr<ExtraInfo> m_extra_info;
    void init();
116 117 118 119
};

//! base class for system error: error caused by uncontrollable environment
class SystemError : public MegBrainError {
120 121
public:
    using MegBrainError::MegBrainError;
122 123 124 125 126
};

/*!
 * \brief exception to be thrown if failing to allocate memory
 */
127 128 129
class MemAllocError : public SystemError {
public:
    using SystemError::SystemError;
130 131
};

132 133 134 135 136 137 138 139
class CudaError final : public SystemError {
public:
    /*!
     * \brief get extra info for current cuda status, to be appended in
     *      error message
     */
    static std::string get_cuda_extra_info();
    CudaError(const std::string& msg);
140 141
};

142 143 144 145 146
class EnFlameError final : public SystemError {
public:
    EnFlameError(const std::string& msg);
};

147 148 149 150 151 152
class AtlasError final: public SystemError {
public:
    AtlasError(const std::string& msg);
};


153 154 155 156 157 158 159 160 161 162 163
class ROCmError final : public SystemError {
public:
    /*!
     * \brief get extra info for current rocm status, to be appended in
     *      error message
     */
    static std::string get_rocm_extra_info();

    ROCmError(const std::string& msg);
};

164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
class CnrtError final : public SystemError {
public:
    /*!
     * \brief get extra info for current cnrt status, to be appended in
     * error message
     */
    static std::string get_cnrt_extra_info();

    CnrtError(const std::string& msg);
};

class CndevError final : public SystemError {
public:
    CndevError(const std::string& msg);
};

class CnmlError final : public SystemError {
public:
    CnmlError(const std::string& msg);
};
184

185 186 187
class AssertionError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
188 189 190
};

//! datatype conversion error
191 192 193
class ConversionError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
194 195
};

196 197 198
class TensorCopyOverlapError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
199 200
};

201 202 203
class TensorReshapeError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
204 205
};

206 207 208
class SerializationError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
209 210
};

211 212 213
class MegDNNError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
214 215 216
};

//! megbrain internal error; should be treated as a bug
217 218 219
class InternalError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
220 221
};

222 223 224
class TimeoutError final : public MegBrainError {
public:
    using MegBrainError::MegBrainError;
225 226
};

227 228 229 230 231

}  // namespace mgb

namespace mgb {

232 233
bool has_uncaught_exception();

234 235
}  // namespace mgb

236 237

// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}