From 302d232047deb53b4c825260aa1d0a8ddde49d80 Mon Sep 17 00:00:00 2001 From: kkm Date: Thu, 28 Feb 2019 20:07:38 -0800 Subject: [PATCH 1/2] [src] Rework error logging for safety and cleanliness * Do not throw exceptions from the destructor in the logging code. * Voidify the value of logging constructs. * Add `class KaldiFatalError : public std::runtime_error`, and throw it from KALDI_ERROR instead of the unspecific`std::runtime_error`. * Remove all uses of `std::endl` from logging code, and disallow it for the future (won't compile). * Improve the handling of decode failures in stack tracing code. * Clean-up obsolete commentary. * Hide global `g_program_name` into kaldi-error.cc unit scope. --- src/base/kaldi-error-test.cc | 7 +- src/base/kaldi-error.cc | 256 +++++++++++---------------- src/base/kaldi-error.h | 186 ++++++++++--------- src/bin/align-text.cc | 32 ++-- src/bin/draw-tree.cc | 12 +- src/feat/pitch-functions-test.cc | 4 +- src/ivector/logistic-regression.cc | 9 +- src/kwsbin/compute-atwv.cc | 5 +- src/latbin/lattice-expand-ngram.cc | 18 +- src/lm/arpa-file-parser.cc | 2 +- src/nnetbin/cuda-gpu-available.cc | 8 +- src/onlinebin/online-audio-client.cc | 27 +-- src/tree/cluster-utils-test.cc | 13 +- src/util/parse-options.cc | 9 +- 14 files changed, 274 insertions(+), 314 deletions(-) diff --git a/src/base/kaldi-error-test.cc b/src/base/kaldi-error-test.cc index 527de852cac..462ad956907 100644 --- a/src/base/kaldi-error-test.cc +++ b/src/base/kaldi-error-test.cc @@ -42,13 +42,12 @@ void UnitTestError() { } // end namespace kaldi. int main() { - kaldi::g_program_name = "/foo/bar/kaldi-error-test"; + kaldi::SetProgramName("/foo/bar/kaldi-error-test"); try { kaldi::UnitTestError(); KALDI_ASSERT(0); // should not happen. exit(1); - } catch(std::runtime_error &r) { - std::cout << "UnitTestError: the error we generated was: " << r.what(); + } catch(kaldi::KaldiFatalError &e) { + std::cout << "The error we generated was: '" << e.KaldiMessage() << "'\n"; } } - diff --git a/src/base/kaldi-error.cc b/src/base/kaldi-error.cc index df03e85f148..9705936466c 100644 --- a/src/base/kaldi-error.cc +++ b/src/base/kaldi-error.cc @@ -1,5 +1,6 @@ // base/kaldi-error.cc +// Copyright 2019 SmartAction LLC (kkm) // Copyright 2016 Brno University of Technology (author: Karel Vesely) // Copyright 2009-2011 Microsoft Corporation; Lukas Burget; Ondrej Glembek @@ -35,88 +36,90 @@ namespace kaldi { + /***** GLOBAL VARIABLES FOR LOGGING *****/ int32 g_kaldi_verbose_level = 0; -const char *g_program_name = NULL; -static LogHandler g_log_handler = NULL; - -// If the program name was set (g_program_name != ""), GetProgramName -// returns the program name (without the path), e.g. "gmm-align". -// Otherwise it returns the empty string "". -const char *GetProgramName() { - return g_program_name == NULL ? "" : g_program_name; +static std::string program_name; +static LogHandler log_handler = NULL; + +void SetProgramName(const char *basename) { + // Using the 'static std::string' for the program name is mostly harmless, + // because (a) Kaldi logging is undefined before main(), and (b) no stdc++ + // string implementation has been found in the wild that would not be just + // an empty string when zero-initialized but not yet constructed. + program_name = basename; } + /***** HELPER FUNCTIONS *****/ -// Given a filename like "/a/b/c/d/e/f.cc", GetShortFileName -// returns "e/f.cc". Does not currently work if backslash is -// the filename separator. -static const char *GetShortFileName(const char *filename) { - const char *last_slash = strrchr(filename, '/'); - if (!last_slash) { - return filename; - } else { - while (last_slash > filename && last_slash[-1] != '/') - last_slash--; - return last_slash; +// Trim filename to at most 1 trailing directory long. Given a filename like +// "/a/b/c/d/e/f.cc", return "e/f.cc". Support both '/' and '\' as the path +// separator. +static const char *GetShortFileName(const char *path) { + if (path == nullptr) + return ""; + + const char *prev = path, *last = path; + while ((path = std::strpbrk(path, "\\/")) != nullptr) { + ++path; + prev = last; + last = path; } + return prev; } -/***** STACKTRACE *****/ +/***** STACK TRACE *****/ +#ifdef HAVE_EXECINFO_H static std::string Demangle(std::string trace_name) { -#if defined(HAVE_CXXABI_H) && defined(HAVE_EXECINFO_H) - // at input the string looks like: +#ifdef HAVE_CXXABI_H + // At input the string looks like: // ./kaldi-error-test(_ZN5kaldi13UnitTestErrorEv+0xb) [0x804965d] - // We want to extract the name e.g. '_ZN5kaldi13UnitTestErrorEv", - // demangle it and return it. + // We want to extract the name e.g. '_ZN5kaldi13UnitTestErrorEv" + // and demangle it. - // try to locate '(' and '+', take the string in between, + // Try to locate '(' and '+', take the string in between. size_t begin(trace_name.find("(")), end(trace_name.rfind("+")); if (begin != std::string::npos && end != std::string::npos && begin < end) { - trace_name = trace_name.substr(begin+1,end-(begin+1)); + trace_name = trace_name.substr(begin + 1, end - (begin + 1)); } - // demangle, + // Try to demangle function name. int status; char *demangled_name = abi::__cxa_demangle(trace_name.c_str(), 0, 0, &status); - std::string ans; - if (status == 0) { - ans = demangled_name; + if (status == 0 && demangled_name != NULL) { + trace_name = demangled_name; free(demangled_name); - } else { - ans = trace_name; } - // return, - return ans; -#else +#endif // HAVE_CXXABI_H return trace_name; -#endif } - +#endif // HAVE_EXECINFO_H static std::string KaldiGetStackTrace() { std::string ans; #ifdef HAVE_EXECINFO_H -#define KALDI_MAX_TRACE_SIZE 50 -#define KALDI_MAX_TRACE_PRINT 20 // must be even. - // buffer for the trace, + const size_t KALDI_MAX_TRACE_SIZE = 50; + const size_t KALDI_MAX_TRACE_PRINT = 20; // Must be even. + // Buffer for the trace. void *trace[KALDI_MAX_TRACE_SIZE]; - // get the trace, + // Get the trace. size_t size = backtrace(trace, KALDI_MAX_TRACE_SIZE); - // get the trace symbols, + // Get the trace symbols. char **trace_symbol = backtrace_symbols(trace, size); + if (trace_symbol == NULL) + return ans; - // Compose the 'string', + // Compose a human-readable backtrace string. ans += "[ Stack-Trace: ]\n"; if (size <= KALDI_MAX_TRACE_PRINT) { for (size_t i = 0; i < size; i++) { ans += Demangle(trace_symbol[i]) + "\n"; } - } else { // print out first+last (e.g.) 5. + } else { // Print out first+last (e.g.) 5. for (size_t i = 0; i < KALDI_MAX_TRACE_PRINT/2; i++) { ans += Demangle(trace_symbol[i]) + "\n"; } @@ -125,11 +128,12 @@ static std::string KaldiGetStackTrace() { ans += Demangle(trace_symbol[i]) + "\n"; } if (size == KALDI_MAX_TRACE_SIZE) - ans += ".\n.\n.\n"; // stack was too long, probably a bug. + ans += ".\n.\n.\n"; // Stack was too long, probably a bug. } - // cleanup, - free(trace_symbol); // it's okay, just the pointers, not the strings. + // We must free the array of pointers allocated by backtrace_symbols(), + // but not the strings themselves. + free(trace_symbol); #endif // HAVE_EXECINFO_H return ans; } @@ -142,118 +146,55 @@ MessageLogger::MessageLogger(LogMessageEnvelope::Severity severity, // Obviously, we assume the strings survive the destruction of this object. envelope_.severity = severity; envelope_.func = func; - envelope_.file = GetShortFileName(file); // Pointer inside 'file'. + envelope_.file = GetShortFileName(file); // Points inside 'file'. envelope_.line = line; } +void MessageLogger::LogMessage() const { + // Send to the logging handler if provided. + if (log_handler != NULL) { + log_handler(envelope_, GetMessage().c_str()); + return; + } -MessageLogger::~MessageLogger() noexcept(false) { - std::string str = GetMessage(); - // print the mesage (or send to logging handler), - MessageLogger::HandleMessage(envelope_, str.c_str()); -} - -std::string MessageLogger::GetMessage() const { - // remove trailing '\n', - std::string str = ss_.str(); - while (!str.empty() && str[str.length() - 1] == '\n') - str.resize(str.length() - 1); - return str; -} - - -void MessageLogger::HandleMessage(const LogMessageEnvelope &envelope, - const char *message) { - // Send to a logging handler if provided. - if (g_log_handler != NULL) { - g_log_handler(envelope, message); + // Otherwise, use the default Kaldi logging. + // Build the log-message header. + std::stringstream full_message; + if (envelope_.severity > LogMessageEnvelope::kInfo) { + full_message << "VLOG[" << envelope_.severity << "] ("; } else { - // Otherwise, we use the default Kaldi logging. - // Build the log-message 'header', - std::stringstream header; - if (envelope.severity > LogMessageEnvelope::kInfo) { - header << "VLOG[" << envelope.severity << "] ("; - } else { - switch (envelope.severity) { - case LogMessageEnvelope::kInfo : - header << "LOG ("; - break; - case LogMessageEnvelope::kWarning : - header << "WARNING ("; - break; - case LogMessageEnvelope::kError : - header << "ERROR ("; - break; - case LogMessageEnvelope::kAssertFailed : - header << "ASSERTION_FAILED ("; - break; - default: - abort(); // coding error (unknown 'severity'), - } + switch (envelope_.severity) { + case LogMessageEnvelope::kInfo : + full_message << "LOG ("; + break; + case LogMessageEnvelope::kWarning : + full_message << "WARNING ("; + break; + case LogMessageEnvelope::kAssertFailed : + full_message << "ASSERTION_FAILED ("; + break; + case LogMessageEnvelope::kError : + default: // If not the ERROR, it still an error! + full_message << "ERROR ("; + break; } - // fill the other info from the envelope, - header << GetProgramName() << "[" KALDI_VERSION "]" << ':' - << envelope.func << "():" << envelope.file << ':' << envelope.line - << ")"; - - // Printing the message, - if (envelope.severity >= LogMessageEnvelope::kWarning) { - // VLOG, LOG, WARNING: - fprintf(stderr, "%s %s\n", header.str().c_str(), message); - } else { - // ERROR, ASSERT_FAILED (print with stack-trace): - fprintf(stderr, "%s %s\n\n%s\n", header.str().c_str(), message, - KaldiGetStackTrace().c_str()); + } + // Add other info from the envelope and the message text. + full_message << program_name.c_str() << "[" KALDI_VERSION "]" << ':' + << envelope_.func << "():" << envelope_.file << ':' + << envelope_.line << ") " << GetMessage().c_str(); + + // Add stack trace for errors and assertion failures, if available. + if (envelope_.severity < LogMessageEnvelope::kWarning) { + const std::string& stack_trace = KaldiGetStackTrace(); + if (!stack_trace.empty()) { + full_message << "\n\n" << stack_trace; } } -} -FatalMessageLogger::FatalMessageLogger(LogMessageEnvelope::Severity severity, - const char *func, const char *file, - int32 line): - MessageLogger(severity, func, file, line) { - if (severity != LogMessageEnvelope::kAssertFailed && - severity != LogMessageEnvelope::kError) { - // Don't use KALDI_ERR, since that will recursively instantiate - // MessageLogger. - throw std::runtime_error("FatalMessageLogger should be called only with " - "severities kAssertFailed and kError"); - } -} -#if defined(_MSC_VER) -FatalMessageLogger::~FatalMessageLogger [[ noreturn ]] () noexcept(false) -#else -[[ noreturn ]] FatalMessageLogger::~FatalMessageLogger() noexcept(false) -#endif -{ - std::string str = GetMessage(); - - // print the mesage (or send to logging handler), - MessageLogger::HandleMessage(envelope_, str.c_str()); - - // Should we throw exception, or abort? - switch (envelope_.severity) { - case LogMessageEnvelope::kAssertFailed: - abort(); // ASSERT_FAILED, - break; - case LogMessageEnvelope::kError: - if (!std::uncaught_exception()) { - // throw exception with empty message, - throw std::runtime_error(""); // KALDI_ERR, - } else { - // If we got here, this thread has already thrown exception, - // and this exception has not yet arrived to its 'catch' clause... - // Throwing a new exception would be unsafe! - // (can happen during 'stack unwinding', if we have 'KALDI_ERR << msg' - // in a destructor of some local object). - abort(); - } - break; - default: // This should never happen, based on constructor's - // preconditions. But we place abort() here so that all - // possible pathways through this function do not return. - abort(); - } + // Print the complete message to stderr. + full_message << "\n"; + std::cerr << full_message.str(); } @@ -261,17 +202,20 @@ FatalMessageLogger::~FatalMessageLogger [[ noreturn ]] () noexcept(false) void KaldiAssertFailure_(const char *func, const char *file, int32 line, const char *cond_str) { - FatalMessageLogger ml(LogMessageEnvelope::kAssertFailed, func, file, line); - ml.stream() << ": '" << cond_str << "' "; + MessageLogger::Log() = + MessageLogger (LogMessageEnvelope::kAssertFailed, func, file, line) + << "Assertion failed: (" << cond_str << ")"; + fflush(NULL); // Flush all pending buffers, abort() may not flush stderr. + std::abort(); } /***** THIRD-PARTY LOG-HANDLER *****/ -LogHandler SetLogHandler(LogHandler new_handler) { - LogHandler old_handler = g_log_handler; - g_log_handler = new_handler; +LogHandler SetLogHandler(LogHandler handler) { + LogHandler old_handler = log_handler; + log_handler = handler; return old_handler; } -} // end namespace kaldi +} // namespace kaldi diff --git a/src/base/kaldi-error.h b/src/base/kaldi-error.h index c643902f01b..c90a18b15f1 100644 --- a/src/base/kaldi-error.h +++ b/src/base/kaldi-error.h @@ -1,5 +1,6 @@ // base/kaldi-error.h +// Copyright 2019 SmartAction LLC (kkm) // Copyright 2016 Brno University of Technology (author: Karel Vesely) // Copyright 2009-2011 Microsoft Corporation; Ondrej Glembek; Lukas Burget; // Saarland University @@ -42,22 +43,23 @@ namespace kaldi { /// \addtogroup error_group /// @{ -/***** VERBOSITY LEVEL *****/ +/***** PROGRAM NAME AND VERBOSITY LEVEL *****/ -/// This is set by util/parse-options.{h, cc} if you set --verbose=? option. -extern int32 g_kaldi_verbose_level; +/// Called by ParseOptions to set base name (no directory) of the executing +/// program. The name is printed in logging code along with every message, +/// because in our scripts, we often mix together the stderr of many programs. +/// This function is very thread-unsafe. +void SetProgramName(const char *basename); -/// This is set by util/parse-options.{h, cc} (from argv[0]) and used (if set) -/// in error reporting code to display the name of the program (this is because -/// in our scripts, we often mix together the stderr of many programs). it is -/// the base-name of the program (no directory), followed by ':' We don't use -/// std::string, due to the static initialization order fiasco. -extern const char *g_program_name; +/// This is set by util/parse-options.{h,cc} if you set --verbose=? option. +/// Do not use directly, prefer {Get,Set}VerboseLevel(). +extern int32 g_kaldi_verbose_level; +/// Get verbosity level, usually set via command line '--verbose=' switch. inline int32 GetVerboseLevel() { return g_kaldi_verbose_level; } -/// This should be rarely used; command-line programs set the verbose level -/// automatically from ParseOptions. +/// This should be rarely used, except by programs using Kaldi as library; +/// command-line programs set the verbose level automatically from ParseOptions. inline void SetVerboseLevel(int32 i) { g_kaldi_verbose_level = i; } @@ -65,76 +67,106 @@ inline void SetVerboseLevel(int32 i) { g_kaldi_verbose_level = i; } /// Log message severity and source location info. struct LogMessageEnvelope { + /// Message severity. In addition to these levels, positive values (1 to 6) + /// specify verbose logging level. Verbose messages are produced only when + /// SetVerboseLevel() has been called to set logging level to at least the + /// corresponding value. enum Severity { - kAssertFailed = -3, - kError = -2, - kWarning = -1, - kInfo = 0, + kAssertFailed = -3, //!< Assertion failure. abort() will be called. + kError = -2, //!< Fatal error. KaldiFatalError will be thrown. + kWarning = -1, //!< Indicates a recoverable but abnormal condition. + kInfo = 0, //!< Informational message. }; - // An 'enum Severity' value, or a positive number indicating verbosity level. - int severity; - const char *func; - const char *file; - int32 line; + int severity; //!< A Severity value, or positive verbosity level. + const char *func; //!< Name of the function invoking the logging. + const char *file; //!< Source file name with up to 1 leading directory. + int32 line; // + MessageLogger &operator<<(const T &val) { + ss_ << val; + return *this; + } + + // When assigned a MessageLogger, log its contents. + struct Log final { + void operator=(const MessageLogger& logger) { + logger.LogMessage(); + } + }; - /// The hook for the 'insertion operator', e.g. - /// 'KALDI_LOG << "Message,"', - inline std::ostream &stream() { return ss_; } + // When assigned a MessageLogger, log its contents and then throw + // a KaldiFatalError. + struct LogAndThrow final { + [[ noreturn ]] void operator=(const MessageLogger& logger) { + logger.LogMessage(); + throw KaldiFatalError(logger.GetMessage()); + } + }; -protected: - std::string GetMessage() const; - /// The logging function, - static void HandleMessage(const LogMessageEnvelope &env, const char *msg); +private: + std::string GetMessage() const { return ss_.str(); } + void LogMessage() const; -protected: LogMessageEnvelope envelope_; - -private: std::ostringstream ss_; }; -class FatalMessageLogger: public MessageLogger { -public: - FatalMessageLogger(LogMessageEnvelope::Severity severity, - const char *func, const char *file, int32 line); - - [[ noreturn ]] ~FatalMessageLogger() noexcept(false); -}; - -// The definition of the logging macros, +// Logging macros. #define KALDI_ERR \ - ::kaldi::FatalMessageLogger(::kaldi::LogMessageEnvelope::kError, \ - __func__, __FILE__, __LINE__).stream() + ::kaldi::MessageLogger::LogAndThrow() = \ + ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kError, \ + __func__, __FILE__, __LINE__) #define KALDI_WARN \ - ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kWarning, \ - __func__, __FILE__, __LINE__).stream() + ::kaldi::MessageLogger::Log() = \ + ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kWarning, \ + __func__, __FILE__, __LINE__) #define KALDI_LOG \ - ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kInfo, \ - __func__, __FILE__, __LINE__).stream() -#define KALDI_VLOG(v) if ((v) <= ::kaldi::g_kaldi_verbose_level) \ - ::kaldi::MessageLogger((::kaldi::LogMessageEnvelope::Severity)(v), \ - __func__, __FILE__, __LINE__).stream() + ::kaldi::MessageLogger::Log() = \ + ::kaldi::MessageLogger(::kaldi::LogMessageEnvelope::kInfo, \ + __func__, __FILE__, __LINE__) +#define KALDI_VLOG(v) \ + if ((v) <= ::kaldi::GetVerboseLevel()) \ + ::kaldi::MessageLogger::Log() = \ + ::kaldi::MessageLogger((::kaldi::LogMessageEnvelope::Severity)(v), \ + __func__, __FILE__, __LINE__) /***** KALDI ASSERTS *****/ @@ -142,17 +174,8 @@ class FatalMessageLogger: public MessageLogger { [[ noreturn ]] void KaldiAssertFailure_(const char *func, const char *file, int32 line, const char *cond_str); -// Note on KALDI_ASSERT and KALDI_PARANOID_ASSERT -// The original (simple) version of the code was this -// -// #define KALDI_ASSERT(cond) if (!(cond)) -// kaldi::KaldiAssertFailure_(__func__, __FILE__, __LINE__, #cond); +// Note on KALDI_ASSERT and KALDI_PARANOID_ASSERT: // -// That worked well, but we were concerned that it -// could potentially cause a performance issue due to failed branch -// prediction (best practice is to have the if branch be the commonly -// taken one). -// Therefore, we decided to move the call into the else{} branch. // A single block {} around if /else does not work, because it causes // syntax error (unmatched else block) in the following code: // @@ -161,19 +184,21 @@ class FatalMessageLogger: public MessageLogger { // else // SomethingElse(); // -// do {} while(0) -- note there is no semicolon at the end! --- works nicely +// do {} while(0) -- note there is no semicolon at the end! -- works nicely, // and compilers will be able to optimize the loop away (as the condition // is always false). +// +// Also see KALDI_COMPILE_TIME_ASSERT, defined in base/kaldi-utils.h, and +// KALDI_ASSERT_IS_INTEGER_TYPE and KALDI_ASSERT_IS_FLOATING_TYPE, also defined +// there. #ifndef NDEBUG #define KALDI_ASSERT(cond) do { if (cond) (void)0; else \ ::kaldi::KaldiAssertFailure_(__func__, __FILE__, __LINE__, #cond); } while(0) #else #define KALDI_ASSERT(cond) (void)0 #endif -// Also see KALDI_COMPILE_TIME_ASSERT, defined in base/kaldi-utils.h, -// and KALDI_ASSERT_IS_INTEGER_TYPE and KALDI_ASSERT_IS_FLOATING_TYPE, -// also defined there. -// some more expensive asserts only checked if this defined + +// Some more expensive asserts only checked if this defined. #ifdef KALDI_PARANOID #define KALDI_PARANOID_ASSERT(cond) do { if (cond) (void)0; else \ ::kaldi::KaldiAssertFailure_(__func__, __FILE__, __LINE__, #cond); } while(0) @@ -184,14 +209,15 @@ class FatalMessageLogger: public MessageLogger { /***** THIRD-PARTY LOG-HANDLER *****/ -/// Type of third-party logging function, +/// Type of third-party logging function. typedef void (*LogHandler)(const LogMessageEnvelope &envelope, const char *message); /// Set logging handler. If called with a non-NULL function pointer, the -/// function pointed by it is called to send messages to a caller-provided -/// log. If called with NULL pointer, restores default Kaldi error logging to -/// stderr. SetLogHandler is obviously not thread safe. +/// function pointed by it is called to send messages to a caller-provided log. +/// If called with a NULL pointer, restores default Kaldi error logging to +/// stderr. This function is obviously not thread safe; the log handler must be. +/// Returns a previously set logging handler pointer, or NULL. LogHandler SetLogHandler(LogHandler); /// @} end "addtogroup error_group" diff --git a/src/bin/align-text.cc b/src/bin/align-text.cc index 616dac858d7..1c695675274 100644 --- a/src/bin/align-text.cc +++ b/src/bin/align-text.cc @@ -86,28 +86,34 @@ int main(int argc, char *argv[]) { if (!text2_reader.HasKey(key)) { KALDI_WARN << "Key " << key << " is in " << text1_rspecifier - << ", but not in " << text2_rspecifier; + << ", but not in " << text2_rspecifier; n_fail++; continue; } const std::vector &text1 = text1_reader.Value(); const std::vector &text2 = text2_reader.Value(key); - // Checks if the special symbol is in the string. - KALDI_ASSERT(std::find(text1.begin(), - text1.end(), special_symbol) == text1.end()); - KALDI_ASSERT(std::find(text2.begin(), - text2.end(), special_symbol) == text2.end()); - if (std::find_if(text1.begin(), text1.end(), IsNotToken) != text1.end()) { - KALDI_ERR << "In text1, the utterance " << key << " contains unprintable characters." \ - << "That means there is a problem with the text (such as incorrect encoding)." << std::endl; - return -1; + KALDI_ERR << "In text1, the utterance " << key + << " contains unprintable characters. That means there is" + << " a problem with the text (such as incorrect encoding)."; } if (std::find_if(text2.begin(), text2.end(), IsNotToken) != text2.end()) { - KALDI_ERR << "In text2, the utterance " << key << " contains unprintable characters." \ - << "That means there is a problem with the text (such as incorrect encoding)." << std::endl; - return -1; + KALDI_ERR << "In text2, the utterance " << key + << " contains unprintable characters. That means there is" + << " a problem with the text (such as incorrect encoding)."; + } + + // Verify that the special symbol is not in the string. + if (std::find(text1.begin(), text1.end(), special_symbol) != text1.end()){ + KALDI_ERR << "In text1, the utterance " << key + << " contains the special symbol '" << special_symbol + << "'. This is not allowed."; + } + if (std::find(text2.begin(), text2.end(), special_symbol) != text2.end()){ + KALDI_ERR << "In text2, the utterance " << key + << " contains the special symbol '" << special_symbol + << "'. This is not allowed."; } std::vector > aligned; diff --git a/src/bin/draw-tree.cc b/src/bin/draw-tree.cc index c9be5586933..d107ab1cfac 100644 --- a/src/bin/draw-tree.cc +++ b/src/bin/draw-tree.cc @@ -34,25 +34,23 @@ void MakeEvent(std::string &qry, fst::SymbolTable *phone_syms, if (key == kPdfClass) { value = static_cast(atoi(valstr.c_str())); if (value < 0) { // not valid pdf-class - KALDI_ERR << "Bad query: invalid pdf-class (" - << valstr << ')' << std::endl << std::endl; + KALDI_ERR << "Bad query: invalid pdf-class (" << valstr << ')'; } } else { value = static_cast(phone_syms->Find(valstr.c_str())); if (value == -1) { // fst::kNoSymbol - KALDI_ERR << "Bad query: invalid symbol (" - << valstr << ')' << std::endl << std::endl; + KALDI_ERR << "Bad query: invalid symbol (" << valstr << ')'; } } query_event->push_back(std::make_pair(key++, value)); old_found = found + 1; } std::string valstr = qry.substr(old_found); - EventValueType value = static_cast(phone_syms->Find(valstr.c_str())); + EventValueType value = + static_cast(phone_syms->Find(valstr.c_str())); if (value == -1) { // fst::kNoSymbol - KALDI_ERR << "Bad query: invalid symbol (" - << valstr << ')' << std::endl << std::endl; + KALDI_ERR << "Bad query: invalid symbol (" << valstr << ')'; } query_event->push_back(std::make_pair(key, value)); diff --git a/src/feat/pitch-functions-test.cc b/src/feat/pitch-functions-test.cc index 098e590a8e9..0e481c18674 100644 --- a/src/feat/pitch-functions-test.cc +++ b/src/feat/pitch-functions-test.cc @@ -449,7 +449,7 @@ static void UnitTestKeeleNccfBallast() { // use pitch code with default configuration.. PitchExtractionOptions op; op.nccf_ballast = 0.05 * k; - KALDI_LOG << " nccf_ballast " << op.nccf_ballast << std::endl; + KALDI_LOG << " nccf_ballast " << op.nccf_ballast; // compute pitch. Matrix m; ComputeKaldiPitch(op, waveform, &m); @@ -493,7 +493,7 @@ static void UnitTestPitchExtractionSpeed() { double tot_time = timer.Elapsed(), speech_time = test_num * waveform.Dim() / wave.SampFreq(); KALDI_LOG << " Pitch extraction time per second of speech is " - << (tot_time / speech_time) << " seconds " << std::endl; + << (tot_time / speech_time) << " seconds."; } } static void UnitTestPitchExtractorCompareKeele() { diff --git a/src/ivector/logistic-regression.cc b/src/ivector/logistic-regression.cc index 5d02c013294..4eae2ebe3d7 100644 --- a/src/ivector/logistic-regression.cc +++ b/src/ivector/logistic-regression.cc @@ -55,8 +55,7 @@ void LogisticRegression::Train(const Matrix &xs, weights_.SetZero(); TrainParameters(xs_with_prior, ys, conf, &xw); - KALDI_LOG << - "Finished training parameters without mixture components." << std::endl; + KALDI_LOG << "Finished training parameters without mixture components."; // If we are using mixture components, we add those components // in MixUp and retrain with the extra weights. @@ -64,8 +63,7 @@ void LogisticRegression::Train(const Matrix &xs, MixUp(ys, num_classes, conf); Matrix xw(xs_num_rows, weights_.NumRows()); TrainParameters(xs_with_prior, ys, conf, &xw); - KALDI_LOG << - "Finished training mixture components." << std::endl; + KALDI_LOG << "Finished training mixture components."; } } @@ -87,8 +85,7 @@ void LogisticRegression::MixUp(const std::vector &ys, static_cast(0)); KALDI_LOG << "Target number mixture components was " << conf.mix_up - << ". Training " << new_dim << " mixture components. " - << std::endl; + << ". Training " << new_dim << " mixture components."; int32 old_dim = weights_.NumRows(), num_components = old_dim, diff --git a/src/kwsbin/compute-atwv.cc b/src/kwsbin/compute-atwv.cc index 6d9f6d2c2bb..0907baf268a 100644 --- a/src/kwsbin/compute-atwv.cc +++ b/src/kwsbin/compute-atwv.cc @@ -112,7 +112,7 @@ int main(int argc, char *argv[]) { if (vals.size() != 4) { KALDI_ERR << "Incorrect format of the reference file" << " -- 4 entries expected, " << vals.size() << " given!\n" - << "Key: " << kwid << std::endl; + << "Key: " << kwid; } KwsTerm inst(kwid, vals); aligner.AddRef(inst); @@ -127,7 +127,7 @@ int main(int argc, char *argv[]) { if (vals.size() != 4) { KALDI_ERR << "Incorrect format of the hypotheses file" << " -- 4 entries expected, " << vals.size() << " given!\n" - << "Key: " << kwid << std::endl; + << "Key: " << kwid; } KwsTerm inst(kwid, vals); aligner.AddHyp(inst); @@ -171,4 +171,3 @@ int main(int argc, char *argv[]) { return -1; } } - diff --git a/src/latbin/lattice-expand-ngram.cc b/src/latbin/lattice-expand-ngram.cc index 1b8cfbee24b..1e7625d79e0 100644 --- a/src/latbin/lattice-expand-ngram.cc +++ b/src/latbin/lattice-expand-ngram.cc @@ -36,15 +36,15 @@ int main(int argc, char *argv[]) { "Usage: lattice-expand-ngram [options] lattice-rspecifier " "lattice-wspecifier\n" "e.g.: lattice-expand-ngram --n=3 ark:lat ark:expanded_lat\n"; - + ParseOptions po(usage); int32 n = 3; std::string word_syms_filename; po.Register("n", &n, "n-gram context to expand to."); - + po.Read(argc, argv); - + if (po.NumArgs() != 2) { po.PrintUsage(); exit(1); @@ -58,10 +58,10 @@ int main(int argc, char *argv[]) { fst::UnweightedNgramFst expand_fst(n); SequentialCompactLatticeReader lat_reader(lats_rspecifier); - CompactLatticeWriter lat_writer(lats_wspecifier); + CompactLatticeWriter lat_writer(lats_wspecifier); int32 n_done = 0, n_fail = 0; - + for (; !lat_reader.Done(); lat_reader.Next()) { std::string key = lat_reader.Key(); KALDI_LOG << "Processing lattice for key " << key; @@ -69,14 +69,14 @@ int main(int argc, char *argv[]) { CompactLattice expanded_lat; ComposeDeterministicOnDemand(lat, &expand_fst, &expanded_lat); if (expanded_lat.Start() == fst::kNoStateId) { - KALDI_WARN << "Empty lattice for utterance " << key << std::endl; + KALDI_WARN << "Empty lattice for utterance " << key; n_fail++; } else { if (lat.NumStates() == expanded_lat.NumStates()) { - KALDI_LOG << "Lattice for key " << key + KALDI_LOG << "Lattice for key " << key << " did not need to be expanded for order " << n << "."; } else { - KALDI_LOG << "Lattice expanded from " << lat.NumStates() << " to " + KALDI_LOG << "Lattice expanded from " << lat.NumStates() << " to " << expanded_lat.NumStates() << " states for order " << n << "."; } lat_writer.Write(key, expanded_lat); @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) { } lat_reader.FreeCurrent(); } - KALDI_LOG << "Processed " << n_done << " lattices with " << n_fail + KALDI_LOG << "Processed " << n_done << " lattices with " << n_fail << " failures."; return 0; } catch(const std::exception &e) { diff --git a/src/lm/arpa-file-parser.cc b/src/lm/arpa-file-parser.cc index f3565eabf4e..53e4a1b61bf 100644 --- a/src/lm/arpa-file-parser.cc +++ b/src/lm/arpa-file-parser.cc @@ -74,7 +74,7 @@ void ArpaFileParser::Read(std::istream &is) { warning_count_ = 0; current_line_.clear(); -#define PARSE_ERR (KALDI_ERR << LineReference() << ": ") +#define PARSE_ERR KALDI_ERR << LineReference() << ": " // Give derived class an opportunity to prepare its state. ReadStarted(); diff --git a/src/nnetbin/cuda-gpu-available.cc b/src/nnetbin/cuda-gpu-available.cc index 390468d3046..41d0227ce08 100644 --- a/src/nnetbin/cuda-gpu-available.cc +++ b/src/nnetbin/cuda-gpu-available.cc @@ -46,8 +46,7 @@ int main(int argc, char *argv[]) try { KALDI_WARN << "Cannot get hostname, " << strerror(errno); } #endif - KALDI_LOG << std::endl << std::endl - << "### IS CUDA GPU AVAILABLE? '" << hostname << "' ###"; + KALDI_LOG << "\n\n### IS CUDA GPU AVAILABLE? '" << hostname << "' ###"; #if HAVE_CUDA == 1 CuDevice::Instantiate().SelectGpuId("yes"); fprintf(stderr, "### HURRAY, WE GOT A CUDA GPU FOR COMPUTATION!!! ##\n\n"); @@ -76,9 +75,9 @@ int main(int argc, char *argv[]) try { return 0; #else std::cerr - << "### CUDA WAS NOT COMPILED IN! ###" << std::endl + << "### CUDA WAS NOT COMPILED IN! ###\n" << "To support CUDA, you must run 'configure' on a machine " - << "that has the CUDA compiler 'nvcc' available."; + << "that has the CUDA compiler 'nvcc' available.\n"; return 1; #endif } catch (const std::exception &e) { @@ -95,4 +94,3 @@ int main(int argc, char *argv[]) try { << "### - You should see your GPU (burnt GPUs may disappear from the list until reboot),"; return -1; } - diff --git a/src/onlinebin/online-audio-client.cc b/src/onlinebin/online-audio-client.cc index 241aee426cc..577204b65e7 100644 --- a/src/onlinebin/online-audio-client.cc +++ b/src/onlinebin/online-audio-client.cc @@ -85,7 +85,7 @@ int main(int argc, char** argv) { int32 client_desc = socket(AF_INET, SOCK_STREAM, 0); if (client_desc == -1) { - std::cerr << "ERROR: couldn't create socket!" << std::endl; + std::cerr << "ERROR: couldn't create socket!\n"; return -1; } @@ -96,8 +96,8 @@ int main(int argc, char** argv) { if (addr == INADDR_NONE) { hp = gethostbyname(server_addr_str.c_str()); if (hp == NULL) { - std::cerr << "ERROR: couldn't resolve host string: " << server_addr_str - << std::endl; + std::cerr << "ERROR: couldn't resolve host string: " + << server_addr_str << '\n'; close(client_desc); return -1; } @@ -110,13 +110,13 @@ int main(int argc, char** argv) { server.sin_family = AF_INET; server.sin_port = htons(server_port); if (::connect(client_desc, (struct sockaddr*) &server, sizeof(server))) { - std::cerr << "ERROR: couldn't connect to server!" << std::endl; + std::cerr << "ERROR: couldn't connect to server!\n"; close(client_desc); return -1; } KALDI_VLOG(2) << "Connected to KALDI server at host " << server_addr_str - << " port " << server_port << std::endl; + << " port " << server_port; char* pack_buffer = new char[packet_size]; @@ -124,7 +124,7 @@ int main(int argc, char** argv) { for (; !reader.Done(); reader.Next()) { std::string wav_key = reader.Key(); - KALDI_VLOG(2) << "File: " << wav_key << std::endl; + KALDI_VLOG(2) << "File: " << wav_key; const WaveData &wav_data = reader.Value(); @@ -257,8 +257,7 @@ int main(int argc, char** argv) { { float speed = total_input_dur / total_reco_dur; - KALDI_VLOG(2) << "Recognized (" << speed << "xRT): " << reco_output - << std::endl; + KALDI_VLOG(2) << "Recognized (" << speed << "xRT): " << reco_output; } if (htk) { @@ -266,7 +265,8 @@ int main(int argc, char** argv) { std::ofstream htk_file(name.c_str()); for (size_t i = 0; i < results.size(); i++) htk_file << (int) (results[i].start * 10000000) << " " - << (int) (results[i].end * 10000000) << " " << results[i].word << std::endl; + << (int) (results[i].end * 10000000) << " " + << results[i].word << "\n"; htk_file.close(); } @@ -309,12 +309,13 @@ int main(int argc, char** argv) { std::string name = wav_key + ".vtt"; std::ofstream vtt_file(name.c_str()); - vtt_file << "WEBVTT FILE" << std::endl << std::endl; + vtt_file << "WEBVTT FILE\n\n"; for (size_t i = 0; i < subtitles.size(); i++) - vtt_file << (i + 1) << std::endl << TimeToTimecode(subtitles[i].start) - << " --> " << TimeToTimecode(subtitles[i].end) << std::endl - << subtitles[i].word << std::endl << std::endl; + vtt_file << (i + 1) << "\n" + << TimeToTimecode(subtitles[i].start) << " --> " + << TimeToTimecode(subtitles[i].end) << "\n" + << subtitles[i].word << "\n\n"; vtt_file.close(); } diff --git a/src/tree/cluster-utils-test.cc b/src/tree/cluster-utils-test.cc index fd5d9690939..8eee3fb5505 100644 --- a/src/tree/cluster-utils-test.cc +++ b/src/tree/cluster-utils-test.cc @@ -97,10 +97,11 @@ static void TestObjfPlus() { AssertEqual(a.Objf(), (BaseFloat)0.0); AssertEqual(b.Objf(), (BaseFloat)0.0); AssertEqual( a.ObjfPlus(b), -0.5 * (1.0-2.5)*(1.0-2.5)); // 0.5 because half-distance, squared = 1/4, times two points... - KALDI_LOG << "Non-binary Output: "<<'\n'; - a.Write(KALDI_LOG, false); - KALDI_LOG << "Binary Output: "<<'\n'; - a.Write(KALDI_LOG, true); + KALDI_LOG << "Non-binary Output:"; + a.Write(std::cerr, false); + std::cerr << "\nBinary Output:\n"; + a.Write(std::cerr, true); + std::cerr << "\n"; } static void TestObjfMinus() { @@ -395,7 +396,7 @@ static void TestClusterKMeansVector() { std::vector points; for (size_t j = 0; j < n_clust; j++) { size_t n_points = 1 + Rand() % 5; - + Vector clust_center(dim); clust_center.SetRandn(); for (size_t k = 0; k < n_points; k++) { @@ -573,5 +574,3 @@ int main() { TestClusterBottomUp(); TestRefineClusters(); } - - diff --git a/src/util/parse-options.cc b/src/util/parse-options.cc index 2f75cb655f9..667d9e91c94 100644 --- a/src/util/parse-options.cc +++ b/src/util/parse-options.cc @@ -323,14 +323,7 @@ int ParseOptions::Read(int argc, const char *const argv[]) { #else const char *c = strrchr(argv[0], '/'); #endif - if (c == NULL) - c = argv[0]; - else - c++; - char *program_name = new char[strlen(c)+1]; - strcpy(program_name, c); - delete [] g_program_name; - g_program_name = program_name; + SetProgramName(c == NULL ? argv[0] : c + 1); } // first pass: look for config parameter, look for priority for (i = 1; i < argc; i++) { From 53522ba81d46b9c486c36eb5b2ad704036e058cb Mon Sep 17 00:00:00 2001 From: kkm Date: Sun, 3 Mar 2019 01:53:08 -0800 Subject: [PATCH 2/2] [src] Do not throw runtime_error where KALDI_ERR should be used * Replace 'throw runtime_error' where KALDI_ERR was intended (everywhere except fsext/, basically). * Catch KaldiFatalError instead of runtime_error in tree/build-tree-utils.cc, and add a sensible message * Document throwing KaldiFatalError where runtime_error was previously mentioned in comments. --- src/base/io-funcs-inl.h | 6 +++--- src/base/io-funcs.cc | 2 +- src/base/io-funcs.h | 2 +- src/base/kaldi-math.cc | 6 ++---- src/lat/determinize-lattice-pruned.cc | 3 +-- src/lm/arpa-lm-compiler-test.cc | 3 +-- src/matrix/tp-matrix.cc | 11 ++++------ src/matrix/tp-matrix.h | 13 ++++++----- src/online/online-audio-source.cc | 8 +++---- src/online/online-audio-source.h | 2 +- src/tree/build-tree-utils.cc | 31 ++++++++++++--------------- src/util/kaldi-table.h | 3 +-- 12 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/base/io-funcs-inl.h b/src/base/io-funcs-inl.h index 6b87f4c1a24..b703ef5addc 100644 --- a/src/base/io-funcs-inl.h +++ b/src/base/io-funcs-inl.h @@ -47,7 +47,7 @@ template void WriteBasicType(std::ostream &os, os << t << " "; } if (os.fail()) { - throw std::runtime_error("Write failure in WriteBasicType."); + KALDI_ERR << "Write failure in WriteBasicType."; } } @@ -122,7 +122,7 @@ inline void WriteIntegerPairVector(std::ostream &os, bool binary, os << "]\n"; } if (os.fail()) { - throw std::runtime_error("Write failure in WriteIntegerPairVector."); + KALDI_ERR << "Write failure in WriteIntegerPairVector."; } } @@ -224,7 +224,7 @@ template inline void WriteIntegerVector(std::ostream &os, bool binary, os << "]\n"; } if (os.fail()) { - throw std::runtime_error("Write failure in WriteIntegerVector."); + KALDI_ERR << "Write failure in WriteIntegerVector."; } } diff --git a/src/base/io-funcs.cc b/src/base/io-funcs.cc index 90988faf3ea..ff9c921874e 100644 --- a/src/base/io-funcs.cc +++ b/src/base/io-funcs.cc @@ -138,7 +138,7 @@ void WriteToken(std::ostream &os, bool binary, const char *token) { CheckToken(token); // make sure it's valid (can be read back) os << token << " "; if (os.fail()) { - throw std::runtime_error("Write failure in WriteToken."); + KALDI_ERR << "Write failure in WriteToken."; } } diff --git a/src/base/io-funcs.h b/src/base/io-funcs.h index 6c2b690f54c..b3015905785 100644 --- a/src/base/io-funcs.h +++ b/src/base/io-funcs.h @@ -46,7 +46,7 @@ namespace kaldi { We also want to have control over whitespace in text mode without affecting the meaning of the file, for pretty-printing purposes. - Errors are handled by throwing an exception (std::runtime_error). + Errors are handled by throwing a KaldiFatalError exception. For integer and floating-point types (and boolean values): diff --git a/src/base/kaldi-math.cc b/src/base/kaldi-math.cc index 991e46a590c..f33c6efad8d 100644 --- a/src/base/kaldi-math.cc +++ b/src/base/kaldi-math.cc @@ -109,10 +109,8 @@ int32 RandInt(int32 min_val, int32 max_val, struct RandomState* state) { return min_val + ( (unsigned int)( (Rand(state)+RAND_MAX*Rand(state))) % (unsigned int)(max_val+1-min_val)); } else { - throw std::runtime_error(std::string() - +"rand_int failed because we do not support " - +"such large random numbers. " - +"(Extend this function)."); + KALDI_ERR << "rand_int failed because we do not support such large " + "random numbers. (Extend this function)."; } } #else diff --git a/src/lat/determinize-lattice-pruned.cc b/src/lat/determinize-lattice-pruned.cc index 447c951d02c..22eae8199ff 100644 --- a/src/lat/determinize-lattice-pruned.cc +++ b/src/lat/determinize-lattice-pruned.cc @@ -665,8 +665,7 @@ template class LatticeDeterminizerPruned { continue; if (opts_.max_loop > 0 && counter++ > opts_.max_loop) { KALDI_ERR << "Lattice determinization aborted since looped more than " - << opts_.max_loop << " times during epsilon closure.\n"; - throw std::runtime_error("looped more than max-arcs times in lattice determinization"); + << opts_.max_loop << " times during epsilon closure."; } for (ArcIterator > aiter(*ifst_, elem.state); !aiter.Done(); aiter.Next()) { const Arc &arc = aiter.Value(); diff --git a/src/lm/arpa-lm-compiler-test.cc b/src/lm/arpa-lm-compiler-test.cc index 697d70c416a..ccfd26af7e5 100644 --- a/src/lm/arpa-lm-compiler-test.cc +++ b/src/lm/arpa-lm-compiler-test.cc @@ -209,8 +209,7 @@ bool ThrowsExceptionTest(bool seps, const string &infile) { // Make memory cleanup easy in both cases of try-catch block. std::unique_ptr compiler(Compile(seps, infile)); return false; - } catch (const std::runtime_error&) { - // Kaldi throws only std::runtime_error in kaldi-error.cc + } catch (const KaldiFatalError&) { return true; } } diff --git a/src/matrix/tp-matrix.cc b/src/matrix/tp-matrix.cc index f01ee1e8f46..6e34dc643e9 100644 --- a/src/matrix/tp-matrix.cc +++ b/src/matrix/tp-matrix.cc @@ -51,7 +51,7 @@ void TpMatrix::Invert() { // format, so we temporarily put in non-packed format. Matrix tmp(*this); int rows = static_cast(this->num_rows_); - + // ATLAS call. It's really row-major ordering and a lower triangular matrix, // but there is some weirdness with Fortran-style indexing that we need to // take account of, so everything gets swapped. @@ -102,14 +102,13 @@ void TpMatrix::Cholesky(const SpMatrix &orig) { } // d = orig(j, j) - d; d = orig_jdata[j] - d; - + if (d >= 0.0) { // (*this)(j, j) = std::sqrt(d); jdata[j] = std::sqrt(d); } else { - KALDI_WARN << "Cholesky decomposition failed. Maybe matrix " - "is not positive definite. Throwing error"; - throw std::runtime_error("Cholesky decomposition failed."); + KALDI_ERR << "Cholesky decomposition failed. Maybe matrix " + "is not positive definite."; } } } @@ -144,5 +143,3 @@ template class TpMatrix; template class TpMatrix; } // namespace kaldi - - diff --git a/src/matrix/tp-matrix.h b/src/matrix/tp-matrix.h index b215e73b000..e3b08701543 100644 --- a/src/matrix/tp-matrix.h +++ b/src/matrix/tp-matrix.h @@ -45,11 +45,11 @@ class TpMatrix : public PackedMatrix { /// Copy constructor from CUDA TpMatrix /// This is defined in ../cudamatrix/cu-tp-matrix.cc explicit TpMatrix(const CuTpMatrix &cu); - - + + template explicit TpMatrix(const TpMatrix& orig) : PackedMatrix(orig) {} - + Real operator() (MatrixIndexT r, MatrixIndexT c) const { if (static_cast(c) > static_cast(r)) { @@ -74,9 +74,9 @@ class TpMatrix : public PackedMatrix { return *(this->data_ + (r*(r+1)) / 2 + c); // Duplicating code from PackedMatrix.h } - // Note: Cholesky may throw std::runtime_error + // Note: Cholesky may throw KaldiFatalError. void Cholesky(const SpMatrix& orig); - + void Invert(); // Inverts in double precision. @@ -99,7 +99,7 @@ class TpMatrix : public PackedMatrix { /// This is implemented in ../cudamatrix/cu-tp-matrix.cc void CopyFromMat(const CuTpMatrix &other); - + /// CopyFromTp copies another triangular matrix into this one. void CopyFromTp(const TpMatrix &other) { PackedMatrix::CopyFromPacked(other); @@ -132,4 +132,3 @@ class TpMatrix : public PackedMatrix { #endif - diff --git a/src/online/online-audio-source.cc b/src/online/online-audio-source.cc index 7b3c31682aa..5998be0690f 100644 --- a/src/online/online-audio-source.cc +++ b/src/online/online-audio-source.cc @@ -72,18 +72,18 @@ OnlinePaSource::OnlinePaSource(const uint32 timeout, &pa_ringbuf_, sizeof(SampleType), rb_size_ / sizeof(SampleType), ring_buffer_); if (rbs != 0) - throw runtime_error("Unexpected PortAudio ring buffer init error"); + KALDI_ERR << "PortAudio ring buffer init error"; PaError paerr = Pa_Initialize(); if (paerr != paNoError) - throw runtime_error("PortAudio initialization error"); + KALDI_ERR << "PortAudio initialization error"; // Monophone, 16-bit input hardcoded KALDI_ASSERT(sizeof(SampleType) == 2 && "The current OnlinePaSource code assumes 16-bit input"); paerr = Pa_OpenDefaultStream(&pa_stream_, 1, 0, paInt16, sample_rate_, 0, PaCallback, this); if (paerr != paNoError) - throw runtime_error("PortAudio failed to open the default stream"); + KALDI_ERR << "PortAudio failed to open the default stream"; } @@ -103,7 +103,7 @@ bool OnlinePaSource::Read(Vector *data) { if (!pa_started_) { // start stream the first time Read() is called PaError paerr = Pa_StartStream(pa_stream_); if (paerr != paNoError) - throw std::runtime_error("Error while trying to open PortAudio stream"); + KALDI_ERR << "Error while trying to open PortAudio stream"; pa_started_ = true; } Timer timer; diff --git a/src/online/online-audio-source.h b/src/online/online-audio-source.h index d880660d24f..64153e9cd52 100644 --- a/src/online/online-audio-source.h +++ b/src/online/online-audio-source.h @@ -42,7 +42,7 @@ class OnlineAudioSourceItf { // The function returns true if there may be more data, and false if it // knows we are at the end of the stream. // In case an unexpected and unrecoverable error occurs the function throws - // an exception of type std::runtime_error (e.g. by using KALDI_ERR macro). + // an exception of type KaldiFatalError (by using KALDI_ERR macro). // // NOTE: The older version of this interface had a second paramater - "timeout". // We decided to remove it, because we don't envision usage scenarios, diff --git a/src/tree/build-tree-utils.cc b/src/tree/build-tree-utils.cc index 4c9be833185..254d7ec36d8 100644 --- a/src/tree/build-tree-utils.cc +++ b/src/tree/build-tree-utils.cc @@ -400,7 +400,7 @@ BaseFloat FindBestSplitForKey(const BuildTreeStatsType &stats, for (size_t i = 0;i < assignments.size();i++) if (assignments[i] == 1) yes_set.push_back(i); } *yes_set_out = yes_set; - + DeletePointers(&clusters); #ifdef KALDI_PARANOID { // Check the "ans" is correct. @@ -763,10 +763,9 @@ EventMap *GetToLengthMap(const BuildTreeStatsType &stats, int32 P, std::vector stats_by_phone; try { SplitStatsByKey(stats, P, &stats_by_phone); - } catch(const std::runtime_error &err) { - KALDI_ERR << "Caught exception in GetToLengthMap: you seem " - "to have provided invalid stats [no central-phone " - "key]. Message was: " << err.what(); + } catch(const KaldiFatalError &) { + KALDI_ERR << + "You seem to have provided invalid stats [no central-phone key]."; } std::map phone_to_length; for (size_t p = 0; p < stats_by_phone.size(); p++) { @@ -774,10 +773,9 @@ EventMap *GetToLengthMap(const BuildTreeStatsType &stats, int32 P, std::vector stats_by_length; try { SplitStatsByKey(stats_by_phone[p], kPdfClass, &stats_by_length); - } catch(const std::runtime_error &err) { - KALDI_ERR << "Caught exception in GetToLengthMap: you seem " - "to have provided invalid stats [no position " - "key]. Message was: " << err.what(); + } catch(const KaldiFatalError &) { + KALDI_ERR << + "You seem to have provided invalid stats [no position key]."; } size_t length = stats_by_length.size(); for (size_t i = 0; i < length; i++) { @@ -868,7 +866,7 @@ EventMap *ClusterEventMapToNClustersRestrictedByMap( int32 *num_removed_ptr) { std::vector split_stats; SplitStatsByMap(stats, e_restrict, &split_stats); - + if (num_clusters_required < split_stats.size()) { KALDI_WARN << "num-clusters-required is less than size of map. Not doing anything."; if (num_removed_ptr) *num_removed_ptr = 0; @@ -904,10 +902,10 @@ EventMap *ClusterEventMapToNClustersRestrictedByMap( if (j > max_index) max_index = j; } } - + normalizer += SumClusterableNormalizer(summed_stats_contiguous[i]); - } else { - // Even if split_stats[i] is empty, a cluster will be assigned to + } else { + // Even if split_stats[i] is empty, a cluster will be assigned to // that. To compensate, we decrease the num-clusters required. num_non_empty_clusters_required--; } @@ -919,7 +917,7 @@ EventMap *ClusterEventMapToNClustersRestrictedByMap( if (num_non_empty_clusters_required > num_non_empty_clusters) { KALDI_WARN << "Cannot get required num-clusters " << num_clusters_required << " as number of non-empty clusters required is larger than " - << " number of non-empty clusters: " << num_non_empty_clusters_required + << " number of non-empty clusters: " << num_non_empty_clusters_required << " > " << num_non_empty_clusters; if (num_removed_ptr) *num_removed_ptr = 0; return e_in.Copy(); @@ -929,7 +927,7 @@ EventMap *ClusterEventMapToNClustersRestrictedByMap( BaseFloat change = ClusterBottomUpCompartmentalized( summed_stats_contiguous, std::numeric_limits::infinity(), - num_non_empty_clusters_required, + num_non_empty_clusters_required, NULL, // don't need clusters out. &assignments); // this algorithm is quadratic, so might be quite slow. @@ -1052,7 +1050,7 @@ EventMap *GetStubMap(int32 P, // Do a split. Recurse. size_t half_sz = phone_sets.size() / 2; std::vector >::const_iterator half_phones = - phone_sets.begin() + half_sz; + phone_sets.begin() + half_sz; std::vector::const_iterator half_share = share_roots.begin() + half_sz; std::vector > phone_sets_1, phone_sets_2; @@ -1127,4 +1125,3 @@ bool ConvertStats(int32 oldN, int32 oldP, int32 newN, int32 newP, } // end namespace kaldi - diff --git a/src/util/kaldi-table.h b/src/util/kaldi-table.h index e3a80b2743b..bb7177ad051 100644 --- a/src/util/kaldi-table.h +++ b/src/util/kaldi-table.h @@ -383,8 +383,7 @@ class TableWriter { // Returns true if open for writing. bool IsOpen() const; - // Write the object. Throws std::runtime_error on error (via the - // KALDI_ERR macro) + // Write the object. Throws KaldiFatalError on error via the KALDI_ERR macro. inline void Write(const std::string &key, const T &value) const;