• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_CORE_LIB_CORE_STATUS_H_
17 #define TENSORFLOW_CORE_LIB_CORE_STATUS_H_
18 
19 #include <functional>
20 #include <iosfwd>
21 #include <memory>
22 #include <string>
23 #include "tensorflow/core/lib/core/error_codes.pb.h"
24 #include "tensorflow/core/lib/core/stringpiece.h"
25 #include "tensorflow/core/platform/logging.h"
26 #include "tensorflow/core/platform/macros.h"
27 
28 namespace tensorflow {
29 
30 #if defined(__clang__)
31 // Only clang supports warn_unused_result as a type annotation.
32 class TF_MUST_USE_RESULT Status;
33 #endif
34 
35 /// @ingroup core
36 /// Denotes success or failure of a call in Tensorflow.
37 class Status {
38  public:
39   /// Create a success status.
Status()40   Status() {}
41 
42   /// \brief Create a status with the specified error code and msg as a
43   /// human-readable string containing more detailed information.
44   Status(tensorflow::error::Code code, tensorflow::StringPiece msg);
45 
46   /// Copy the specified status.
47   Status(const Status& s);
48   void operator=(const Status& s);
49 
OK()50   static Status OK() { return Status(); }
51 
52   /// Returns true iff the status indicates success.
ok()53   bool ok() const { return (state_ == NULL); }
54 
code()55   tensorflow::error::Code code() const {
56     return ok() ? tensorflow::error::OK : state_->code;
57   }
58 
error_message()59   const string& error_message() const {
60     return ok() ? empty_string() : state_->msg;
61   }
62 
63   bool operator==(const Status& x) const;
64   bool operator!=(const Status& x) const;
65 
66   /// \brief If `ok()`, stores `new_status` into `*this`.  If `!ok()`,
67   /// preserves the current status, but may augment with additional
68   /// information about `new_status`.
69   ///
70   /// Convenient way of keeping track of the first error encountered.
71   /// Instead of:
72   ///   `if (overall_status.ok()) overall_status = new_status`
73   /// Use:
74   ///   `overall_status.Update(new_status);`
75   void Update(const Status& new_status);
76 
77   /// \brief Return a string representation of this status suitable for
78   /// printing. Returns the string `"OK"` for success.
79   string ToString() const;
80 
81   // Ignores any errors. This method does nothing except potentially suppress
82   // complaints from any tools that are checking that errors are not dropped on
83   // the floor.
84   void IgnoreError() const;
85 
86  private:
87   static const string& empty_string();
88   struct State {
89     tensorflow::error::Code code;
90     string msg;
91   };
92   // OK status has a `NULL` state_.  Otherwise, `state_` points to
93   // a `State` structure containing the error code and message(s)
94   std::unique_ptr<State> state_;
95 
96   void SlowCopyFrom(const State* src);
97 };
98 
Status(const Status & s)99 inline Status::Status(const Status& s)
100     : state_((s.state_ == NULL) ? NULL : new State(*s.state_)) {}
101 
102 inline void Status::operator=(const Status& s) {
103   // The following condition catches both aliasing (when this == &s),
104   // and the common case where both s and *this are ok.
105   if (state_ != s.state_) {
106     SlowCopyFrom(s.state_.get());
107   }
108 }
109 
110 inline bool Status::operator==(const Status& x) const {
111   return (this->state_ == x.state_) || (ToString() == x.ToString());
112 }
113 
114 inline bool Status::operator!=(const Status& x) const { return !(*this == x); }
115 
116 /// @ingroup core
117 std::ostream& operator<<(std::ostream& os, const Status& x);
118 
119 typedef std::function<void(const Status&)> StatusCallback;
120 
121 extern tensorflow::string* TfCheckOpHelperOutOfLine(
122     const ::tensorflow::Status& v, const char* msg);
123 
TfCheckOpHelper(::tensorflow::Status v,const char * msg)124 inline tensorflow::string* TfCheckOpHelper(::tensorflow::Status v,
125                                            const char* msg) {
126   if (v.ok()) return nullptr;
127   return TfCheckOpHelperOutOfLine(v, msg);
128 }
129 
130 #define TF_DO_CHECK_OK(val, level)                                \
131   while (auto _result = ::tensorflow::TfCheckOpHelper(val, #val)) \
132   LOG(level) << *(_result)
133 
134 #define TF_CHECK_OK(val) TF_DO_CHECK_OK(val, FATAL)
135 #define TF_QCHECK_OK(val) TF_DO_CHECK_OK(val, QFATAL)
136 
137 // DEBUG only version of TF_CHECK_OK.  Compiler still parses 'val' even in opt
138 // mode.
139 #ifndef NDEBUG
140 #define TF_DCHECK_OK(val) TF_CHECK_OK(val)
141 #else
142 #define TF_DCHECK_OK(val) \
143   while (false && (::tensorflow::Status::OK() == (val))) LOG(FATAL)
144 #endif
145 
146 }  // namespace tensorflow
147 
148 #endif  // TENSORFLOW_CORE_LIB_CORE_STATUS_H_
149