From 94520c7819dd46754fe5e3e9a2b425ee14f56761 Mon Sep 17 00:00:00 2001 From: Martin Erhart Date: Sat, 23 Nov 2024 19:02:36 +0000 Subject: [PATCH 1/2] [RTG][RTGTest] Add CAPI and a basic lowering pipeline --- include/circt-c/Dialect/RTG.h | 53 +++++++++++ include/circt-c/Dialect/RTGTest.h | 38 ++++++++ include/circt-c/RtgTool.h | 79 ++++++++++++++++ .../circt/Dialect/RTGTest/IR/RTGTestTypes.td | 2 +- include/circt/Tools/rtgtool/RtgToolOptions.h | 93 +++++++++++++++++++ lib/CAPI/CMakeLists.txt | 1 + lib/CAPI/Dialect/CMakeLists.txt | 20 ++++ lib/CAPI/Dialect/RTG.cpp | 65 +++++++++++++ lib/CAPI/Dialect/RTGTest.cpp | 32 +++++++ lib/CAPI/RtgTool/CMakeLists.txt | 7 ++ lib/CAPI/RtgTool/RtgTool.cpp | 92 ++++++++++++++++++ lib/Tools/CMakeLists.txt | 1 + lib/Tools/rtgtool/CMakeLists.txt | 10 ++ lib/Tools/rtgtool/RtgToolOptions.cpp | 35 +++++++ test/CAPI/CMakeLists.txt | 40 ++++++++ test/CAPI/rtg-pipelines.c | 56 +++++++++++ test/CAPI/rtg.c | 70 ++++++++++++++ test/CAPI/rtgtest.c | 33 +++++++ test/CMakeLists.txt | 3 + test/lit.cfg.py | 8 +- 20 files changed, 734 insertions(+), 4 deletions(-) create mode 100644 include/circt-c/Dialect/RTG.h create mode 100644 include/circt-c/Dialect/RTGTest.h create mode 100644 include/circt-c/RtgTool.h create mode 100644 include/circt/Tools/rtgtool/RtgToolOptions.h create mode 100644 lib/CAPI/Dialect/RTG.cpp create mode 100644 lib/CAPI/Dialect/RTGTest.cpp create mode 100644 lib/CAPI/RtgTool/CMakeLists.txt create mode 100644 lib/CAPI/RtgTool/RtgTool.cpp create mode 100644 lib/Tools/rtgtool/CMakeLists.txt create mode 100644 lib/Tools/rtgtool/RtgToolOptions.cpp create mode 100644 test/CAPI/rtg-pipelines.c create mode 100644 test/CAPI/rtg.c create mode 100644 test/CAPI/rtgtest.c diff --git a/include/circt-c/Dialect/RTG.h b/include/circt-c/Dialect/RTG.h new file mode 100644 index 000000000000..dbd5a2bf6fce --- /dev/null +++ b/include/circt-c/Dialect/RTG.h @@ -0,0 +1,53 @@ +//===- RTG.h - C interface for the for RTG dialect ----------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_C_DIALECT_RTG_H +#define CIRCT_C_DIALECT_RTG_H + +#include "mlir-c/IR.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(RTG, rtg); + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +/// If the type is an RTG sequence. +MLIR_CAPI_EXPORTED bool rtgTypeIsASequence(MlirType type); + +/// Creates an RTG sequence type in the context. +MLIR_CAPI_EXPORTED MlirType rtgSequenceTypeGet(MlirContext ctxt); + +/// If the type is an RTG set. +MLIR_CAPI_EXPORTED bool rtgTypeIsASet(MlirType type); + +/// Creates an RTG set type in the context. +MLIR_CAPI_EXPORTED MlirType rtgSetTypeGet(MlirType elementType); + +/// If the type is an RTG dict. +MLIR_CAPI_EXPORTED bool rtgTypeIsADict(MlirType type); + +/// Creates an RTG dict type in the context. +MLIR_CAPI_EXPORTED MlirType rtgDictTypeGet(MlirContext ctxt, + intptr_t numEntries, + MlirAttribute const *entryNames, + MlirType const *entryTypes); + +#ifdef __cplusplus +} +#endif + +#endif // CIRCT_C_DIALECT_RTG_H diff --git a/include/circt-c/Dialect/RTGTest.h b/include/circt-c/Dialect/RTGTest.h new file mode 100644 index 000000000000..0462795588a0 --- /dev/null +++ b/include/circt-c/Dialect/RTGTest.h @@ -0,0 +1,38 @@ +//===- RTGTest.h - C interface for the for RTGTest dialect --------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_C_DIALECT_RTGTEST_H +#define CIRCT_C_DIALECT_RTGTEST_H + +#include "mlir-c/IR.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(RTGTest, rtgtest); + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +/// If the type is an RTGTest CPUType. +MLIR_CAPI_EXPORTED bool rtgtestTypeIsACPU(MlirType type); + +/// Creates an RTGTest CPU type in the context. +MLIR_CAPI_EXPORTED MlirType rtgtestCPUTypeGet(MlirContext ctxt); + +#ifdef __cplusplus +} +#endif + +#endif // CIRCT_C_DIALECT_RTGTEST_H diff --git a/include/circt-c/RtgTool.h b/include/circt-c/RtgTool.h new file mode 100644 index 000000000000..84964070de4e --- /dev/null +++ b/include/circt-c/RtgTool.h @@ -0,0 +1,79 @@ +//===-- circt-c/RtgTool.h - C API for the rtgtool -----------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_C_RTGTOOL_H +#define CIRCT_C_RTGTOOL_H + +#include "mlir-c/Pass.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//===----------------------------------------------------------------------===// +// Tool Options API. +//===----------------------------------------------------------------------===// + +#define DEFINE_C_API_STRUCT(name, storage) \ + struct name { \ + storage *ptr; \ + }; \ + typedef struct name name + +DEFINE_C_API_STRUCT(CirctRtgToolOptions, void); + +#undef DEFINE_C_API_STRUCT + +// NOLINTNEXTLINE(modernize-use-using) +typedef enum CiretRtgToolOutputFormat { + CIRCT_RTGTOOL_OUTPUT_FORMAT_MLIR, + CIRCT_RTGTOOL_OUTPUT_FORMAT_ELABORATED_MLIR, + CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM, +} CirctRtgToolOutputFormat; + +MLIR_CAPI_EXPORTED CirctRtgToolOptions +circtRtgToolOptionsCreateDefault(unsigned seed); +MLIR_CAPI_EXPORTED void circtRtgToolOptionsDestroy(CirctRtgToolOptions options); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetOutputFormat(CirctRtgToolOptions options, + CirctRtgToolOutputFormat format); + +MLIR_CAPI_EXPORTED void circtRtgToolOptionsSetSeed(CirctRtgToolOptions options, + unsigned seed); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetVerifyPasses(CirctRtgToolOptions options, bool enable); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options, + bool enable); + +MLIR_CAPI_EXPORTED void circtRtgToolOptionsSetUnsupportedInstructions( + CirctRtgToolOptions options, unsigned numInstr, + const char **unsupportedInstructions); + +MLIR_CAPI_EXPORTED void circtRtgToolOptionsAddUnsupportedInstruction( + CirctRtgToolOptions options, const char *unsupportedInstruction); + +MLIR_CAPI_EXPORTED void +circtRtgToolOptionsSetUnsupportedInstructionsFile(CirctRtgToolOptions options, + const char *filename); + +//===----------------------------------------------------------------------===// +// Pipeline Population API. +//===----------------------------------------------------------------------===// + +MLIR_CAPI_EXPORTED void +circtRtgToolRandomizerPipeline(MlirPassManager pm, CirctRtgToolOptions options); + +#ifdef __cplusplus +} +#endif + +#endif // CIRCT_C_RTGTOOL_H diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td index 8351cd8b9661..3db49151a2f1 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td @@ -20,7 +20,7 @@ include "mlir/IR/AttrTypeBase.td" class RTGTestTypeDef traits = []> : TypeDef; -def CPUType : RTGTestTypeDef<"cpu", [ContextResourceTypeInterface]> { +def CPUType : RTGTestTypeDef<"CPU", [ContextResourceTypeInterface]> { let summary = "handle to a specific CPU"; let description = [{ This type implements a specific context resource to test RTG operations diff --git a/include/circt/Tools/rtgtool/RtgToolOptions.h b/include/circt/Tools/rtgtool/RtgToolOptions.h new file mode 100644 index 000000000000..4c35a89320d1 --- /dev/null +++ b/include/circt/Tools/rtgtool/RtgToolOptions.h @@ -0,0 +1,93 @@ +//===- RtgToolOptions.h - Configuration Options for rtgtool -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This header file defines configuration options for the rtgtool. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_TOOLS_RTGTOOL_RTGTOOLOPTIONS_H +#define CIRCT_TOOLS_RTGTOOL_RTGTOOLOPTIONS_H + +#include "circt/Support/LLVM.h" +#include "mlir/Pass/PassManager.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" + +namespace circt { +namespace rtg { + +/// The set of options used to control the behavior of the RTG tool. +class RtgToolOptions { +public: + enum class OutputFormat { MLIR, ElaboratedMLIR, ASM }; + + RtgToolOptions(unsigned seed) : seed(seed) {} + + void setOutputFormat(OutputFormat format) { outputFormat = format; } + OutputFormat getOutputFormat() const { return outputFormat; } + + RtgToolOptions &setSeed(unsigned seed) { + this->seed = seed; + return *this; + } + unsigned getSeed() const { return seed; } + + RtgToolOptions &setVerifyPasses(bool enable) { + verifyPasses = enable; + return *this; + } + bool getVerifyPasses() const { return verifyPasses; } + + RtgToolOptions &setVerbosePassExecution(bool enable) { + verbosePassExecution = enable; + return *this; + } + bool getVerbosePassExecution() const { return verbosePassExecution; } + + RtgToolOptions &setUnsupportedInstructions(SmallVector &&instr) { + unsupportedInstructions = instr; + return *this; + } + RtgToolOptions &setUnsupportedInstructions(ArrayRef instr) { + unsupportedInstructions = SmallVector(instr); + return *this; + } + RtgToolOptions &addUnsupportedInstruction(const std::string &instr) { + unsupportedInstructions.push_back(instr); + return *this; + } + ArrayRef getUnsupportedInstructions() const { + return unsupportedInstructions; + } + + RtgToolOptions &setUnsupportedInstructionsFile(StringRef filename) { + unsupportedInstructionsFile = filename; + return *this; + } + std::string getUnsupportedInstructionsFile() const { + return unsupportedInstructionsFile; + } + +private: + OutputFormat outputFormat = OutputFormat::ElaboratedMLIR; + unsigned seed; + bool verifyPasses = true; + bool verbosePassExecution = false; + SmallVector unsupportedInstructions; + std::string unsupportedInstructionsFile; +}; + +/// Populates the passes necessary to lower IR with RTG randomization operations +/// to fully elaborated IR (i.e., IR without random constructs). +void populateRandomizerPipeline(mlir::PassManager &pm, + const RtgToolOptions &options); + +} // namespace rtg +} // namespace circt + +#endif // CIRCT_TOOLS_RTGTOOL_RTGTOOLOPTIONS_H diff --git a/lib/CAPI/CMakeLists.txt b/lib/CAPI/CMakeLists.txt index 5c7865400325..d9ca6a0fe83b 100644 --- a/lib/CAPI/CMakeLists.txt +++ b/lib/CAPI/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(ExportFIRRTL) add_subdirectory(ExportVerilog) add_subdirectory(Dialect) add_subdirectory(Firtool) +add_subdirectory(RtgTool) diff --git a/lib/CAPI/Dialect/CMakeLists.txt b/lib/CAPI/Dialect/CMakeLists.txt index 984fd60ee58a..a3be2a6bfd07 100644 --- a/lib/CAPI/Dialect/CMakeLists.txt +++ b/lib/CAPI/Dialect/CMakeLists.txt @@ -17,6 +17,8 @@ set(LLVM_OPTIONAL_SOURCES MSFT.cpp Moore.cpp OM.cpp + RTG.cpp + RTGTest.cpp SV.cpp Seq.cpp Verif.cpp @@ -129,6 +131,24 @@ add_circt_public_c_api_library(CIRCTCAPIOM CIRCTOMEvaluator ) +add_circt_public_c_api_library(CIRCTCAPIRTG + RTG.cpp + + LINK_LIBS PUBLIC + MLIRCAPIIR + CIRCTRTGDialect +) + +if(CIRCT_INCLUDE_TESTS) + add_circt_public_c_api_library(CIRCTCAPIRTGTest + RTGTest.cpp + + LINK_LIBS PUBLIC + MLIRCAPIIR + CIRCTRTGTestDialect + ) +endif() + add_circt_public_c_api_library(CIRCTCAPISeq Seq.cpp diff --git a/lib/CAPI/Dialect/RTG.cpp b/lib/CAPI/Dialect/RTG.cpp new file mode 100644 index 000000000000..b8172bc432d8 --- /dev/null +++ b/lib/CAPI/Dialect/RTG.cpp @@ -0,0 +1,65 @@ +//===- RTG.cpp - C interface for the RTG dialect --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "circt-c/Dialect/RTG.h" +#include "circt/Dialect/RTG/IR/RTGDialect.h" +#include "circt/Dialect/RTG/IR/RTGTypes.h" + +#include "mlir/CAPI/Registration.h" + +using namespace circt; +using namespace circt::rtg; + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(RTG, rtg, RTGDialect) + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +// SequenceType +//===----------------------------------------------------------------------===// + +bool rtgTypeIsASequence(MlirType type) { + return isa(unwrap(type)); +} + +MlirType rtgSequenceTypeGet(MlirContext ctxt) { + return wrap(SequenceType::get(unwrap(ctxt))); +} + +// SetType +//===----------------------------------------------------------------------===// + +bool rtgTypeIsASet(MlirType type) { return isa(unwrap(type)); } + +MlirType rtgSetTypeGet(MlirType elementType) { + auto ty = unwrap(elementType); + return wrap(SetType::get(ty.getContext(), ty)); +} + +// DictType +//===----------------------------------------------------------------------===// + +bool rtgTypeIsADict(MlirType type) { return isa(unwrap(type)); } + +MlirType rtgDictTypeGet(MlirContext ctxt, intptr_t numEntries, + MlirAttribute const *entryNames, + MlirType const *entryTypes) { + SmallVector entries; + for (unsigned i = 0; i < numEntries; ++i) { + DictEntry entry; + entry.name = cast(unwrap(entryNames[i])); + entry.type = unwrap(entryTypes[i]); + entries.emplace_back(entry); + } + return wrap(DictType::get(unwrap(ctxt), entries)); +} diff --git a/lib/CAPI/Dialect/RTGTest.cpp b/lib/CAPI/Dialect/RTGTest.cpp new file mode 100644 index 000000000000..a4564b94e08b --- /dev/null +++ b/lib/CAPI/Dialect/RTGTest.cpp @@ -0,0 +1,32 @@ +//===- RTGTest.cpp - C interface for the RTGTest dialect ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "circt-c/Dialect/RTGTest.h" +#include "circt/Dialect/RTGTest/IR/RTGTestDialect.h" +#include "circt/Dialect/RTGTest/IR/RTGTestTypes.h" + +#include "mlir/CAPI/Registration.h" + +using namespace circt; +using namespace circt::rtgtest; + +//===----------------------------------------------------------------------===// +// Dialect API. +//===----------------------------------------------------------------------===// + +MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(RTGTest, rtgtest, RTGTestDialect) + +//===----------------------------------------------------------------------===// +// Type API. +//===----------------------------------------------------------------------===// + +bool rtgtestTypeIsACPU(MlirType type) { return isa(unwrap(type)); } + +MlirType rtgtestCPUTypeGet(MlirContext ctxt) { + return wrap(CPUType::get(unwrap(ctxt))); +} diff --git a/lib/CAPI/RtgTool/CMakeLists.txt b/lib/CAPI/RtgTool/CMakeLists.txt new file mode 100644 index 000000000000..8369bc43e78f --- /dev/null +++ b/lib/CAPI/RtgTool/CMakeLists.txt @@ -0,0 +1,7 @@ +add_circt_public_c_api_library(CIRCTCAPIRtgTool + RtgTool.cpp + + LINK_LIBS PUBLIC + CIRCTRtgToolLib + MLIRCAPIIR +) diff --git a/lib/CAPI/RtgTool/RtgTool.cpp b/lib/CAPI/RtgTool/RtgTool.cpp new file mode 100644 index 000000000000..891e445fb65d --- /dev/null +++ b/lib/CAPI/RtgTool/RtgTool.cpp @@ -0,0 +1,92 @@ +//===- RtgTool.cpp - C Interface for the rtgtool --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "circt-c/RtgTool.h" + +#include "circt/Tools/rtgtool/RtgToolOptions.h" +#include "mlir/CAPI/Pass.h" +#include + +using namespace circt; +using namespace circt::rtg; + +//===----------------------------------------------------------------------===// +// Tool Option API. +//===----------------------------------------------------------------------===// + +DEFINE_C_API_PTR_METHODS(CirctRtgToolOptions, RtgToolOptions) + +CirctRtgToolOptions circtRtgToolOptionsCreateDefault(unsigned seed) { + auto *options = new RtgToolOptions(seed); + return wrap(options); +} + +void circtRtgToolOptionsDestroy(CirctRtgToolOptions options) { + delete unwrap(options); +} + +void circtRtgToolOptionsSetOutputFormat(CirctRtgToolOptions options, + CirctRtgToolOutputFormat format) { + RtgToolOptions::OutputFormat converted; + switch (format) { + case CIRCT_RTGTOOL_OUTPUT_FORMAT_MLIR: + converted = RtgToolOptions::OutputFormat::MLIR; + break; + case CIRCT_RTGTOOL_OUTPUT_FORMAT_ELABORATED_MLIR: + converted = RtgToolOptions::OutputFormat::ElaboratedMLIR; + break; + case CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM: + converted = RtgToolOptions::OutputFormat::ASM; + break; + } + + unwrap(options)->setOutputFormat(converted); +} + +void circtRtgToolOptionsSetSeed(CirctRtgToolOptions options, unsigned seed) { + unwrap(options)->setSeed(seed); +} + +void circtRtgToolOptionsSetVerifyPasses(CirctRtgToolOptions options, + bool enable) { + unwrap(options)->setVerifyPasses(enable); +} + +void circtRtgToolOptionsSetVerbosePassExecution(CirctRtgToolOptions options, + bool enable) { + unwrap(options)->setVerbosePassExecution(enable); +} + +void circtRtgToolOptionsSetUnsupportedInstructions( + CirctRtgToolOptions options, unsigned numInstr, + const char **unsupportedInstructions) { + SmallVector instr; + for (unsigned i = 0; i < numInstr; ++i) + instr.push_back(std::string(unsupportedInstructions[i])); + unwrap(options)->setUnsupportedInstructions(std::move(instr)); +} + +void circtRtgToolOptionsAddUnsupportedInstruction( + CirctRtgToolOptions options, const char *unsupportedInstruction) { + unwrap(options)->addUnsupportedInstruction( + std::string(unsupportedInstruction)); +} + +void circtRtgToolOptionsSetUnsupportedInstructionsFile( + CirctRtgToolOptions options, const char *filename) { + unwrap(options)->setUnsupportedInstructionsFile(std::string(filename)); +} + +//===----------------------------------------------------------------------===// +// Pipeline Population API. +//===----------------------------------------------------------------------===// + +void circtRtgToolRandomizerPipeline(MlirPassManager pm, + CirctRtgToolOptions options) { + populateRandomizerPipeline(*unwrap(pm), *unwrap(options)); +} diff --git a/lib/Tools/CMakeLists.txt b/lib/Tools/CMakeLists.txt index aa66538d8bff..90e6c429baa0 100644 --- a/lib/Tools/CMakeLists.txt +++ b/lib/Tools/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(circt-bmc) add_subdirectory(circt-lec) +add_subdirectory(rtgtool) diff --git a/lib/Tools/rtgtool/CMakeLists.txt b/lib/Tools/rtgtool/CMakeLists.txt new file mode 100644 index 000000000000..d8a24bc1e41c --- /dev/null +++ b/lib/Tools/rtgtool/CMakeLists.txt @@ -0,0 +1,10 @@ +add_circt_library(CIRCTRtgToolLib + RtgToolOptions.cpp + + LINK_LIBS PUBLIC + CIRCTSupport + + MLIRIR + MLIRPass + MLIRTransforms +) diff --git a/lib/Tools/rtgtool/RtgToolOptions.cpp b/lib/Tools/rtgtool/RtgToolOptions.cpp new file mode 100644 index 000000000000..0d0076a6d18f --- /dev/null +++ b/lib/Tools/rtgtool/RtgToolOptions.cpp @@ -0,0 +1,35 @@ +//===- RtgToolOptions.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "circt/Tools/rtgtool/RtgToolOptions.h" +#include "circt/Support/Passes.h" +#include "mlir/Transforms/Passes.h" + +using namespace circt; +using namespace circt::rtg; + +//===----------------------------------------------------------------------===// +// RTG Tool Pipelines +//===----------------------------------------------------------------------===// + +void rtg::populateRandomizerPipeline(mlir::PassManager &pm, + const RtgToolOptions &options) { + pm.enableVerifier(options.getVerifyPasses()); + + if (options.getVerbosePassExecution()) + pm.addInstrumentation( + std::make_unique>( + "rtgtool")); + + pm.addPass(createSimpleCanonicalizerPass()); + if (options.getOutputFormat() != RtgToolOptions::OutputFormat::MLIR) { + // TODO: add elaboration pass here + pm.addPass(mlir::createCSEPass()); + pm.addPass(createSimpleCanonicalizerPass()); + } +} diff --git a/test/CAPI/CMakeLists.txt b/test/CAPI/CMakeLists.txt index ba59ddecb483..20a09b422db3 100644 --- a/test/CAPI/CMakeLists.txt +++ b/test/CAPI/CMakeLists.txt @@ -69,3 +69,43 @@ target_link_libraries(circt-capi-arc-test MLIRCAPIIR CIRCTCAPIArc ) + +add_llvm_executable(circt-capi-rtg-pipelines-test + PARTIAL_SOURCES_INTENDED + rtg-pipelines.c +) +llvm_update_compile_flags(circt-capi-rtg-pipelines-test) + +target_link_libraries(circt-capi-rtg-pipelines-test + PRIVATE + + MLIRCAPIIR + CIRCTCAPIRTG + CIRCTCAPIRtgTool +) + +add_llvm_executable(circt-capi-rtg-test + PARTIAL_SOURCES_INTENDED + rtg.c +) +llvm_update_compile_flags(circt-capi-rtg-test) + +target_link_libraries(circt-capi-rtg-test + PRIVATE + + MLIRCAPIIR + CIRCTCAPIRTG +) + +add_llvm_executable(circt-capi-rtgtest-test + PARTIAL_SOURCES_INTENDED + rtgtest.c +) +llvm_update_compile_flags(circt-capi-rtgtest-test) + +target_link_libraries(circt-capi-rtgtest-test + PRIVATE + + MLIRCAPIIR + CIRCTCAPIRTGTest +) diff --git a/test/CAPI/rtg-pipelines.c b/test/CAPI/rtg-pipelines.c new file mode 100644 index 000000000000..9ca801a79410 --- /dev/null +++ b/test/CAPI/rtg-pipelines.c @@ -0,0 +1,56 @@ +//===- rtg-pipelines.c - RTG pipeline CAPI unit tests ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// RUN: circt-capi-rtg-pipelines-test 2>&1 | FileCheck %s + +#include + +#include "circt-c/Dialect/RTG.h" +#include "circt-c/RtgTool.h" + +int main(int argc, char **argv) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleRegisterDialect(mlirGetDialectHandle__rtg__(), ctx); + + MlirModule moduleOp = mlirModuleCreateParse( + ctx, mlirStringRefCreateFromCString("rtg.sequence @seq {\n" + "}\n" + "rtg.test @test : !rtg.dict<> {\n" + " %0 = rtg.sequence_closure @seq\n" + "}\n")); + if (mlirModuleIsNull(moduleOp)) { + printf("ERROR: Could not parse.\n"); + mlirContextDestroy(ctx); + return 1; + } + + MlirPassManager pm = mlirPassManagerCreate(ctx); + CirctRtgToolOptions options = circtRtgToolOptionsCreateDefault(/*seed=*/0); + circtRtgToolRandomizerPipeline(pm, options); + + MlirOperation op = mlirModuleGetOperation(moduleOp); + + if (mlirLogicalResultIsFailure(mlirPassManagerRunOnOp(pm, op))) { + printf("ERROR: Pipeline run failed.\n"); + mlirModuleDestroy(moduleOp); + mlirPassManagerDestroy(pm); + circtRtgToolOptionsDestroy(options); + mlirContextDestroy(ctx); + return 1; + } + + // CHECK-LABEL: rtg.test @test + // CHECK-NEXT: } + mlirOperationDump(op); + + mlirModuleDestroy(moduleOp); + mlirPassManagerDestroy(pm); + circtRtgToolOptionsDestroy(options); + mlirContextDestroy(ctx); + return 0; +} diff --git a/test/CAPI/rtg.c b/test/CAPI/rtg.c new file mode 100644 index 000000000000..aac18f4be43e --- /dev/null +++ b/test/CAPI/rtg.c @@ -0,0 +1,70 @@ +//===- rtg.c - RTG Dialect CAPI unit tests --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// RUN: circt-capi-rtg-test 2>&1 | FileCheck %s + +#include + +#include "circt-c/Dialect/RTG.h" +#include "mlir-c/BuiltinAttributes.h" +#include "mlir-c/BuiltinTypes.h" + +static void testSequenceType(MlirContext ctx) { + MlirType sequenceTy = rtgSequenceTypeGet(ctx); + + // CHECK: is_sequence + fprintf(stderr, rtgTypeIsASequence(sequenceTy) ? "is_sequence\n" + : "isnot_sequence\n"); + // CHECK: !rtg.sequence + mlirTypeDump(sequenceTy); +} + +static void testSetType(MlirContext ctx) { + MlirType elTy = mlirIntegerTypeGet(ctx, 32); + MlirType setTy = rtgSetTypeGet(elTy); + + // CHECK: is_set + fprintf(stderr, rtgTypeIsASet(setTy) ? "is_set\n" : "isnot_set\n"); + // CHECK: !rtg.set + mlirTypeDump(setTy); +} + +static void testDictType(MlirContext ctx) { + MlirType elTy = mlirIntegerTypeGet(ctx, 32); + MlirAttribute name0 = + mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("entry0")); + MlirAttribute name1 = + mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("entry1")); + const MlirAttribute names[] = {name0, name1}; + const MlirType types[] = {elTy, elTy}; + MlirType dictTy = rtgDictTypeGet(ctx, 2, names, types); + + // CHECK: is_dict + fprintf(stderr, rtgTypeIsADict(dictTy) ? "is_dict\n" : "isnot_dict\n"); + // CHECK: !rtg.dict + mlirTypeDump(dictTy); + + MlirType emptyDictTy = rtgDictTypeGet(ctx, 0, NULL, NULL); + // CHECK: is_dict + fprintf(stderr, rtgTypeIsADict(dictTy) ? "is_dict\n" : "isnot_dict\n"); + // CHECK: !rtg.dict<> + mlirTypeDump(emptyDictTy); +} + +int main(int argc, char **argv) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtg__(), ctx); + + testSequenceType(ctx); + testSetType(ctx); + testDictType(ctx); + + mlirContextDestroy(ctx); + + return 0; +} diff --git a/test/CAPI/rtgtest.c b/test/CAPI/rtgtest.c new file mode 100644 index 000000000000..e14f27667a62 --- /dev/null +++ b/test/CAPI/rtgtest.c @@ -0,0 +1,33 @@ +//===- rtgtest.c - RTGTest Dialect CAPI unit tests ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// RUN: circt-capi-rtgtest-test 2>&1 | FileCheck %s + +#include + +#include "circt-c/Dialect/RTGTest.h" + +static void testCPUType(MlirContext ctx) { + MlirType cpuTy = rtgtestCPUTypeGet(ctx); + + // CHECK: is_cpu + fprintf(stderr, rtgtestTypeIsACPU(cpuTy) ? "is_cpu\n" : "isnot_cpu\n"); + // CHECK: !rtgtest.cpu + mlirTypeDump(cpuTy); +} + +int main(int argc, char **argv) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx); + + testCPUType(ctx); + + mlirContextDestroy(ctx); + + return 0; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a4eeda68788e..fa5981cb4b7f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,6 +22,9 @@ set(CIRCT_TEST_DEPENDS circt-capi-om-test circt-capi-firrtl-test circt-capi-firtool-test + circt-capi-rtg-pipelines-test + circt-capi-rtg-test + circt-capi-rtgtest-test circt-as circt-dis circt-lec diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 80042d0221c1..6ff8c38100cd 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -59,9 +59,11 @@ ] tools = [ 'arcilator', 'circt-as', 'circt-capi-ir-test', 'circt-capi-om-test', - 'circt-capi-firrtl-test', 'circt-capi-firtool-test', 'circt-dis', - 'circt-lec', 'circt-reduce', 'circt-synth', 'circt-test', 'circt-translate', - 'firtool', 'hlstool', 'om-linker', 'kanagawatool' + 'circt-capi-firrtl-test', 'circt-capi-firtool-test', + 'circt-capi-rtg-pipelines-test', 'circt-capi-rtg-test', + 'circt-capi-rtgtest-test', 'circt-dis', 'circt-lec', 'circt-reduce', + 'circt-synth', 'circt-test', 'circt-translate', 'firtool', 'hlstool', + 'om-linker', 'kanagawatool' ] if "CIRCT_OPT_CHECK_IR_ROUNDTRIP" in os.environ: From ebf8a7a97b8db0ed25581bb5fb18d5d5b0df0a62 Mon Sep 17 00:00:00 2001 From: Martin Erhart Date: Sun, 24 Nov 2024 13:52:59 +0000 Subject: [PATCH 2/2] [RTG] Add Python Bindings --- .../circt/Dialect/RTGTest/IR/RTGTestOps.td | 1 - .../Bindings/Python/dialects/rtg.py | 79 +++++++++++ lib/Bindings/Python/CIRCTModule.cpp | 22 +++ lib/Bindings/Python/CIRCTModules.h | 5 + lib/Bindings/Python/CMakeLists.txt | 92 +++++++++---- lib/Bindings/Python/RTGModule.cpp | 60 +++++++++ lib/Bindings/Python/RTGTestModule.cpp | 34 +++++ lib/Bindings/Python/RTGToolModule.cpp | 125 ++++++++++++++++++ lib/Bindings/Python/dialects/RTGOps.td | 14 ++ lib/Bindings/Python/dialects/RTGTestOps.td | 14 ++ lib/Bindings/Python/dialects/rtg.py | 6 + lib/Bindings/Python/dialects/rtgtest.py | 6 + lib/Bindings/Python/rtgtool_support.py | 5 + 13 files changed, 435 insertions(+), 28 deletions(-) create mode 100644 integration_test/Bindings/Python/dialects/rtg.py create mode 100644 lib/Bindings/Python/RTGModule.cpp create mode 100644 lib/Bindings/Python/RTGTestModule.cpp create mode 100644 lib/Bindings/Python/RTGToolModule.cpp create mode 100644 lib/Bindings/Python/dialects/RTGOps.td create mode 100644 lib/Bindings/Python/dialects/RTGTestOps.td create mode 100644 lib/Bindings/Python/dialects/rtg.py create mode 100644 lib/Bindings/Python/dialects/rtgtest.py create mode 100644 lib/Bindings/Python/rtgtool_support.py diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestOps.td b/include/circt/Dialect/RTGTest/IR/RTGTestOps.td index e64f6c8ac21e..697cf6c38571 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestOps.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTestOps.td @@ -20,7 +20,6 @@ class RTGTestOp traits = []> : def CPUDeclOp : RTGTestOp<"cpu_decl", [ Pure, - ConstantLike, ContextResourceDefining, ]> { let summary = "declare a CPU"; diff --git a/integration_test/Bindings/Python/dialects/rtg.py b/integration_test/Bindings/Python/dialects/rtg.py new file mode 100644 index 000000000000..c840d8fa941f --- /dev/null +++ b/integration_test/Bindings/Python/dialects/rtg.py @@ -0,0 +1,79 @@ +# REQUIRES: bindings_python +# RUN: %PYTHON% %s | FileCheck %s + +import circt + +from circt.dialects import rtg, rtgtest +from circt.ir import Context, Location, Module, InsertionPoint, Block, StringAttr, TypeAttr +from circt.passmanager import PassManager +from circt import rtgtool_support as rtgtool + +with Context() as ctx, Location.unknown(): + circt.register_dialects(ctx) + m = Module.create() + with InsertionPoint(m.body): + cpuTy = rtgtest.CPUType.get() + dictTy = rtg.DictType.get(ctx, [(StringAttr.get('cpu0'), cpuTy), + (StringAttr.get('cpu1'), cpuTy)]) + + target = rtg.TargetOp('target_name', TypeAttr.get(dictTy)) + targetBlock = Block.create_at_start(target.bodyRegion, []) + with InsertionPoint(targetBlock): + cpu0 = rtgtest.CPUDeclOp(cpuTy, 0) + cpu1 = rtgtest.CPUDeclOp(cpuTy, 1) + rtg.YieldOp([cpu0, cpu1]) + + test = rtg.TestOp('test_name', TypeAttr.get(dictTy)) + Block.create_at_start(test.bodyRegion, [cpuTy, cpuTy]) + + # CHECK: rtg.target @target_name : !rtg.dict { + # CHECK: [[V0:%.+]] = rtgtest.cpu_decl 0 + # CHECK: [[V1:%.+]] = rtgtest.cpu_decl 1 + # CHECK: rtg.yield [[V0]], [[V1]] : !rtgtest.cpu, !rtgtest.cpu + # CHECK: } + # CHECK: rtg.test @test_name : !rtg.dict { + # CHECK: ^bb{{.*}}(%{{.*}}: !rtgtest.cpu, %{{.*}}: !rtgtest.cpu): + # CHECK: } + print(m) + +with Context() as ctx, Location.unknown(): + circt.register_dialects(ctx) + m = Module.create() + with InsertionPoint(m.body): + seq = rtg.SequenceOp('seq') + setTy = rtg.SetType.get(rtg.SequenceType.get()) + seqBlock = Block.create_at_start(seq.bodyRegion, [setTy]) + + # CHECK: rtg.sequence @seq { + # CHECK: ^bb{{.*}}(%{{.*}}: !rtg.set): + # CHECK: } + print(m) + +with Context() as ctx, Location.unknown(): + circt.register_dialects(ctx) + m = Module.create() + with InsertionPoint(m.body): + seq = rtg.SequenceOp('sequence_name') + Block.create_at_start(seq.bodyRegion, []) + + test = rtg.TestOp('test_name', TypeAttr.get(rtg.DictType.get())) + block = Block.create_at_start(test.bodyRegion, []) + with InsertionPoint(block): + seq_closure = rtg.SequenceClosureOp('sequence_name', []) + + # CHECK: rtg.test @test_name : !rtg.dict<> { + # CHECK-NEXT: rtg.sequence_closure + # CHECK-NEXT: } + print(m) + + pm = PassManager() + options = rtgtool.Options( + seed=0, + output_format=rtgtool.OutputFormat.ELABORATED_MLIR, + ) + rtgtool.populate_randomizer_pipeline(pm, options) + pm.run(m.operation) + + # CHECK: rtg.test @test_name : !rtg.dict<> { + # CHECK-NEXT: } + print(m) diff --git a/lib/Bindings/Python/CIRCTModule.cpp b/lib/Bindings/Python/CIRCTModule.cpp index db308e759e85..e24981bbd06a 100644 --- a/lib/Bindings/Python/CIRCTModule.cpp +++ b/lib/Bindings/Python/CIRCTModule.cpp @@ -22,6 +22,10 @@ #include "circt-c/Dialect/LTL.h" #include "circt-c/Dialect/MSFT.h" #include "circt-c/Dialect/OM.h" +#include "circt-c/Dialect/RTG.h" +#ifdef CIRCT_INCLUDE_TESTS +#include "circt-c/Dialect/RTGTest.h" +#endif #include "circt-c/Dialect/SV.h" #include "circt-c/Dialect/Seq.h" #include "circt-c/Dialect/Verif.h" @@ -98,6 +102,16 @@ PYBIND11_MODULE(_circt, m) { mlirDialectHandleRegisterDialect(om, context); mlirDialectHandleLoadDialect(om, context); + MlirDialectHandle rtg = mlirGetDialectHandle__rtg__(); + mlirDialectHandleRegisterDialect(rtg, context); + mlirDialectHandleLoadDialect(rtg, context); + +#ifdef CIRCT_INCLUDE_TESTS + MlirDialectHandle rtgtest = mlirGetDialectHandle__rtgtest__(); + mlirDialectHandleRegisterDialect(rtgtest, context); + mlirDialectHandleLoadDialect(rtgtest, context); +#endif + MlirDialectHandle seq = mlirGetDialectHandle__seq__(); mlirDialectHandleRegisterDialect(seq, context); mlirDialectHandleLoadDialect(seq, context); @@ -145,6 +159,14 @@ PYBIND11_MODULE(_circt, m) { circt::python::populateDialectSeqSubmodule(seq); py::module om = m.def_submodule("_om", "OM API"); circt::python::populateDialectOMSubmodule(om); + py::module rtg = m.def_submodule("_rtg", "RTG API"); + circt::python::populateDialectRTGSubmodule(rtg); + py::module rtgtool = m.def_submodule("_rtgtool", "RTGTool API"); + circt::python::populateDialectRTGToolSubmodule(rtgtool); +#ifdef CIRCT_INCLUDE_TESTS + py::module rtgtest = m.def_submodule("_rtgtest", "RTGTest API"); + circt::python::populateDialectRTGTestSubmodule(rtgtest); +#endif py::module sv = m.def_submodule("_sv", "SV API"); circt::python::populateDialectSVSubmodule(sv); py::module support = m.def_submodule("_support", "CIRCT support"); diff --git a/lib/Bindings/Python/CIRCTModules.h b/lib/Bindings/Python/CIRCTModules.h index 230b36c864f9..a082a8445e5c 100644 --- a/lib/Bindings/Python/CIRCTModules.h +++ b/lib/Bindings/Python/CIRCTModules.h @@ -22,6 +22,11 @@ void populateDialectESISubmodule(pybind11::module &m); void populateDialectHWSubmodule(pybind11::module &m); void populateDialectMSFTSubmodule(pybind11::module &m); void populateDialectOMSubmodule(pybind11::module &m); +void populateDialectRTGSubmodule(pybind11::module &m); +void populateDialectRTGToolSubmodule(pybind11::module &m); +#ifdef CIRCT_INCLUDE_TESTS +void populateDialectRTGTestSubmodule(pybind11::module &m); +#endif void populateDialectSeqSubmodule(pybind11::module &m); void populateDialectSVSubmodule(pybind11::module &m); void populateSupportSubmodule(pybind11::module &m); diff --git a/lib/Bindings/Python/CMakeLists.txt b/lib/Bindings/Python/CMakeLists.txt index 4319f91fc407..c665fa8e3256 100644 --- a/lib/Bindings/Python/CMakeLists.txt +++ b/lib/Bindings/Python/CMakeLists.txt @@ -9,39 +9,58 @@ add_compile_definitions("MLIR_PYTHON_PACKAGE_PREFIX=circt.") ################################################################################ # Declare native Python extension ################################################################################ +set(LLVM_OPTIONAL_SOURCES + RTGTestModule.cpp +) + +set(PYTHON_BINDINGS_SOURCES + CIRCTModule.cpp + ESIModule.cpp + HWModule.cpp + MSFTModule.cpp + OMModule.cpp + RTGModule.cpp + RTGToolModule.cpp + SeqModule.cpp + SupportModule.cpp + SVModule.cpp +) + +set(PYTHON_BINDINGS_LINK_LIBS + CIRCTCAPIArc + CIRCTCAPIComb + CIRCTCAPIConversion + CIRCTCAPIDC + CIRCTCAPIDebug + CIRCTCAPIEmit + CIRCTCAPIESI + CIRCTCAPIExportVerilog + CIRCTCAPIFSM + CIRCTCAPIHandshake + CIRCTCAPIHW + CIRCTCAPIHWArith + CIRCTCAPILTL + CIRCTCAPIMSFT + CIRCTCAPIOM + CIRCTCAPIRTG + CIRCTCAPIRtgTool + CIRCTCAPISeq + CIRCTCAPISV + CIRCTCAPIVerif + MLIRCAPITransforms +) +if (CIRCT_INCLUDE_TESTS) + list(APPEND PYTHON_BINDINGS_SOURCES RTGTestModule.cpp) + list(APPEND PYTHON_BINDINGS_LINK_LIBS CIRCTCAPIRTGTest) +endif() declare_mlir_python_extension(CIRCTBindingsPythonExtension MODULE_NAME _circt SOURCES - CIRCTModule.cpp - ESIModule.cpp - HWModule.cpp - OMModule.cpp - MSFTModule.cpp - SeqModule.cpp - SupportModule.cpp - SVModule.cpp + ${PYTHON_BINDINGS_SOURCES} EMBED_CAPI_LINK_LIBS - CIRCTCAPIArc - CIRCTCAPIComb - CIRCTCAPIDC - CIRCTCAPIDebug - CIRCTCAPIEmit - CIRCTCAPIESI - CIRCTCAPIExportVerilog - CIRCTCAPIFSM - CIRCTCAPIHW - CIRCTCAPIHWArith - CIRCTCAPIHandshake - CIRCTCAPILTL - CIRCTCAPIMSFT - CIRCTCAPIOM - CIRCTCAPISV - CIRCTCAPISeq - CIRCTCAPIVerif - CIRCTCAPIConversion - MLIRCAPITransforms + ${PYTHON_BINDINGS_LINK_LIBS} PRIVATE_LINK_LIBS LLVMSupport ) @@ -57,6 +76,7 @@ declare_mlir_python_sources(CIRCTBindingsPythonSources SOURCES __init__.py support.py + rtgtool_support.py ) ################################################################################ @@ -126,6 +146,24 @@ declare_mlir_dialect_python_bindings( dialects/om.py DIALECT_NAME om) +declare_mlir_dialect_python_bindings( + ADD_TO_PARENT CIRCTBindingsPythonSources.Dialects + ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + TD_FILE dialects/RTGOps.td + SOURCES + dialects/rtg.py + DIALECT_NAME rtg) + +if (CIRCT_INCLUDE_TESTS) + declare_mlir_dialect_python_bindings( + ADD_TO_PARENT CIRCTBindingsPythonSources.Dialects + ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + TD_FILE dialects/RTGTestOps.td + SOURCES + dialects/rtgtest.py + DIALECT_NAME rtgtest) +endif() + declare_mlir_dialect_python_bindings( ADD_TO_PARENT CIRCTBindingsPythonSources.Dialects ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" diff --git a/lib/Bindings/Python/RTGModule.cpp b/lib/Bindings/Python/RTGModule.cpp new file mode 100644 index 000000000000..452332ab585d --- /dev/null +++ b/lib/Bindings/Python/RTGModule.cpp @@ -0,0 +1,60 @@ +//===- RTGModule.cpp - RTG API pybind module ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CIRCTModules.h" + +#include "circt-c/Dialect/RTG.h" + +#include "mlir/Bindings/Python/PybindAdaptors.h" + +#include +#include +#include +namespace py = pybind11; + +using namespace circt; +using namespace mlir::python::adaptors; + +/// Populate the rtg python module. +void circt::python::populateDialectRTGSubmodule(py::module &m) { + m.doc() = "RTG dialect Python native extension"; + + mlir_type_subclass(m, "SequenceType", rtgTypeIsASequence) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgSequenceTypeGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_type_subclass(m, "SetType", rtgTypeIsASet) + .def_classmethod( + "get", + [](py::object cls, MlirType elementType) { + return cls(rtgSetTypeGet(elementType)); + }, + py::arg("self"), py::arg("element_type")); + + mlir_type_subclass(m, "DictType", rtgTypeIsADict) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt, + const std::vector> &entries) { + std::vector names; + std::vector types; + for (auto entry : entries) { + names.push_back(entry.first); + types.push_back(entry.second); + } + return cls( + rtgDictTypeGet(ctxt, types.size(), names.data(), types.data())); + }, + py::arg("self"), py::arg("ctxt") = nullptr, + py::arg("entries") = + std::vector>()); +} diff --git a/lib/Bindings/Python/RTGTestModule.cpp b/lib/Bindings/Python/RTGTestModule.cpp new file mode 100644 index 000000000000..b2c2e496ac75 --- /dev/null +++ b/lib/Bindings/Python/RTGTestModule.cpp @@ -0,0 +1,34 @@ +//===- RTGTestModule.cpp - RTGTest API pybind module ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CIRCTModules.h" + +#include "circt-c/Dialect/RTGTest.h" + +#include "mlir/Bindings/Python/PybindAdaptors.h" + +#include +#include +#include +namespace py = pybind11; + +using namespace circt; +using namespace mlir::python::adaptors; + +/// Populate the rtgtest python module. +void circt::python::populateDialectRTGTestSubmodule(py::module &m) { + m.doc() = "RTGTest dialect Python native extension"; + + mlir_type_subclass(m, "CPUType", rtgtestTypeIsACPU) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestCPUTypeGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); +} diff --git a/lib/Bindings/Python/RTGToolModule.cpp b/lib/Bindings/Python/RTGToolModule.cpp new file mode 100644 index 000000000000..06d25c506d80 --- /dev/null +++ b/lib/Bindings/Python/RTGToolModule.cpp @@ -0,0 +1,125 @@ +//===- RTGToolModule.cpp - RTG Tool API pybind module ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CIRCTModules.h" + +#include "circt-c/RtgTool.h" + +#include "mlir/Bindings/Python/PybindAdaptors.h" + +#include +#include +#include +namespace py = pybind11; + +using namespace circt; + +namespace { +/// Wrapper around an CirctRtgToolOptions. +class PyRtgToolOptions { +public: + PyRtgToolOptions(unsigned seed, CirctRtgToolOutputFormat outputFormat, + bool verifyPasses, bool verbosePassExecution, + const std::vector &unsupportedInstructions, + const std::string &unsupportedInstructionsFile) + : options(circtRtgToolOptionsCreateDefault(seed)) { + setOutputFormat(outputFormat); + setVerifyPasses(verifyPasses); + setVerbosePassExecution(verbosePassExecution); + setUnsupportedInstructions(unsupportedInstructions); + setUnsupportedInstructionsFile(unsupportedInstructionsFile); + } + ~PyRtgToolOptions() { circtRtgToolOptionsDestroy(options); } + + operator CirctRtgToolOptions() const { return options; } + CirctRtgToolOptions get() const { return options; } + + void setOutputFormat(CirctRtgToolOutputFormat format) { + circtRtgToolOptionsSetOutputFormat(options, format); + } + + void setSeed(unsigned seed) { circtRtgToolOptionsSetSeed(options, seed); } + + void setVerifyPasses(bool enable) { + circtRtgToolOptionsSetVerifyPasses(options, enable); + } + + void setVerbosePassExecution(bool enable) { + circtRtgToolOptionsSetVerbosePassExecution(options, enable); + } + + void + setUnsupportedInstructions(const std::vector &instructions) { + circtRtgToolOptionsSetUnsupportedInstructions( + options, instructions.size(), + const_cast(instructions.data())); + } + + void addUnsupportedInstruction(const std::string &instruction) { + circtRtgToolOptionsAddUnsupportedInstruction(options, instruction.c_str()); + } + + void setUnsupportedInstructionsFile(const std::string &filename) { + circtRtgToolOptionsSetUnsupportedInstructionsFile(options, + filename.c_str()); + } + +private: + CirctRtgToolOptions options; +}; +} // namespace + +/// Populate the rtgtool python module. +void circt::python::populateDialectRTGToolSubmodule(py::module &m) { + m.doc() = "RTGTool Python native extension"; + + py::enum_(m, "OutputFormat") + .value("MLIR", CIRCT_RTGTOOL_OUTPUT_FORMAT_MLIR) + .value("ELABORATED_MLIR", CIRCT_RTGTOOL_OUTPUT_FORMAT_ELABORATED_MLIR) + .value("ASM", CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM); + + py::class_(m, "Options") + .def(py::init &, const std::string &>(), + py::arg("seed"), + py::arg("output_format") = CIRCT_RTGTOOL_OUTPUT_FORMAT_ASM, + py::arg("verify_passes") = true, + py::arg("verbose_pass_execution") = false, + py::arg("unsupported_instructions") = std::vector(), + py::arg("unsupported_instructions_file") = "") + .def("set_output_format", &PyRtgToolOptions::setOutputFormat, + "Specify the output format of the tool", py::arg("format")) + .def("set_seed", &PyRtgToolOptions::setSeed, + "Specify the seed for all RNGs used in the tool", py::arg("seed")) + .def("set_verify_passes", &PyRtgToolOptions::setVerifyPasses, + "Specify whether the verifiers should be run after each pass", + py::arg("enable")) + .def("set_verbose_pass_execution", + &PyRtgToolOptions::setVerbosePassExecution, + "Specify whether passes should run in verbose mode", + py::arg("enable")) + .def("set_unsupported_instructions", + &PyRtgToolOptions::setUnsupportedInstructions, + "Set the list of of instructions unsupported by the assembler", + py::arg("instructions")) + .def("add_unsupported_instruction", + &PyRtgToolOptions::addUnsupportedInstruction, + "Add the instruction given by name to the list of instructions not " + "supported by the assembler", + py::arg("instruction_name")) + .def("set_unsupported_instructions_file", + &PyRtgToolOptions::setUnsupportedInstructionsFile, + "Register a file containing a comma-separated list of instruction " + "names which are not supported by the assembler.", + py::arg("filename")); + + m.def("populate_randomizer_pipeline", + [](MlirPassManager pm, const PyRtgToolOptions &options) { + circtRtgToolRandomizerPipeline(pm, options.get()); + }); +} diff --git a/lib/Bindings/Python/dialects/RTGOps.td b/lib/Bindings/Python/dialects/RTGOps.td new file mode 100644 index 000000000000..aadcbdb8887a --- /dev/null +++ b/lib/Bindings/Python/dialects/RTGOps.td @@ -0,0 +1,14 @@ +//===- RTGOps.td - Entry point for RTG bindings ------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef BINDINGS_PYTHON_RTG_OPS +#define BINDINGS_PYTHON_RTG_OPS + +include "circt/Dialect/RTG/IR/RTG.td" + +#endif // BINDINGS_PYTHON_RTG_OPS diff --git a/lib/Bindings/Python/dialects/RTGTestOps.td b/lib/Bindings/Python/dialects/RTGTestOps.td new file mode 100644 index 000000000000..b7c0ac0d671e --- /dev/null +++ b/lib/Bindings/Python/dialects/RTGTestOps.td @@ -0,0 +1,14 @@ +//===- RTGTestOps.td - Entry point for RTGTest bindings ----*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef BINDINGS_PYTHON_RTGTEST_OPS +#define BINDINGS_PYTHON_RTGTEST_OPS + +include "circt/Dialect/RTGTest/IR/RTGTest.td" + +#endif // BINDINGS_PYTHON_RTGTEST_OPS diff --git a/lib/Bindings/Python/dialects/rtg.py b/lib/Bindings/Python/dialects/rtg.py new file mode 100644 index 000000000000..b615bffe963a --- /dev/null +++ b/lib/Bindings/Python/dialects/rtg.py @@ -0,0 +1,6 @@ +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +from ._rtg_ops_gen import * +from .._mlir_libs._circt._rtg import * diff --git a/lib/Bindings/Python/dialects/rtgtest.py b/lib/Bindings/Python/dialects/rtgtest.py new file mode 100644 index 000000000000..cfc6167bd6f4 --- /dev/null +++ b/lib/Bindings/Python/dialects/rtgtest.py @@ -0,0 +1,6 @@ +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +from ._rtgtest_ops_gen import * +from .._mlir_libs._circt._rtgtest import * diff --git a/lib/Bindings/Python/rtgtool_support.py b/lib/Bindings/Python/rtgtool_support.py new file mode 100644 index 000000000000..4a1fff5d84bc --- /dev/null +++ b/lib/Bindings/Python/rtgtool_support.py @@ -0,0 +1,5 @@ +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +from ._mlir_libs._circt._rtgtool import *