diff --git a/mlir/include/mlir-c/Dialect/Transform.h b/mlir/include/mlir-c/Dialect/Transform.h new file mode 100644 --- /dev/null +++ b/mlir/include/mlir-c/Dialect/Transform.h @@ -0,0 +1,46 @@ +//===-- mlir-c/Dialect/Transform.h - C API for Transform 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 MLIR_C_DIALECT_TRANSFORM_H +#define MLIR_C_DIALECT_TRANSFORM_H + +#include "mlir-c/IR.h" +#include "mlir-c/Support.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(Transform, transform); + +//===---------------------------------------------------------------------===// +// AnyOpType +//===---------------------------------------------------------------------===// + +MLIR_CAPI_EXPORTED bool mlirTypeIsATransformAnyOpType(MlirType type); + +MLIR_CAPI_EXPORTED MlirType mlirTransformAnyOpTypeGet(MlirContext ctx); + +//===---------------------------------------------------------------------===// +// OperationType +//===---------------------------------------------------------------------===// + +MLIR_CAPI_EXPORTED bool mlirTypeIsATransformOperationType(MlirType type); + +MLIR_CAPI_EXPORTED MlirType +mlirTransformOperationTypeGet(MlirContext ctx, MlirStringRef operationName); + +MLIR_CAPI_EXPORTED MlirStringRef +mlirTransformOperationTypeGetOperationName(MlirType type); + +#ifdef __cplusplus +} +#endif + +#endif // MLIR_C_DIALECT_TRANSFORM_H diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td b/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td --- a/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.td @@ -359,6 +359,8 @@ /// mnemonic. [[noreturn]] void reportDuplicateTypeRegistration(StringRef mnemonic); + void initializeTypes(); + template friend class TransformDialectExtension; diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.td b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.td --- a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.td @@ -104,6 +104,13 @@ "::mlir::ArrayRef<::mlir::Operation *>":$payload) > ]; + + let extraSharedClassDeclaration = [{ + DiagnosedSilenceableFailure emitSilenceableError(Location loc) const { + Diagnostic diag(loc, DiagnosticSeverity::Error); + return DiagnosedSilenceableFailure::silenceableFailure(std::move(diag)); + } + }]; } def FunctionalStyleTransformOpTrait diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.td b/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.td --- a/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.td +++ b/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.td @@ -23,4 +23,24 @@ let assemblyFormat = ""; } +def Transform_OperationType : TypeDef]> { + let description = [{ + Transform IR handle that can be associated with a list of Payload IR + operations with the specified operation name. + }]; + let mnemonic = "op"; + let parameters = (ins + StringRefParameter<"Name of the allowed payload operation">:$operation_name + ); + let assemblyFormat = "`<` $operation_name `>`"; +} + +class Transform_ConcreteOpType + : Type()" + ".getOperationName() == \"" # opname # "\"">]>, + "Transform IR handle to " # opname # " operations", + "::mlir::transform::OperationType">; + #endif // MLIR_DIALECT_TRANSFORM_IR_TRANSFORMTYPES diff --git a/mlir/lib/Bindings/Python/DialectTransform.cpp b/mlir/lib/Bindings/Python/DialectTransform.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/Bindings/Python/DialectTransform.cpp @@ -0,0 +1,64 @@ +//===- DialectTransform.cpp - 'transform' dialect submodule ---------------===// +// +// 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 "mlir-c/Dialect/Transform.h" +#include "mlir-c/IR.h" +#include "mlir-c/Support.h" +#include "mlir/Bindings/Python/PybindAdaptors.h" + +namespace py = pybind11; +using namespace mlir; +using namespace mlir::python; +using namespace mlir::python::adaptors; + +void populateDialectTransformSubmodule(const pybind11::module &m) { + //===-------------------------------------------------------------------===// + // AnyOpType + //===-------------------------------------------------------------------===// + + auto anyOpType = + mlir_type_subclass(m, "AnyOpType", mlirTypeIsATransformAnyOpType); + anyOpType.def_classmethod( + "get", + [](py::object cls, MlirContext ctx) { + return cls(mlirTransformAnyOpTypeGet(ctx)); + }, + "Get an instance of AnyOpType in the given context.", py::arg("cls"), + py::arg("context") = py::none()); + + //===-------------------------------------------------------------------===// + // OperationType + //===-------------------------------------------------------------------===// + + auto operationType = + mlir_type_subclass(m, "OperationType", mlirTypeIsATransformOperationType); + operationType.def_classmethod( + "get", + [](py::object cls, const std::string &operationName, MlirContext ctx) { + MlirStringRef cOperationName = + mlirStringRefCreate(operationName.data(), operationName.size()); + return cls(mlirTransformOperationTypeGet(ctx, cOperationName)); + }, + "Get an instance of OperationType for the given kind in the given " + "context", + py::arg("cls"), py::arg("operation_name"), + py::arg("context") = py::none()); + operationType.def_property_readonly( + "operation_name", + [](MlirType type) { + MlirStringRef operationName = + mlirTransformOperationTypeGetOperationName(type); + return py::str(operationName.data, operationName.length); + }, + "Get the name of the payload operation accepted by the handle."); +} + +PYBIND11_MODULE(_mlirDialectsTransform, m) { + m.doc() = "MLIR Transform dialect."; + populateDialectTransformSubmodule(m); +} diff --git a/mlir/lib/CAPI/Dialect/CMakeLists.txt b/mlir/lib/CAPI/Dialect/CMakeLists.txt --- a/mlir/lib/CAPI/Dialect/CMakeLists.txt +++ b/mlir/lib/CAPI/Dialect/CMakeLists.txt @@ -116,6 +116,15 @@ MLIRTensorDialect ) +add_mlir_upstream_c_api_library(MLIRCAPITransformDialect + Transform.cpp + + PARTIAL_SOURCES_INTENDED + LINK_LIBS PUBLIC + MLIRCAPIIR + MLIRTransformDialect +) + add_mlir_upstream_c_api_library(MLIRCAPIQuant Quant.cpp diff --git a/mlir/lib/CAPI/Dialect/Transform.cpp b/mlir/lib/CAPI/Dialect/Transform.cpp new file mode 100644 --- /dev/null +++ b/mlir/lib/CAPI/Dialect/Transform.cpp @@ -0,0 +1,48 @@ +//===- Transform.cpp - C Interface for Transform 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 "mlir-c/Dialect/Transform.h" +#include "mlir-c/Support.h" +#include "mlir/CAPI/Registration.h" +#include "mlir/Dialect/Transform/IR/TransformDialect.h" +#include "mlir/Dialect/Transform/IR/TransformTypes.h" + +using namespace mlir; + +MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(Transform, transform, + transform::TransformDialect) + +//===---------------------------------------------------------------------===// +// AnyOpType +//===---------------------------------------------------------------------===// + +bool mlirTypeIsATransformAnyOpType(MlirType type) { + return unwrap(type).isa(); +} + +MlirType mlirTransformAnyOpTypeGet(MlirContext ctx) { + return wrap(transform::AnyOpType::get(unwrap(ctx))); +} + +//===---------------------------------------------------------------------===// +// OperationType +//===---------------------------------------------------------------------===// + +bool mlirTypeIsATransformOperationType(MlirType type) { + return unwrap(type).isa(); +} + +MlirType mlirTransformOperationTypeGet(MlirContext ctx, + MlirStringRef operationName) { + return wrap( + transform::OperationType::get(unwrap(ctx), unwrap(operationName))); +} + +MlirStringRef mlirTransformOperationTypeGetOperationName(MlirType type) { + return wrap(unwrap(type).cast().getOperationName()); +} diff --git a/mlir/lib/Dialect/Transform/IR/TransformDialect.cpp b/mlir/lib/Dialect/Transform/IR/TransformDialect.cpp --- a/mlir/lib/Dialect/Transform/IR/TransformDialect.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformDialect.cpp @@ -60,10 +60,7 @@ #define GET_OP_LIST #include "mlir/Dialect/Transform/IR/TransformOps.cpp.inc" >(); - addTypesChecked< -#define GET_TYPEDEF_LIST -#include "mlir/Dialect/Transform/IR/TransformTypes.cpp.inc" - >(); + initializeTypes(); pdl::OperationType::attachInterface< PDLOperationTypeTransformTypeInterfaceImpl>(*getContext()); diff --git a/mlir/lib/Dialect/Transform/IR/TransformTypes.cpp b/mlir/lib/Dialect/Transform/IR/TransformTypes.cpp --- a/mlir/lib/Dialect/Transform/IR/TransformTypes.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformTypes.cpp @@ -30,8 +30,31 @@ #define GET_TYPEDEF_CLASSES #include "mlir/Dialect/Transform/IR/TransformTypes.cpp.inc" +void transform::TransformDialect::initializeTypes() { + addTypesChecked< +#define GET_TYPEDEF_LIST +#include "mlir/Dialect/Transform/IR/TransformTypes.cpp.inc" + >(); +} + DiagnosedSilenceableFailure transform::AnyOpType::checkPayload(Location loc, ArrayRef payload) const { return DiagnosedSilenceableFailure::success(); } + +DiagnosedSilenceableFailure +transform::OperationType::checkPayload(Location loc, + ArrayRef payload) const { + OperationName opName(getOperationName(), loc.getContext()); + for (Operation *op : payload) { + if (opName != op->getName()) { + DiagnosedSilenceableFailure diag = + emitSilenceableError(loc) << "incompatible payload operation name"; + diag.attachNote(op->getLoc()) << "payload operation"; + return diag; + } + } + + return DiagnosedSilenceableFailure::success(); +} diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt --- a/mlir/python/CMakeLists.txt +++ b/mlir/python/CMakeLists.txt @@ -121,6 +121,7 @@ SOURCES dialects/_transform_ops_ext.py dialects/transform/__init__.py + _mlir_libs/_mlir/dialects/transform/__init__.pyi DIALECT_NAME transform) declare_mlir_dialect_extension_python_bindings( @@ -353,6 +354,19 @@ MLIRCAPISparseTensor ) +declare_mlir_python_extension(MLIRPythonExtension.Dialects.Transform.Pybind + MODULE_NAME _mlirDialectsTransform + ADD_TO_PARENT MLIRPythonSources.Dialects.transform + ROOT_DIR "${PYTHON_SOURCE_DIR}" + SOURCES + DialectTransform.cpp + PRIVATE_LINK_LIBS + LLVMSupport + EMBED_CAPI_LINK_LIBS + MLIRCAPIIR + MLIRCAPITransformDialect +) + declare_mlir_python_extension(MLIRPythonExtension.AsyncDialectPasses MODULE_NAME _mlirAsyncPasses ADD_TO_PARENT MLIRPythonSources.Dialects.async_dialect diff --git a/mlir/python/mlir/_mlir_libs/_mlir/dialects/transform/__init__.pyi b/mlir/python/mlir/_mlir_libs/_mlir/dialects/transform/__init__.pyi new file mode 100644 --- /dev/null +++ b/mlir/python/mlir/_mlir_libs/_mlir/dialects/transform/__init__.pyi @@ -0,0 +1,26 @@ +# 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 typing import Optional + +from mlir.ir import Type, Context + + +class AnyOpType(Type): + @staticmethod + def isinstance(type: Type) -> bool: ... + + @staticmethod + def get(context: Optional[Context] = None) -> AnyOpType: ... + + +class OperationType(Type): + @staticmethod + def isinstance(type: Type) -> bool: ... + + @staticmethod + def get(operation_name: str, context: Optional[Context] = None) -> OperationType: ... + + @property + def operation_name(self) -> str: ... diff --git a/mlir/python/mlir/dialects/_transform_ops_ext.py b/mlir/python/mlir/dialects/_transform_ops_ext.py --- a/mlir/python/mlir/dialects/_transform_ops_ext.py +++ b/mlir/python/mlir/dialects/_transform_ops_ext.py @@ -18,6 +18,16 @@ return FlatSymbolRefAttr.get(value) +class CastOp: + + def __init__(self, result_type: Type, target: Union[Operation, Value], *, loc=None, ip=None): + super().__init__( + result_type, + _get_op_result_or_value(target), + loc=loc, + ip=ip) + + class GetClosestIsolatedParentOp: def __init__(self, result_type: Type, target: Union[Operation, Value], *, loc=None, ip=None): diff --git a/mlir/python/mlir/dialects/transform/__init__.py b/mlir/python/mlir/dialects/transform/__init__.py --- a/mlir/python/mlir/dialects/transform/__init__.py +++ b/mlir/python/mlir/dialects/transform/__init__.py @@ -18,3 +18,4 @@ return 2 from .._transform_ops_gen import * +from ..._mlir_libs._mlirDialectsTransform import * diff --git a/mlir/test/CAPI/CMakeLists.txt b/mlir/test/CAPI/CMakeLists.txt --- a/mlir/test/CAPI/CMakeLists.txt +++ b/mlir/test/CAPI/CMakeLists.txt @@ -54,6 +54,14 @@ MLIRCAPITransforms ) +_add_capi_test_executable(mlir-capi-pdl-test + pdl.c + LINK_LIBS PRIVATE + MLIRCAPIIR + MLIRCAPIRegisterEverything + MLIRCAPIPDL +) + _add_capi_test_executable(mlir-capi-sparse-tensor-test sparse_tensor.c LINK_LIBS PRIVATE @@ -70,10 +78,10 @@ MLIRCAPIQuant ) -_add_capi_test_executable(mlir-capi-pdl-test - pdl.c +_add_capi_test_executable(mlir-capi-transform-test + transform.c LINK_LIBS PRIVATE MLIRCAPIIR MLIRCAPIRegisterEverything - MLIRCAPIPDL + MLIRCAPITransformDialect ) diff --git a/mlir/test/CAPI/transform.c b/mlir/test/CAPI/transform.c new file mode 100644 --- /dev/null +++ b/mlir/test/CAPI/transform.c @@ -0,0 +1,88 @@ +//===- transform.c - Test of Transform dialect C API ----------------------===// +// +// 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: mlir-capi-transform-test 2>&1 | FileCheck %s + +#include "mlir-c/Dialect/Transform.h" +#include "mlir-c/IR.h" +#include "mlir-c/Support.h" + +#include +#include +#include + +// CHECK-LABEL: testAnyOpType +void testAnyOpType(MlirContext ctx) { + fprintf(stderr, "testAnyOpType\n"); + + MlirType parsedType = mlirTypeParseGet( + ctx, mlirStringRefCreateFromCString("!transform.any_op")); + MlirType constructedType = mlirTransformAnyOpTypeGet(ctx); + + assert(!mlirTypeIsNull(parsedType) && "couldn't parse AnyOpType"); + assert(!mlirTypeIsNull(constructedType) && "couldn't construct AnyOpType"); + + // CHECK: equal: 1 + fprintf(stderr, "equal: %d\n", mlirTypeEqual(parsedType, constructedType)); + + // CHECK: parsedType isa AnyOpType: 1 + fprintf(stderr, "parsedType isa AnyOpType: %d\n", + mlirTypeIsATransformAnyOpType(parsedType)); + // CHECK: parsedType isa OperationType: 0 + fprintf(stderr, "parsedType isa OperationType: %d\n", + mlirTypeIsATransformOperationType(parsedType)); + + // CHECK: !transform.any_op + mlirTypeDump(constructedType); + + fprintf(stderr, "\n\n"); +} + +// CHECK-LABEL: testOperationType +void testOperationType(MlirContext ctx) { + fprintf(stderr, "testOperationType\n"); + + MlirType parsedType = mlirTypeParseGet( + ctx, mlirStringRefCreateFromCString("!transform.op<\"foo.bar\">")); + MlirType constructedType = mlirTransformOperationTypeGet( + ctx, mlirStringRefCreateFromCString("foo.bar")); + + assert(!mlirTypeIsNull(parsedType) && "couldn't parse AnyOpType"); + assert(!mlirTypeIsNull(constructedType) && "couldn't construct AnyOpType"); + + // CHECK: equal: 1 + fprintf(stderr, "equal: %d\n", mlirTypeEqual(parsedType, constructedType)); + + // CHECK: parsedType isa AnyOpType: 0 + fprintf(stderr, "parsedType isa AnyOpType: %d\n", + mlirTypeIsATransformAnyOpType(parsedType)); + // CHECK: parsedType isa OperationType: 1 + fprintf(stderr, "parsedType isa OperationType: %d\n", + mlirTypeIsATransformOperationType(parsedType)); + + // CHECK: operation name equal: 1 + MlirStringRef operationName = + mlirTransformOperationTypeGetOperationName(constructedType); + fprintf(stderr, "operation name equal: %d\n", + mlirStringRefEqual(operationName, + mlirStringRefCreateFromCString("foo.bar"))); + + // CHECK: !transform.op<"foo.bar"> + mlirTypeDump(constructedType); + + fprintf(stderr, "\n\n"); +} + +int main(void) { + MlirContext ctx = mlirContextCreate(); + mlirDialectHandleRegisterDialect(mlirGetDialectHandle__transform__(), ctx); + testAnyOpType(ctx); + testOperationType(ctx); + return EXIT_SUCCESS; +} diff --git a/mlir/test/CMakeLists.txt b/mlir/test/CMakeLists.txt --- a/mlir/test/CMakeLists.txt +++ b/mlir/test/CMakeLists.txt @@ -70,9 +70,10 @@ mlir-capi-ir-test mlir-capi-llvm-test mlir-capi-pass-test - mlir-capi-sparse-tensor-test - mlir-capi-quant-test mlir-capi-pdl-test + mlir-capi-quant-test + mlir-capi-sparse-tensor-test + mlir-capi-transform-test mlir-linalg-ods-yaml-gen mlir-lsp-server mlir-pdll-lsp-server diff --git a/mlir/test/Dialect/Transform/ops.mlir b/mlir/test/Dialect/Transform/ops.mlir --- a/mlir/test/Dialect/Transform/ops.mlir +++ b/mlir/test/Dialect/Transform/ops.mlir @@ -64,4 +64,6 @@ ^bb0(%arg0: !pdl.operation): // CHECK: cast %{{.*}} : !pdl.operation to !transform.any_op %0 = cast %arg0: !pdl.operation to !transform.any_op + // CHECK: cast %{{.*}} : !transform.any_op to !transform.op<"builtin.module"> + %1 = cast %0: !transform.any_op to !transform.op<"builtin.module"> } diff --git a/mlir/test/Dialect/Transform/test-interpreter.mlir b/mlir/test/Dialect/Transform/test-interpreter.mlir --- a/mlir/test/Dialect/Transform/test-interpreter.mlir +++ b/mlir/test/Dialect/Transform/test-interpreter.mlir @@ -841,3 +841,45 @@ transform.cast %2 : !transform.test_dialect_op to !pdl.operation } } + +// ----- + +"test.some_op"() : () -> () +"other_dialect.other_op"() : () -> () + +transform.with_pdl_patterns { +^bb0(%arg0: !pdl.operation): + pdl.pattern @some : benefit(1) { + %0 = pdl.operation "test.some_op" + pdl.rewrite %0 with "transform.dialect" + } + + sequence %arg0 : !pdl.operation failures(propagate) { + ^bb1(%arg1: !pdl.operation): + %0 = pdl_match @some in %arg1 : (!pdl.operation) -> !pdl.operation + %2 = transform.cast %0 : !pdl.operation to !transform.op<"test.some_op"> + transform.cast %2 : !transform.op<"test.some_op"> to !pdl.operation + } +} + +// ----- + +"test.some_op"() : () -> () +// expected-note @below {{payload operation}} +"other_dialect.other_op"() : () -> () + +transform.with_pdl_patterns { +^bb0(%arg0: !pdl.operation): + pdl.pattern @other : benefit(1) { + %0 = pdl.operation "other_dialect.other_op" + pdl.rewrite %0 with "transform.dialect" + } + + sequence %arg0 : !pdl.operation failures(propagate) { + ^bb1(%arg1: !pdl.operation): + %0 = pdl_match @other in %arg1 : (!pdl.operation) -> !pdl.operation + // expected-error @below {{incompatible payload operation name}} + %2 = transform.cast %0 : !pdl.operation to !transform.op<"test.some_op"> + transform.cast %2 : !transform.op<"test.some_op"> to !pdl.operation + } +} diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py --- a/mlir/test/lit.cfg.py +++ b/mlir/test/lit.cfg.py @@ -60,9 +60,10 @@ 'mlir-capi-ir-test', 'mlir-capi-llvm-test', 'mlir-capi-pass-test', - 'mlir-capi-sparse-tensor-test', - 'mlir-capi-quant-test', 'mlir-capi-pdl-test', + 'mlir-capi-quant-test', + 'mlir-capi-sparse-tensor-test', + 'mlir-capi-transform-test', 'mlir-cpu-runner', 'mlir-linalg-ods-yaml-gen', 'mlir-reduce', diff --git a/mlir/test/python/dialects/transform.py b/mlir/test/python/dialects/transform.py --- a/mlir/test/python/dialects/transform.py +++ b/mlir/test/python/dialects/transform.py @@ -15,6 +15,20 @@ return f +@run +def testTypes(): + # CHECK-LABEL: TEST: testTypes + # CHECK: !transform.any_op + any_op = transform.AnyOpType.get() + print(any_op) + + # CHECK: !transform.op<"foo.bar"> + # CHECK: foo.bar + concrete_op = transform.OperationType.get("foo.bar") + print(concrete_op) + print(concrete_op.operation_name) + + @run def testSequenceOp(): sequence = transform.SequenceOp(transform.FailurePropagationMode.PROPAGATE, diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -565,6 +565,23 @@ ], ) +mlir_c_api_cc_library( + name = "CAPITransformDialect", + srcs = [ + "lib/CAPI/Dialect/Transform.cpp", + ], + hdrs = [ + "include/mlir-c/Dialect/Transform.h", + ], + capi_deps = [ + ":CAPIIR", + ], + includes = ["include"], + deps = [ + ":TransformDialect", + ], +) + mlir_c_api_cc_library( name = "CAPIMLProgram", srcs = [