From b9e2690823268604d18402f38af7aa363ec3d849 Mon Sep 17 00:00:00 2001 From: Andi Drebes Date: Mon, 13 Sep 2021 15:10:49 +0200 Subject: [PATCH] refactor(compiler): Replace LOG_{VERBOSE,ERROR} macros with C++-style streams Replace the macros `LOG_VERBOSE` and `LOG_ERROR` with C++-style streams retrieved through `log_verbose()` and `log_error()`. This aligns with the `MLIR` infrastructure and avoids pollution of the global namespace through a common header file in subsequent refactoring commits splitting the functionality of `src/main.cpp` into multiple files. --- compiler/include/zamalang/Support/logging.h | 38 ++++++++++++++++ compiler/lib/Support/CMakeLists.txt | 1 + compiler/lib/Support/logging.cpp | 22 +++++++++ compiler/src/main.cpp | 49 +++++++++++---------- 4 files changed, 86 insertions(+), 24 deletions(-) create mode 100644 compiler/include/zamalang/Support/logging.h create mode 100644 compiler/lib/Support/logging.cpp diff --git a/compiler/include/zamalang/Support/logging.h b/compiler/include/zamalang/Support/logging.h new file mode 100644 index 000000000..426381bcb --- /dev/null +++ b/compiler/include/zamalang/Support/logging.h @@ -0,0 +1,38 @@ +#ifndef ZAMALANG_SUPPORT_LOGGING_H_ +#define ZAMALANG_SUPPORT_LOGGING_H_ + +#include + +namespace mlir { +namespace zamalang { + +// Returning references to instances of different classes `S` and `T` +// is prohibited, even if `T` inherits from `S`. The wrapper class +// `StreamWrap` can be initialized with a pointer to an instance of +// `S` or any of its subclasses and acts as a proxy transparently +// forwarding all calls to `S::operator<<`. The class thus hides the +// dereferencing of the pointer and a reference to it can be used as a +// replacement for a reference to `S`. +template class StreamWrap { +public: + StreamWrap() = delete; + StreamWrap(S *s) : s(s) {} + + // Forward all invocations of + // `StreamWrap::operator<<` to S::operator<<`. + template StreamWrap &operator<<(const T &v) { + *this->s << v; + return *this; + } + +private: + S *s = nullptr; +}; + +StreamWrap &log_error(void); +StreamWrap &log_verbose(void); +void setupLogging(bool verbose); +} // namespace zamalang +} // namespace mlir + +#endif diff --git a/compiler/lib/Support/CMakeLists.txt b/compiler/lib/Support/CMakeLists.txt index 279efbaf2..55fc97e2c 100644 --- a/compiler/lib/Support/CMakeLists.txt +++ b/compiler/lib/Support/CMakeLists.txt @@ -5,6 +5,7 @@ add_mlir_library(ZamalangSupport V0Curves.cpp ClientParameters.cpp KeySet.cpp + logging.cpp ADDITIONAL_HEADER_DIRS ${PROJECT_SOURCE_DIR}/include/zamalang/Support diff --git a/compiler/lib/Support/logging.cpp b/compiler/lib/Support/logging.cpp new file mode 100644 index 000000000..0f800c459 --- /dev/null +++ b/compiler/lib/Support/logging.cpp @@ -0,0 +1,22 @@ +#include + +namespace mlir { +namespace zamalang { +static bool verbose = false; +static StreamWrap errWrap(&llvm::errs()); +static StreamWrap nullWrap(&llvm::nulls()); + +// Returns a stream for logging errors +StreamWrap &log_error(void) { return errWrap; } + +// Returns a stream that either shows or discards messages depending +// on the setup through `setupLogging`. +StreamWrap &log_verbose(void) { + return (verbose) ? errWrap : nullWrap; +} + +// Sets up logging. If `verbose` is false, messages passed to +// `log_verbose` will be discarded. +void setupLogging(bool verbose) { ::mlir::zamalang::verbose = verbose; } +} // namespace zamalang +} // namespace mlir diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index 04b4fe185..a6441a789 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -20,6 +20,7 @@ #include "zamalang/Dialect/MidLFHE/IR/MidLFHEDialect.h" #include "zamalang/Dialect/MidLFHE/IR/MidLFHETypes.h" #include "zamalang/Support/CompilerTools.h" +#include "zamalang/Support/logging.h" namespace cmdline { @@ -78,12 +79,6 @@ llvm::cl::opt toLLVM("to-llvm", llvm::cl::desc("Compile to llvm and "), llvm::cl::init(false)); }; // namespace cmdline -#define LOG_VERBOSE(expr) \ - if (cmdline::verbose) \ - llvm::errs() << expr; - -#define LOG_ERROR(expr) llvm::errs() << expr; - auto defaultOptPipeline = mlir::makeOptimizingTransformer(3, 0, nullptr); mlir::LogicalResult dumpLLVMIR(mlir::ModuleOp module, llvm::raw_ostream &os) { @@ -112,25 +107,27 @@ mlir::LogicalResult runJit(mlir::ModuleOp module, auto maybeArguments = mlir::zamalang::JITLambda::Argument::create(keySet); if (auto err = maybeArguments.takeError()) { - LOG_ERROR("Cannot create lambda arguments: " << err << "\n"); + mlir::zamalang::log_error() + << "Cannot create lambda arguments: " << err << "\n"; return mlir::failure(); } // Set the arguments auto arguments = std::move(maybeArguments.get()); for (auto i = 0; i < cmdline::jitArgs.size(); i++) { if (auto err = arguments->setArg(i, cmdline::jitArgs[i])) { - LOG_ERROR("Cannot push argument " << i << ": " << err << "\n"); + mlir::zamalang::log_error() + << "Cannot push argument " << i << ": " << err << "\n"; return mlir::failure(); } } // Invoke the lambda if (auto err = lambda->invoke(*arguments)) { - LOG_ERROR("Cannot invoke : " << err << "\n"); + mlir::zamalang::log_error() << "Cannot invoke : " << err << "\n"; return mlir::failure(); } uint64_t res = 0; if (auto err = arguments->getResult(0, res)) { - LOG_ERROR("Cannot get result : " << err << "\n"); + mlir::zamalang::log_error() << "Cannot get result : " << err << "\n"; return mlir::failure(); } llvm::errs() << res << "\n"; @@ -185,17 +182,18 @@ processInputBuffer(mlir::MLIRContext &context, .failed()) { return mlir::failure(); } - LOG_VERBOSE("### Global FHE constraint: {norm2:" - << fheContext.constraint.norm2 - << ", p:" << fheContext.constraint.p << "}\n"); - LOG_VERBOSE("### FHE parameters for the atomic pattern: {k: " - << fheContext.parameter.k - << ", polynomialSize: " << fheContext.parameter.polynomialSize - << ", nSmall: " << fheContext.parameter.nSmall - << ", brLevel: " << fheContext.parameter.brLevel - << ", brLogBase: " << fheContext.parameter.brLogBase - << ", ksLevel: " << fheContext.parameter.ksLevel - << ", ksLogBase: " << fheContext.parameter.ksLogBase << "}\n"); + mlir::zamalang::log_verbose() + << "### Global FHE constraint: {norm2:" << fheContext.constraint.norm2 + << ", p:" << fheContext.constraint.p << "}\n"; + mlir::zamalang::log_verbose() + << "### FHE parameters for the atomic pattern: {k: " + << fheContext.parameter.k + << ", polynomialSize: " << fheContext.parameter.polynomialSize + << ", nSmall: " << fheContext.parameter.nSmall + << ", brLevel: " << fheContext.parameter.brLevel + << ", brLogBase: " << fheContext.parameter.brLogBase + << ", ksLevel: " << fheContext.parameter.ksLevel + << ", ksLogBase: " << fheContext.parameter.ksLogBase << "}\n"; // Generate the keySet std::unique_ptr keySet; @@ -204,10 +202,11 @@ processInputBuffer(mlir::MLIRContext &context, auto clientParameter = mlir::zamalang::createClientParametersForV0( fheContext, cmdline::jitFuncname, *module); if (auto err = clientParameter.takeError()) { - LOG_ERROR("cannot generate client parameters: " << err << "\n"); + mlir::zamalang::log_error() + << "cannot generate client parameters: " << err << "\n"; return mlir::failure(); } - LOG_VERBOSE("### Generate the key set\n"); + mlir::zamalang::log_verbose() << "### Generate the key set\n"; auto maybeKeySet = mlir::zamalang::KeySet::generate(clientParameter.get(), 0, 0); // TODO: seed @@ -226,7 +225,7 @@ processInputBuffer(mlir::MLIRContext &context, } if (cmdline::runJit) { - LOG_VERBOSE("### JIT compile & running\n"); + mlir::zamalang::log_verbose() << "### JIT compile & running\n"; return runJit(module.get(), *keySet, os); } if (cmdline::toLLVM) { @@ -243,6 +242,8 @@ mlir::LogicalResult compilerMain(int argc, char **argv) { // Initialize the MLIR context mlir::MLIRContext context; + mlir::zamalang::setupLogging(cmdline::verbose); + // String for error messages from library functions std::string errorMessage;