Blame view

src/doc/error.dox 5.66 KB
8dcb6dfcb   Yannick Estève   first commit
1
2
3
4
5
6
7
8
9
10
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  // doc/error.dox
  
  
  // Copyright 2009-2011 Microsoft Corporation
  
  // See ../../COPYING for clarification regarding multiple authors
  //
  // Licensed 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
  
  // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  // MERCHANTABLITY OR NON-INFRINGEMENT.
  // See the Apache 2 License for the specific language governing permissions and
  // limitations under the License.
  
  namespace kaldi {
  /** \page error Kaldi logging and error-reporting
  
    \section error_overview Overview
  
    All output that consists of logging messages, warnings or errors is
    directed to the standard error in Kaldi programs.  This is so that our
    programs can be used in of pipes without such messages becoming
    "mixed up" with the program's output.  The most common way to produce logging,
    warning or error output is through the macros KALDI_LOG, KALDI_WARN and
    KALDI_ERR.  Invoking the KALDI_ERR macro will normally terminate the program
    (unless the exception is caught).  An example code fragment that illustrates
    all three of these is as follows:
    \code
  
    KALDI_LOG << "On iteration " << iter
              << ", objective function change was " << delta;
    if (delta < 0.0) {
      KALDI_WARN << "Negative objf change " << delta;
      if (delta < -0.1) 
        KALDI_ERR << "Convergence failure in EM";
    }
    \endcode
    Notice that these examples don't include a newline character (this gets added
    automatically).  A typical example of the messages that get produced by this is:
   \verbatim
    WARNING (copy-feats:Next():util/kaldi-table-inl.h:381) Invalid archive file format
  \endverbatim
    For log messages that are not quite important enough (or are too verbose) to appear in
   normal logs, you can use KALDI_VLOG: for example,
   \code
    KALDI_VLOG(2) << "This message is not important enough to use KALDI_LOG for.";
   \endcode
   This will get printed if the argument to the \c --verbose option is greater than
   or equal to the number in parentheses, e.g. the message above would get printed
   if the user called a program with \c --verbose=2 or greater.  See \ref parse_options_implicit
   for more context on this.
  
   Some parts of the code print logging messages to the standard error directly; this
   is discouraged.
  
   \section error_assertions Assertions in Kaldi
  
   Assertions should ideally be done using the macro KALDI_ASSERT.  This prints more informative
   output than a normal assertion using assert(); KALDI_ASSERT prints a stack trace.  
   KALDI_ASSERT is also more reconfigurable.
  
   A typical assertion is: 
  \code
   KALDI_ASSERT(i < M.NumRows());
  \endcode
   A trick that we sometimes to get more informative assert-failure message is
   to follow the assert condition with "&& [some string]", for example:
  \code
   KALDI_ASSERT(ApproxEqual(delta, objf_change) && "Probable coding error in optimization");
  \endcode
  
   If compiled normally asserts will get checked, but not if compiled with NDEBUG defined.
   For inner-loop assertions that use a lot of CPU,
   we use the following pattern:
  \code
  #ifdef KALDI_PARANOID
    KALDI_ASSERT(i>=0);
  #endif
  \endcode
   The macro KALDI_PARANOID is on by default in the current build setup.  
    
   \section error_exceptions Exceptions thrown by KALDI_ERR
  
   When the KALDI_ERR macro is invoked, it prints
   the error message to the standard error, and then  throws an exception of type std::runtime_error. 
   The string held by this exception contains the error message, and also a stack trace 
   (if supported by the OS).  The normal behavior of current Kaldi programs is to catch the exception
   in a try...catch block in main(), which prints the exception's string to the standard error, and exits.
   This typically results in the error message being printed twice. 
  
   In some cases, the error message will be caught by Kaldi code and not re-thrown.
   This occurs in Holder code (see \ref io_sec_holders) that is called by
   Table code (see \ref io_sec_tables).  Here, exceptions thrown by Read
   functions of Kaldi objects are caught and get propagated to the Table code as
   a boolean return value (e.g. see KaldiObjectHolder::Read() ).  Depending
   on the \ref io_sec_rspecifiers "options", such as the "p" (permissive) option to the Table code,
   and depending how the Table code is called, this may or may not result in another 
   exception.
  
   The only other type of error other than std::runtime_error that should get
   thrown in Kaldi code under normal circumstances is probably std::alloc_error.  
  
   Some parts of Kaldi code currently throw std::runtime_error directly, or call assert() directly,
   but this is to be changed to the more standard KALDI_ERR and KALDI_ASSERT macros.
  
   \section error_compile_time_assertions Compile-time assertions in Kaldi
  
   It is also possible to make assertions that are checked at compile time (they
   will produce a compilation error if they fail).  This is enabled by some macros
   defined in kaldi-utils.h.  It is especially useful to make sure that templates
   have been instantiated with the right kind of types.  Examples of compile-time
   assertions are:
  \code
    KALDI_COMPILE_TIME_ASSERT(kSomeConstant < 0);
    ...
    template<class T> class foo {
       foo() { KALDI_ASSERT_IS_INTEGER_TYPE(T);
    };
    ...
    template<class T> class bar {
       bar() { KALDI_ASSERT_IS_FLOATING_TYPE(T);
    }
  \endcode
  
  
  
  */
  
  /**
   \defgroup error_group "Functions relating to logging and error reporting"
  
   See \ref error_overview for an overview of how logging and errors are handled in Kaldi.
  
  */
  }