Index: parallel-libs/trunk/streamexecutor/examples/Example.cpp =================================================================== --- parallel-libs/trunk/streamexecutor/examples/Example.cpp +++ parallel-libs/trunk/streamexecutor/examples/Example.cpp @@ -23,27 +23,6 @@ #include "streamexecutor/StreamExecutor.h" -/// [Example saxpy host helper functions] -// Example handler for streamexecutor::Expected return values. -template T getOrDie(streamexecutor::Expected &&E) { - if (!E) { - std::fprintf(stderr, "Error extracting an expected value: %s.\n", - streamexecutor::consumeAndGetMessage(E.takeError()).c_str()); - std::exit(EXIT_FAILURE); - } - return std::move(*E); -} - -// Example handler for streamexecutor::Error return values. -void check(streamexecutor::Error &&E) { - if (E) { - std::fprintf(stderr, "Error encountered: %s.\n", - streamexecutor::consumeAndGetMessage(std::move(E)).c_str()); - std::exit(EXIT_FAILURE); - } -} -/// [Example saxpy host helper functions] - /// [Example saxpy compiler-generated] // Code in this namespace is generated by the compiler (e.g. clang). // @@ -148,7 +127,7 @@ .thenLaunch(ArraySize, 1, *Kernel, A, X, Y) .thenCopyD2H(X, HostX); // Wait for the stream to complete. - check(Stream->blockHostUntilDone()); + se::dieIfError(Stream->blockHostUntilDone()); // Process output data in HostX. std::vector ExpectedX = {4, 47, 90, 133}; @@ -157,7 +136,7 @@ } // Free device memory. - check(Device->freeDeviceMemory(X)); - check(Device->freeDeviceMemory(Y)); + se::dieIfError(Device->freeDeviceMemory(X)); + se::dieIfError(Device->freeDeviceMemory(Y)); /// [Example saxpy host main] } Index: parallel-libs/trunk/streamexecutor/include/streamexecutor/StreamExecutor.h =================================================================== --- parallel-libs/trunk/streamexecutor/include/streamexecutor/StreamExecutor.h +++ parallel-libs/trunk/streamexecutor/include/streamexecutor/StreamExecutor.h @@ -23,15 +23,12 @@ /// /// \snippet examples/Example.cpp Example saxpy host main /// -/// In the example, a couple of handler functions are used to handle error -/// return values in the StreamExecutor API: -/// -/// \snippet examples/Example.cpp Example saxpy host helper functions -/// -/// These are just example handler functions. A real application will likely -/// want to define similar handlers of its own that log errors in an -/// application-specific way, convert errors to the application's own -/// error-handling framework, or try to recover from errors as appropriate. +/// In the example, a couple of handler functions, \c getOrDie and \c +/// dieIfError, are used to handle error return values in the StreamExecutor +/// API. These functions are provided by StreamExecutor for quick-and-dirty +/// error handling, but real applications will likely want to define their own +/// versions of these handlers so that errors are handled more gracefully than +/// just exiting the program. /// /// The example also references some symbols from a compiler-generated /// namespace: Index: parallel-libs/trunk/streamexecutor/include/streamexecutor/Utils/Error.h =================================================================== --- parallel-libs/trunk/streamexecutor/include/streamexecutor/Utils/Error.h +++ parallel-libs/trunk/streamexecutor/include/streamexecutor/Utils/Error.h @@ -65,6 +65,8 @@ /// There is also a function consumeError that consumes an error value without /// fetching the error message. This is useful when we want to ignore an error. /// +/// The dieIfError function is also provided for quick-and-dirty error handling. +/// /// /// \section expected The Expected Class /// @@ -137,6 +139,8 @@ /// } /// \endcode /// +/// The getOrDie function is also available for quick-and-dirty error handling. +/// /// /// \section llvm Relation to llvm::Error and llvm::Expected /// @@ -159,6 +163,8 @@ #ifndef STREAMEXECUTOR_UTILS_ERROR_H #define STREAMEXECUTOR_UTILS_ERROR_H +#include +#include #include #include @@ -171,14 +177,39 @@ using llvm::Expected; using llvm::Twine; -// Makes an Error object from an error message. +/// Makes an Error object from an error message. Error make_error(Twine Message); -// Consumes the input error and returns its error message. -// -// Assumes the input was created by the make_error function above. +/// Consumes the input error and returns its error message. +/// +/// Assumes the input was created by the make_error function above. std::string consumeAndGetMessage(Error &&E); +/// Extracts the T value from an Expected or prints an error message to +/// stderr and exits the program with code EXIT_FAILURE if the Expected is an +/// error. +/// +/// This function and the dieIfError function are provided for applications that +/// are OK with aborting the program if an error occurs, and which don't have +/// any special error logging needs. Applications with different error handling +/// needs will likely want to declare their own functions with similar +/// signatures but which log error messages in a different way or attempt to +/// recover from errors instead of aborting the program. +template T getOrDie(Expected &&E) { + if (!E) { + std::fprintf(stderr, "Error extracting an expected value: %s.\n", + consumeAndGetMessage(E.takeError()).c_str()); + std::exit(EXIT_FAILURE); + } + return std::move(*E); +} + +/// Prints an error message to stderr and exits the program with code +/// EXIT_FAILURE if the input is an error. +/// +/// \sa getOrDie +void dieIfError(Error &&E); + } // namespace streamexecutor #endif // STREAMEXECUTOR_UTILS_ERROR_H Index: parallel-libs/trunk/streamexecutor/lib/Utils/Error.cpp =================================================================== --- parallel-libs/trunk/streamexecutor/lib/Utils/Error.cpp +++ parallel-libs/trunk/streamexecutor/lib/Utils/Error.cpp @@ -60,4 +60,12 @@ return Message; } +void dieIfError(Error &&E) { + if (E) { + std::fprintf(stderr, "Error encountered: %s.\n", + streamexecutor::consumeAndGetMessage(std::move(E)).c_str()); + std::exit(EXIT_FAILURE); + } +} + } // namespace streamexecutor