14#include "mlir-c/Bindings/Python/Interop.h"
16#include "mlir/Bindings/Python/NanobindAdaptors.h"
17#include "mlir/CAPI/IR.h"
18#include "mlir/CAPI/Support.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallVector.h"
24#include <nanobind/nanobind.h>
38 MlirLogicalResult
run(MlirOperation reqOp, MlirOperation declOp,
39 MlirOperation recOp) {
40 nb::gil_scoped_acquire acquire;
41 nb::object rc =
genFunc(reqOp, declOp, recOp);
42 return nb::cast<bool>(rc) ? mlirLogicalResultSuccess()
43 : mlirLogicalResultFailure();
55 MlirOperation recOp,
void *userData) {
56 std::string *name =
static_cast<std::string *
>(userData);
59 return mlirLogicalResultFailure();
60 return iter->getSecond().run(reqOp, declOp, recOp);
64 std::string *n =
new std::string(name);
80 MlirLocation loc)
const {
83 if (path.ptr ==
nullptr)
85 return nb::cast(path);
92using namespace mlir::python::nanobind_adaptors;
95 m.doc() =
"ESI Python Native Extension";
100 m.def(
"cleanup", cleanup,
101 "Cleanup various references. Must be called before the module is "
102 "unloaded in order to not leak.");
105 "Register a service generator for a given service name.",
106 nb::arg(
"impl_type"), nb::arg(
"generator"));
111 [](nb::object cls, MlirType inner, uint32_t signaling = 0,
112 uint64_t dataDelay = 0) {
117 nb::arg(
"cls"), nb::arg(
"inner"), nb::arg(
"signaling") = 0,
118 nb::arg(
"dataDelay") = 0)
119 .def_property_readonly(
121 .def_property_readonly(
124 .def_property_readonly(
"data_delay", [](MlirType self) {
131 [](nb::object cls, MlirContext ctxt) {
134 nb::arg(
"self"), nb::arg(
"ctxt") =
nullptr);
139 [](nb::object cls, MlirType inner) {
142 nb::arg(
"cls"), nb::arg(
"inner"))
143 .def_property_readonly(
"element_type", [](MlirType self) {
147 nb::enum_<ChannelDirection>(m,
"ChannelDirection")
148 .value(
"TO", ChannelDirection::to)
149 .value(
"FROM", ChannelDirection::from);
153 [](nb::object cls, std::vector<nb::tuple> channelTuples,
154 bool resettable, MlirContext ctxt) {
155 llvm::SmallVector<CirctESIBundleTypeBundleChannel, 4> channels(
156 llvm::map_range(channelTuples, [ctxt](nb::tuple t) {
157 std::string name = nb::cast<std::string>(t[0]);
159 mlirIdentifierGet(ctxt, mlirStringRefCreate(
160 name.data(), name.length())),
161 (uint32_t)nb::cast<ChannelDirection>(t[1]),
162 nb::cast<MlirType>(t[2])};
165 channels.data(), resettable));
167 nb::arg(
"cls"), nb::arg(
"channels"), nb::arg(
"resettable"),
168 nb::arg(
"ctxt") =
nullptr)
170 .def_property_readonly(
"channels", [](MlirType bundleType) {
171 std::vector<nb::tuple> channels;
173 for (
size_t i = 0; i < numChannels; ++i) {
176 MlirStringRef name = mlirIdentifierStr(channel.
name);
177 channels.push_back(nb::make_tuple(nb::str(name.data, name.length),
187 [](nb::object cls, std::string name, std::optional<uint64_t> index,
189 if (index.has_value())
193 "Create an AppID attribute", nb::arg(
"cls"), nb::arg(
"name"),
194 nb::arg(
"index") = nb::none(), nb::arg(
"context") = nb::none())
195 .def_property_readonly(
"name",
196 [](MlirAttribute self) {
197 llvm::StringRef name =
199 return std::string(name.data(), name.size());
201 .def_property_readonly(
"index", [](MlirAttribute self) -> nb::object {
204 return nb::cast(index);
208 mlir_attribute_subclass(m,
"AppIDPathAttr",
212 [](nb::object cls, MlirAttribute root,
213 std::vector<MlirAttribute> path, MlirContext ctxt) {
217 "Create an AppIDPath attribute", nb::arg(
"cls"), nb::arg(
"root"),
218 nb::arg(
"path"), nb::arg(
"context") = nb::none())
224 "Check that two types match, allowing for AnyType in 'expected'.",
225 nb::arg(
"expected"), nb::arg(
"actual"));
227 nb::class_<PyAppIDIndex>(m,
"AppIDIndex")
228 .def(nb::init<MlirOperation>(), nb::arg(
"root"))
230 "Return a dictionary of AppIDAttrs to ArrayAttr of InnerRefAttrs "
231 "containing the relative paths to the leaf of the particular "
232 "AppIDAttr. Argument MUST be HWModuleLike.",
235 "Return an array of InnerNameRefAttrs representing the relative "
236 "path to 'appid' from 'fromMod'.",
237 nb::arg(
"from_mod"), nb::arg(
"appid"),
238 nb::arg(
"query_site") = nb::none());
return wrap(CMemoryType::get(unwrap(ctx), baseType, numElements))
static MlirLogicalResult serviceGenFunc(MlirOperation reqOp, MlirOperation declOp, MlirOperation recOp, void *userData)
void registerServiceGenerator(std::string name, nb::object genFunc)
llvm::DenseMap< std::string *, ServiceGenFunc > serviceGenFuncLookup
MLIR_CAPI_EXPORTED uint32_t circtESIChannelGetSignaling(MlirType channelType)
MLIR_CAPI_EXPORTED MlirType circtESIBundleTypeGet(MlirContext, size_t numChannels, const CirctESIBundleTypeBundleChannel *channels, bool resettable)
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDAttrGet(MlirContext, MlirStringRef name, uint64_t index)
MLIR_CAPI_EXPORTED bool circtESIBundleTypeGetResettable(MlirType bundle)
MLIR_CAPI_EXPORTED bool circtESITypeIsAnAnyType(MlirType type)
MLIR_CAPI_EXPORTED void circtESIRegisterGlobalServiceGenerator(MlirStringRef impl_type, CirctESIServiceGeneratorFunc, void *userData)
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDIndexGetChildAppIDsOf(CirctESIAppIDIndex, MlirOperation)
MLIR_CAPI_EXPORTED MlirType circtESIChannelGetInner(MlirType channelType)
MLIR_CAPI_EXPORTED CirctESIBundleTypeBundleChannel circtESIBundleTypeGetChannel(MlirType bundle, size_t idx)
MLIR_CAPI_EXPORTED void circtESIAppIDIndexFree(CirctESIAppIDIndex)
Free an AppIDIndex.
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDAttrGetNoIdx(MlirContext ctxt, MlirStringRef name)
MLIR_CAPI_EXPORTED uint64_t circtESIAppIDAttrPathGetNumComponents(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDIndexGetAppIDPath(CirctESIAppIDIndex, MlirOperation fromMod, MlirAttribute appid, MlirLocation loc)
MLIR_CAPI_EXPORTED MlirStringRef circtESIAppIDAttrGetName(MlirAttribute attr)
MLIR_CAPI_EXPORTED MlirType circtESIChannelTypeGet(MlirType inner, uint32_t signaling, uint64_t dataDelay)
MLIR_CAPI_EXPORTED bool circtESITypeIsAChannelType(MlirType type)
MLIR_CAPI_EXPORTED size_t circtESIBundleTypeGetNumChannels(MlirType bundle)
MLIR_CAPI_EXPORTED MlirType circtESIListTypeGetElementType(MlirType channelType)
MLIR_CAPI_EXPORTED MlirType circtESIAnyTypeGet(MlirContext)
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDAttrPathGetComponent(MlirAttribute attr, uint64_t index)
MLIR_CAPI_EXPORTED uint64_t circtESIChannelGetDataDelay(MlirType channelType)
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDAttrPathGet(MlirContext, MlirAttribute root, intptr_t numElements, MlirAttribute const *elements)
MLIR_CAPI_EXPORTED MlirType circtESIListTypeGet(MlirType inner)
MLIR_CAPI_EXPORTED bool circtESITypeIsABundleType(MlirType type)
MLIR_CAPI_EXPORTED bool circtESIAppIDAttrGetIndex(MlirAttribute attr, uint64_t *index)
MLIR_CAPI_EXPORTED bool circtESICheckInnerTypeMatch(MlirType to, MlirType from)
MLIR_CAPI_EXPORTED MlirAttribute circtESIAppIDAttrPathGetRoot(MlirAttribute attr)
MLIR_CAPI_EXPORTED bool circtESIAttributeIsAnAppIDPathAttr(MlirAttribute)
MLIR_CAPI_EXPORTED CirctESIAppIDIndex circtESIAppIDIndexGet(MlirOperation root)
Create an index of appids through which to do appid lookups efficiently.
MLIR_CAPI_EXPORTED bool circtESIAttributeIsAnAppIDAttr(MlirAttribute)
MLIR_CAPI_EXPORTED bool circtESITypeIsAListType(MlirType type)
static EvaluatorValuePtr unwrap(OMEvaluatorValue c)
PyAppIDIndex(const PyAppIDIndex &)=delete
PyAppIDIndex(MlirOperation root)
nb::object getAppIDPathAttr(MlirOperation fromMod, MlirAttribute appid, MlirLocation loc) const
MlirAttribute getChildAppIDsOf(MlirOperation op) const
Container for a Python function that will be called to generate a service.
MlirLogicalResult run(MlirOperation reqOp, MlirOperation declOp, MlirOperation recOp)
ServiceGenFunc(nb::object genFunc)
void populateDialectESISubmodule(nanobind::module_ &m)