Skip to content

Commit

Permalink
Merge branch 'main' into taa-add-contribution-guidelines
Browse files Browse the repository at this point in the history
  • Loading branch information
taalexander authored Jan 3, 2024
2 parents 5cb699c + b6b3404 commit 02bacbf
Show file tree
Hide file tree
Showing 9 changed files with 1,036 additions and 524 deletions.
22 changes: 7 additions & 15 deletions include/Config/CLIConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ namespace qssc::config {

/// @brief Get the CLI category for the QSS compiler.
/// @return The reference to the CLI category for the compiler.
llvm::cl::OptionCategory &getQSSCCategory();
llvm::cl::OptionCategory &getQSSCCLCategory();

/// @brief Get the CLI category for the QSS compiler mlir-opt options.
/// @return The reference to the CLI category for the compiler.
llvm::cl::OptionCategory &getQSSOptCLCategory();

/// @brief Build a QSSConfig from input CLI arguments.
///
Expand All @@ -32,23 +36,11 @@ llvm::cl::OptionCategory &getQSSCCategory();
///
/// The qss-compiler adds several cli arguments to
/// configure the QSSConfig through the CLIConfigBuilder.
///
/// These currently are:
/// - `--target=<str>`: Sets QSSConfig::targetName.
/// - `--config=<str>`: Sets QSSConfig::targetConfigPath.
/// - `--allow-unregistered-dialect=<bool>`: Sets
/// QSSConfig::allowUnregisteredDialects.
/// - `--add-target-passes=<bool>`: Sets QSSConfig::addTargetPasses.
///
class CLIConfigBuilder : public QSSConfigBuilder {
public:
explicit CLIConfigBuilder();
static void registerCLOptions(mlir::DialectRegistry &registry);
llvm::Error populateConfig(QSSConfig &config) override;

private:
llvm::Error populateConfigurationPath_(QSSConfig &config);
llvm::Error populateTarget_(QSSConfig &config);
llvm::Error populateAllowUnregisteredDialects_(QSSConfig &config);
llvm::Error populateAddTargetPasses_(QSSConfig &config);
};

} // namespace qssc::config
Expand Down
213 changes: 206 additions & 7 deletions include/Config/QSSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,44 @@
#include "llvm/Support/raw_ostream.h"

#include "mlir/IR/MLIRContext.h"
#include "mlir/Tools/mlir-opt/MlirOptMain.h"

#include <iostream>
#include <optional>
#include <string>
#include <utility>

namespace qssc::config {

enum class EmitAction { None, AST, ASTPretty, MLIR, WaveMem, QEM, QEQEM };

enum class FileExtension {
None,
AST,
ASTPretty,
QASM,
MLIR,
WaveMem,
QEM,
QEQEM
};

enum class InputType { None, QASM, MLIR };

std::string to_string(const EmitAction &inExt);

std::string to_string(const FileExtension &inExt);

std::string to_string(const InputType &inType);

InputType fileExtensionToInputType(const FileExtension &inExt);

EmitAction fileExtensionToAction(const FileExtension &inExt);

FileExtension strToFileExtension(const llvm::StringRef extStr);

FileExtension getExtension(const llvm::StringRef inStr);

/// @brief The QSS configuration data structure that is to be used for global
/// configuration of the QSS infrastructure. This is to be used for static
/// options that are rarely changed for a system and do not need to be
Expand All @@ -33,18 +64,164 @@ namespace qssc::config {
/// as CLI, environment variables and possible configuration file formats
/// through QSSConfigBuilder implementations which apply successive views over
/// the configuration to produce the final configuration.
struct QSSConfig {
struct QSSConfig : mlir::MlirOptMainConfig {

public:
friend class CLIConfigBuilder;
friend class EnvVarConfigBuilder;

QSSConfig &setInputSource(std::string source) {
inputSource = std::move(source);
return *this;
}
llvm::StringRef getInputSource() const { return inputSource; }

QSSConfig &directInput(bool flag) {
directInputFlag = flag;
return *this;
}
bool isDirectInput() const { return directInputFlag; }

QSSConfig &setOutputFilePath(std::string path) {
outputFilePath = std::move(path);
return *this;
}
llvm::StringRef getOutputFilePath() const { return outputFilePath; }

QSSConfig &setTargetName(std::string name) {
targetName = std::move(name);
return *this;
}
std::optional<llvm::StringRef> getTargetName() const {
if (targetName.has_value())
return targetName.value();
return std::nullopt;
}

QSSConfig &setTargetConfigPath(std::string path) {
targetConfigPath = std::move(path);
return *this;
}
std::optional<llvm::StringRef> getTargetConfigPath() const {
if (targetConfigPath.has_value())
return targetConfigPath.value();
return std::nullopt;
}

QSSConfig &setInputType(InputType type) {
inputType = type;
return *this;
}
InputType getInputType() const { return inputType; }

QSSConfig &setEmitAction(EmitAction action) {
emitAction = action;
return *this;
}
EmitAction getEmitAction() const { return emitAction; }

QSSConfig &addTargetPasses(bool flag) {
addTargetPassesFlag = flag;
return *this;
}
bool shouldAddTargetPasses() const { return addTargetPassesFlag; }

QSSConfig &showTargets(bool flag) {
showTargetsFlag = flag;
return *this;
}
bool shouldShowTargets() const { return showTargetsFlag; }

QSSConfig &showPayloads(bool flag) {
showPayloadsFlag = flag;
return *this;
}
bool shouldShowPayloads() const { return showPayloadsFlag; }

QSSConfig &showConfig(bool flag) {
showConfigFlag = flag;
return *this;
}
bool shouldShowConfig() const { return showConfigFlag; }

QSSConfig &emitPlaintextPayload(bool flag) {
emitPlaintextPayloadFlag = flag;
return *this;
}
bool shouldEmitPlaintextPayload() const { return emitPlaintextPayloadFlag; }

QSSConfig &includeSource(bool flag) {
includeSourceFlag = flag;
return *this;
}
bool shouldIncludeSource() const { return includeSourceFlag; }

QSSConfig &compileTargetIR(bool flag) {
compileTargetIRFlag = flag;
return *this;
}
bool shouldCompileTargetIR() const { return compileTargetIRFlag; }

QSSConfig &bypassPayloadTargetCompilation(bool flag) {
bypassPayloadTargetCompilationFlag = flag;
return *this;
}
bool shouldBypassPayloadTargetCompilation() const {
return bypassPayloadTargetCompilationFlag;
}

QSSConfig &setPassPlugins(std::vector<std::string> plugins) {
dialectPlugins = std::move(plugins);
return *this;
}
const std::vector<std::string> &getPassPlugins() { return dialectPlugins; }

QSSConfig &setDialectPlugins(std::vector<std::string> plugins) {
dialectPlugins = std::move(plugins);
return *this;
}
const std::vector<std::string> &getDialectPlugins() { return dialectPlugins; }

public:
/// @brief Emit the configuration to stdout.
void emit(llvm::raw_ostream &out) const;

protected:
/// @brief input source (file path or direct input) to compile
std::string inputSource = "-";
/// @brief Whether inputSource directly contains the input source (otherwise
/// it is a file path).
bool directInputFlag = false;
/// @brief Output path for the compiler output if emitting to file.
std::string outputFilePath = "-";
/// @brief The TargetSystem to target compilation for.
std::optional<std::string> targetName = std::nullopt;
/// @brief The path to the TargetSystem configuration information.
std::optional<std::string> targetConfigPath = std::nullopt;
/// @brief Allow unregistered dialects to be used during compilation.
bool allowUnregisteredDialects = false;
/// @brief Source input type
InputType inputType = InputType::None;
/// @brief Output action to take
EmitAction emitAction = EmitAction::None;
/// @brief Register target passes with the compiler.
bool addTargetPasses = true;

/// @brief Emit the configuration to stdout.
void emit(llvm::raw_ostream &out) const;
bool addTargetPassesFlag = true;
/// @brief Should available targets be printed
bool showTargetsFlag = false;
/// @brief Should available payloads be printed
bool showPayloadsFlag = false;
/// @brief Should the current configuration be printed
bool showConfigFlag = false;
/// @brief Should the plaintext payload be emitted
bool emitPlaintextPayloadFlag = false;
/// @brief Should the input source be included in the payload
bool includeSourceFlag = false;
/// @brief Should the IR be compiled for the target
bool compileTargetIRFlag = false;
/// @brief Should target payload generation be bypassed
bool bypassPayloadTargetCompilationFlag = false;
/// @brief Pass plugin paths
std::vector<std::string> passPlugins;
/// @brief Dialect plugin paths
std::vector<std::string> dialectPlugins;
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QSSConfig &config);
Expand All @@ -61,6 +238,16 @@ void setContextConfig(mlir::MLIRContext *context, const QSSConfig &config);
/// @param context The context to lookup the configuration for.
llvm::Expected<const QSSConfig &> getContextConfig(mlir::MLIRContext *context);

/// @brief Load a dynamic dialect plugin
/// @param pluginPath Path to the plugin
/// @param registry Dialect registry to register the plugin dialect with
mlir::LogicalResult loadDialectPlugin(const std::string &pluginPath,
mlir::DialectRegistry &registry);

/// @brief Load a dynamic pass plugin
/// @param pluginPath Path to the plugin
mlir::LogicalResult loadPassPlugin(const std::string &pluginPath);

/// @brief A builder class for the QSSConfig. All standard configuration
/// population should be completed through builders.
class QSSConfigBuilder {
Expand All @@ -73,5 +260,17 @@ class QSSConfigBuilder {
virtual ~QSSConfigBuilder() = default;
};

/// Build the default tool configuration
/// @brief Build the QSSConfig using the standard sources and assign to the
/// supplied context.
///
/// The configuration precedence order is
/// 1. Default values
/// 2. Environment variables
/// 3. CLI arguments.
///
/// @return The constructed configuration
llvm::Expected<qssc::config::QSSConfig> buildToolConfig();

} // namespace qssc::config
#endif // QSS_QSSCONFIG_H
Loading

0 comments on commit 02bacbf

Please sign in to comment.