Commit Graph

147 Commits

Author SHA1 Message Date
Alex Zinenko e82a30bdce [mlir] enable Python bindings for the MemRef dialect
A previous commit moved multiple ops from Standard to MemRef dialect.
Some of these ops are exercised in Python bindings. Enable bindings for
the newly created MemRef dialect and update a test accordingly.
2021-03-15 14:07:51 +01:00
Vladislav Vinogradov f3bf5c053b [mlir] Model MemRef memory space as Attribute
Based on the following discussion:
https://llvm.discourse.group/t/rfc-memref-memory-shape-as-attribute/2229

The goal of the change is to make memory space property to have more
expressive representation, rather then "magic" integer values.

It will allow to have more clean ASM form:

```
gpu.func @test(%arg0: memref<100xf32, "workgroup">)

// instead of

gpu.func @test(%arg0: memref<100xf32, 3>)
```

Explanation for `Attribute` choice instead of plain `string`:

* `Attribute` classes allow to use more type safe API based on RTTI.
* `Attribute` classes provides faster comparison operator based on
  pointer comparison in contrast to generic string comparison.
* `Attribute` allows to store more complex things, like structs or dictionaries.
  It will allows to have more complex memory space hierarchy.

This commit preserve old integer-based API and implements it on top
of the new one.

Depends on D97476

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D96145
2021-03-10 12:57:27 +03:00
Stella Laurenzo e31c77b182 [mlir][python] Reorganize MLIR python into namespace packages.
* Only leaf packages are non-namespace packages. This allows most of the top levels to be split into different directories or deployment packages. In the previous state, the presence of __init__.py files at each level meant that the entire tree could only ever exist in one physical directory on the path.
* This changes the API usage slightly: `import mlir` will no longer do a deep import of `mlir.ir`, etc. This may necessitate some client code changes.
* Dialect gen code was restructured so that the user is responsible for providing the `my_dialect.py` file, which then must import its peer `_my_dialect_ops_gen`. This gives complete control of the dialect namespace to the user instead of to tablegen code, allowing further dialect-specific python APIs.
* Correspondingly, the previous extension modules `_my_dialect.py` are now `_my_dialect_ops_ext.py`.
* Now that the `linalg` namespace is open, moved the `linalg_opdsl` tool into it.
* This may require some corresponding downstream adjustments to npcomp, circt, et al:
  * Probably some shallow imports need to be converted to deep imports (i.e. not `import mlir` brings in the world).
  * Each tablegen generated dialect now needs an explicit `foo.py` which does a `from ._foo_ops_gen import *`. This is similar to the way that generated code operates in the C++ world.
  * If providing dialect op extensions, those need to be moved from `_foo.py` -> `_foo_ops_ext.py`.

Differential Revision: https://reviews.llvm.org/D98096
2021-03-08 23:01:34 -08:00
Stella Laurenzo 0b5f1b859f [mlir][linalg] Add linalg_opdsl tool first draft.
* Mostly imported from experimental repo as-is with cosmetic changes.
* Temporarily left out emission code (for building ops at runtime) to keep review size down.
* Documentation and lit tests added fresh.
* Sample op library that represents current Linalg named ops included.

Differential Revision: https://reviews.llvm.org/D97995
2021-03-05 11:45:09 -08:00
Stella Laurenzo a9ccdfbc7d NFC: Glob all python sources in the MLIR Python bindings.
* Also switches to use symlinks vs copy as that enables edit-and-continue python development.
* Broken out of https://reviews.llvm.org/D97995 per request from reviewer.

Differential Revision: https://reviews.llvm.org/D98005
2021-03-05 10:21:02 -08:00
Mehdi Amini 13cb431719 Add basic JIT Python Bindings
This offers the ability to create a JIT and invoke a function by passing
ctypes pointers to the argument and the result.

Differential Revision: https://reviews.llvm.org/D97523
2021-03-03 18:19:40 +00:00
River Riddle 06e25d5645 [mlir][IR] Refactor the `getChecked` and `verifyConstructionInvariants` methods on Attributes/Types
`verifyConstructionInvariants` is intended to allow for verifying the invariants of an attribute/type on construction, and `getChecked` is intended to enable more graceful error handling aside from an assert. There are a few problems with the current implementation of these methods:
* `verifyConstructionInvariants` requires an mlir::Location for emitting errors, which is prohibitively costly in the situations that would most likely use them, e.g. the parser.
This creates an unfortunate code duplication between the verifier code and the parser code, given that the parser operates on llvm::SMLoc and it is an undesirable overhead to pre-emptively convert from that to an mlir::Location.
* `getChecked` effectively requires duplicating the definition of the `get` method, creating a quite clunky workflow due to the subtle different in its signature.

This revision aims to talk the above problems by refactoring the implementation to use a callback for error emission. Using a callback allows for deferring the costly part of error emission until it is actually necessary.

Due to the necessary signature change in each instance of these methods, this revision also takes this opportunity to cleanup the definition of these methods by:
* restructuring the signature of `getChecked` such that it can be generated from the same code block as the `get` method.
* renaming `verifyConstructionInvariants` to `verify` to match the naming scheme of the rest of the compiler.

Differential Revision: https://reviews.llvm.org/D97100
2021-02-22 17:37:49 -08:00
Stella Laurenzo 4c3f1be84f [mlir][python] Add python binding for AffineMapAttribute.
Differential Revision: https://reviews.llvm.org/D96815
2021-02-16 15:43:30 -08:00
Alex Zinenko b208e5bcd0 [mlir] Add Python bindings for IntegerSet
This follows up on the introduction of C API for the same object and is similar
to AffineExpr and AffineMap.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D95437
2021-01-26 17:32:51 +01:00
zhanghb97 a2914e0c15 [mlir][Python] Fix comments of 'getCapsule' and 'createFromCapsule'
The `getCapsule` and `createFromCapsule` comments incorrectly state the `PyMlirContext` and `MlirContext` in `PyLocation`, `PyAttribute`, and `PyType` classes.

Differential Revision: https://reviews.llvm.org/D95413
2021-01-26 12:53:21 +08:00
Stella Laurenzo fd226c9b02 [mlir][Python] Roll up of python API fixes.
* As discussed, fixes the ordering or (operands, results) -> (results, operands) in various `create` like methods.
* Fixes a syntax error in an ODS accessor method.
* Removes the linalg example in favor of a test case that exercises the same.
* Fixes FuncOp visibility to properly use None instead of the empty string and defaults it to None.
* Implements what was documented for requiring that trailing __init__ args `loc` and `ip` are keyword only.
* Adds a check to `InsertionPoint.insert` so that if attempting to insert past the terminator, an exception is raised telling you what to do instead. Previously, this would crash downstream (i.e. when trying to print the resultant module).
* Renames `_ods_build_default` -> `build_generic` and documents it.
* Removes `result` from the list of prohibited words and for single-result ops, defaults to naming the result `result`, thereby matching expectations and what is already implemented on the base class.
* This was intended to be a relatively small set of changes to be inlined with the broader support for ODS generating the most specific builder, but it spidered out once actually testing various combinations, so rolling up separately.

Differential Revision: https://reviews.llvm.org/D95320
2021-01-24 19:02:59 -08:00
Mehdi Amini 922b26cde4 Add Python bindings for the builtin dialect
This includes some minor customization for FuncOp and ModuleOp.

Differential Revision: https://reviews.llvm.org/D95022
2021-01-21 22:44:44 +00:00
Stella Laurenzo b62c7e0474 [mlir][python] Swap shape and element_type order for MemRefType.
* Matches how all of the other shaped types are declared.
* No super principled reason fro this ordering beyond that it makes the one that was different be like the rest.
* Also matches ordering of things like ndarray, et al.

Reviewed By: ftynse, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D94812
2021-01-19 16:03:19 -08:00
Stella Laurenzo 894d88a759 [mlir][python] Add facility for extending generated python ODS.
* This isn't exclusive with other mechanisms for more ODS centric op definitions, but based on discussions, we feel that we will always benefit from a python escape hatch, and that is the most natural way to write things that don't fit the mold.
* I suspect this facility needs further tweaking, and once it settles, I'll document it and add more tests.
* Added extensions for linalg, since it is unusable without them and continued to evolve my e2e example.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D94752
2021-01-19 13:20:26 -08:00
Stella Laurenzo 71b6b010e6 [mlir][python] Factor out standalone OpView._ods_build_default class method.
* This allows us to hoist trait level information for regions and sized-variadic to class level attributes (_ODS_REGIONS, _ODS_OPERAND_SEGMENTS, _ODS_RESULT_SEGMENTS).
* Eliminates some splicey python generated code in favor of a native helper for it.
* Makes it possible to implement custom, variadic and region based builders with one line of python, without needing to manually code access to the segment attributes.
* Needs follow-on work for region based callbacks and support for SingleBlockImplicitTerminator.
* A follow-up will actually add ODS support for generating custom Python builders that delegate to this new method.
* Also includes the start of an e2e sample for constructing linalg ops where this limitation was discovered (working progressively through this example and cleaning up as I go).

Differential Revision: https://reviews.llvm.org/D94738
2021-01-19 09:29:57 -08:00
zhanghb97 c0f3ea8a08 [mlir][Python] Add checking process before create an AffineMap from a permutation.
An invalid permutation will trigger a C++ assertion when attempting to create an AffineMap from the permutation.
This patch adds an `isPermutation` function to check the given permutation before creating the AffineMap.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D94492
2021-01-13 09:32:32 +08:00
Stella Laurenzo 53c866c286 Enable python bindings for tensor, shape and linalg dialects.
* We've got significant missing features in order to use most of these effectively (i.e. custom builders, region-based builders).
* We presently also lack a mechanism for actually registering these dialects but they can be use with contexts that allow unregistered dialects for further prototyping.

Differential Revision: https://reviews.llvm.org/D94368
2021-01-11 12:35:49 -08:00
Alex Zinenko 547e3eef14 [mlir] Expose MemRef layout in Python bindings
This wasn't possible before because there was no support for affine expressions
as maps. Now that this support is available, provide the mechanism for
constructing maps with a layout and inspecting it.

Rework the `get` method on MemRefType in Python to avoid needing an explicit
memory space or layout map. Remove the `get_num_maps`, it is too low-level,
using the length of the now-avaiable pseudo-list of layout maps is more
pythonic.

Depends On D94297

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D94302
2021-01-11 19:57:16 +01:00
Alex Zinenko e79bd0b4f2 [mlir] More Python bindings for AffineMap
Now that the bindings for AffineExpr have been added, add more bindings for
constructing and inspecting AffineMap that consists of AffineExprs.

Depends On D94225

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D94297
2021-01-11 19:57:15 +01:00
Alex Zinenko 74628c4305 [mlir] Add Python bindings for AffineExpr
This adds the Python bindings for AffineExpr and a couple of utility functions
to the C API. AffineExpr is a top-level context-owned object and is modeled
similarly to attributes and types. It is required, e.g., to build layout maps
of the built-in memref type.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D94225
2021-01-11 19:57:13 +01:00
Kazuaki Ishizaki f88fab5006 [mlir] NFC: fix trivial typos
fix typo under include and lib directories

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D94220
2021-01-08 02:10:12 +09:00
Stella Laurenzo 42c57dcc35 [mlir][python] Tweaks to make python extensions packagable/distributable.
* Works in tandem with prototype packaging scripts here: https://github.com/stellaraccident/mlir-py-release
* The `mlir` top-level now differentiates between in-tree builds where all packages are co-located and distribution mode where all native components are under a top-level `_mlir_libs` package.
* Also fixes the generated dialect python installation again. Hopefully the last tweak.
* With this, I am able to install and generate archives with the above setup script on Linux. Archive size=31M with just host codegen and headers/shared-libraries. Will need more linker tweaks when wiring up the next dependent project.

Differential Revision: https://reviews.llvm.org/D93936
2020-12-30 23:35:46 -08:00
zhanghb97 abb4cd3e74 [mlir][Python] Initial Affine Map Python Bindings.
- Add `PyAffineMap` to wrap around `MlirAffineMap`.
- Add `mlirPythonAffineMapToCapsule` and `mlirPythonCapsuleToAffineMap` to interoperate with python capsule.
- Add and test some simple bindings of `PyAffineMap`.

Differential Revision: https://reviews.llvm.org/D93200
2020-12-30 17:36:39 +08:00
Stella Laurenzo 11f41cd445 [mlir][python] Install generated dialect sources.
Differential Revision: https://reviews.llvm.org/D93928
2020-12-29 20:15:07 -08:00
Siddharth Krishna 14056c88d6 [mlir][Python] Add an Operation.name property
Reviewed By: stellaraccident, mehdi_amini

Differential Revision: https://reviews.llvm.org/D93474
2020-12-29 14:14:32 -08:00
Stella Laurenzo f5665a2486 [mlir][python] Add Operation.verify().
Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93913
2020-12-29 14:10:31 -08:00
Stella Laurenzo df7ddeea66 [mlir][python] Add FlatSymbolRef attribute.
Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93909
2020-12-29 12:24:28 -08:00
kweisamx c84b53ca9b [mlir] Add Python binding for MLIR Dict Attribute
Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93004
2020-12-13 04:30:35 +00:00
Mehdi Amini aadcb26ee1 Store a MlirIdentifier instead of a MlirStringRef in MlirNameAttribute
This mirror the C++ API for NamedAttribute, and has the advantage or
internalizing earlier in the Context and not requiring the caller to
keep the StringRef alive beyong this call.

Differential Revision: https://reviews.llvm.org/D93133
2020-12-11 22:38:48 +00:00
Mehdi Amini 285c0aa262 Add MLIR Python binding for Array Attribute
Differential Revision: https://reviews.llvm.org/D92948
2020-12-10 20:51:34 +00:00
Mehdi Amini ac6ada4d3e Fix MLIR Python bindings build after changes to the C API to use StringRef (NFC) 2020-12-09 03:27:37 +00:00
Mehdi Amini e56f398dd3 Add Python binding for MLIR Type Attribute
Differential Revision: https://reviews.llvm.org/D92711
2020-12-07 23:06:58 +00:00
Mehdi Amini e15ae454b4 Customize exception thrown from mlir.Operation.create() python bindings
The default exception handling isn't very user friendly and does not
point accurately to the issue. Instead we can indicate which of the
operands isn't valid and provide contextual information in the error
message.

Differential Revision: https://reviews.llvm.org/D92710
2020-12-07 23:06:58 +00:00
River Riddle c7cae0e4fa [mlir][Attributes][NFC] Move all builtin Attribute classes to BuiltinAttributes.h
This mirrors the file structure of Types.

Differential Revision: https://reviews.llvm.org/D92499
2020-12-03 18:02:11 -08:00
River Riddle 09f7a55fad [mlir][Types][NFC] Move all of the builtin Type classes to BuiltinTypes.h
This is part of a larger refactoring the better congregates the builtin structures under the BuiltinDialect. This also removes the problematic "standard" naming that clashes with the "standard" dialect, which is not defined within IR/. A temporary forward is placed in StandardTypes.h to allow time for downstream users to replaced references.

Differential Revision: https://reviews.llvm.org/D92435
2020-12-03 18:02:10 -08:00
Mehdi Amini 1c2159494d Use the generic form when printing from the python bindings and the verifier fails
This reduces the chances of segfault. While it is a good practice to ensure
robust custom printers, it is unfortunately common to have them crash on
invalid input.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D92536
2020-12-03 18:45:00 +00:00
Stella Laurenzo 62195b7548 [mlir][CAPI] Convert the rest of the API int -> bool.
* Follows on https://reviews.llvm.org/D92193
* I had a mid-air collision with some additional occurrences and then noticed that there were a lot more. Think I got them all.

Differential Revision: https://reviews.llvm.org/D92292
2020-11-29 20:36:42 -08:00
Stella Laurenzo ba0fe76b7e [mlir][Python] Add an Operation.result property.
* If ODS redefines this, it is fine, but I have found this accessor to be universally useful in the old npcomp bindings and I'm closing gaps that will let me switch.

Differential Revision: https://reviews.llvm.org/D92287
2020-11-29 18:09:07 -08:00
Stella Laurenzo bd2083c2fa [mlir][Python] Python API cleanups and additions found during code audit.
* Add capsule get/create for Attribute and Type, which already had capsule interop defined.
* Add capsule interop and get/create for Location.
* Add Location __eq__.
* Use get() and implicit cast to go from PyAttribute, PyType, PyLocation to MlirAttribute, MlirType, MlirLocation (bundled with this change because I didn't want to continue the pattern one more time).

Differential Revision: https://reviews.llvm.org/D92283
2020-11-29 18:09:07 -08:00
zhanghb97 5f0c1e3806 [mlir][Python] Sync Python bindings with C API MlirStringRef modification.
MLIR C API use the `MlirStringRef` instead of `const char *` for the string type now. This patch sync the Python bindings with the C API modification.

Differential Revision: https://reviews.llvm.org/D92007
2020-11-24 19:33:48 +00:00
Alex Zinenko ee6255d207 [mlir] move lib/Bindings/Python/Attributes.td to include/mlir/Bindings/Python
This file is intended to be included by other files, including
out-of-tree dialects, and makes more sense in `include` than in `lib`.

Depends On D91652

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D91961
2020-11-24 09:19:01 +01:00
Alex Zinenko 029e199dbf [mlir] Make attributes mutable in Python bindings
Attributes represent additional data about an operation and are intended to be
modifiable during the lifetime of the operation. In the dialect-specific Python
bindings, attributes are exposed as properties on the operation class. Allow
for assigning values to these properties. Also support creating new and
deleting existing attributes through the generic "attributes" property of an
operation. Any validity checking must be performed by the op verifier after the
mutation, similarly to C++. Operations are not invalidated in the process: no
dangling pointers can be created as all attributes are owned by the context and
will remain live even if they are not used in any operation.

Introduce a Python Test dialect by analogy with the Test dialect and to avoid
polluting the latter with Python-specific constructs. Use this dialect to
implement a test for the attribute access and mutation API.

Reviewed By: stellaraccident, mehdi_amini

Differential Revision: https://reviews.llvm.org/D91652
2020-11-24 09:16:25 +01:00
zhanghb97 77133b29b9 [mlir] Get array from the dense elements attribute with buffer protocol.
- Add `mlirElementsAttrGetType` C API.
- Add `def_buffer` binding to PyDenseElementsAttribute.
- Implement the protocol to access the buffer.

Differential Revision: https://reviews.llvm.org/D91021
2020-11-18 15:50:59 +08:00
Stella Laurenzo 989b194429 [mlir][Python] Make DenseElementsAttr loading be int size agnostic.
* I had missed the note about "Standard size" in the docs. On Windows, the 'l' types are 32bit.
* This fixes the only failing MLIR-Python test on Windows.

Differential Revision: https://reviews.llvm.org/D91283
2020-11-17 21:50:44 -08:00
Alex Zinenko f3dab16dc7 [mlir] Add a _get_default_loc_context utility to Python bindings
This utility function is helpful for dialect-specific builders that need
to access the context through location, and the location itself may be
either provided as an argument or expected to be recovered from the
implicit location stack.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D91623
2020-11-17 17:55:47 +01:00
Alex Zinenko c5a6712f8c [mlir] Add basic support for attributes in ODS-generated Python bindings
In ODS, attributes of an operation can be provided as a part of the "arguments"
field, together with operands. Such attributes are accepted by the op builder
and have accessors generated.

Implement similar functionality for ODS-generated op-specific Python bindings:
the `__init__` method now accepts arguments together with operands, in the same
order as in the ODS `arguments` field; the instance properties are introduced
to OpView classes to access the attributes.

This initial implementation accepts and returns instances of the corresponding
attribute class, and not the underlying values since the mapping scheme of the
value types between C++, C and Python is not yet clear. Default-valued
attributes are not supported as that would require Python to be able to parse
C++ literals.

Since attributes in ODS are tightely related to the actual C++ type system,
provide a separate Tablegen file with the mapping between ODS storage type for
attributes (typically, the underlying C++ attribute class), and the
corresponding class name. So far, this might look unnecessary since all names
match exactly, but this is not necessarily the cases for non-standard,
out-of-tree attributes, which may also be placed in non-default namespaces or
Python modules. This also allows out-of-tree users to generate Python bindings
without having to modify the bindings generator itself. Storage type was
preferred over the Tablegen "def" of the attribute class because ODS
essentially encodes attribute _constraints_ rather than classes, e.g. there may
be many Tablegen "def"s in the ODS that correspond to the same attribute type
with additional constraints

The presence of the explicit mapping requires the change in the .td file
structure: instead of just calling the bindings generator directly on the main
ODS file of the dialect, it becomes necessary to create a new file that
includes the main ODS file of the dialect and provides the mapping for
attribute types. Arguably, this approach offers better separability of the
Python bindings in the build system as the main dialect no longer needs to know
that it is being processed by the bindings generator.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D91542
2020-11-17 11:47:37 +01:00
Stella Laurenzo 4726a402a3 [mlir][Python] Fix 'unreferenced local variable' warning on MSVC.
Differential Revision: https://reviews.llvm.org/D91282
2020-11-12 13:34:57 -08:00
Stella Laurenzo 5fef6ce0cc [mlir][Python] Allow PassManager to interop with the capsule APIs.
* Used in npcomp to cast Python objects via the C-API.

Differential Revision: https://reviews.llvm.org/D91232
2020-11-11 10:37:21 -08:00
Stella Laurenzo 99b1c42fd3 [mlir][Python] Add Windows DLL loader to get python extensions working there.
Differential Revision: https://reviews.llvm.org/D90958
2020-11-11 09:54:47 -08:00
Mehdi Amini 6cb1c0cae0 Add Python binding to run a PassManager on a MLIR Module
Reviewed By: ftynse, stellaraccident

Differential Revision: https://reviews.llvm.org/D90823
2020-11-10 20:06:23 +00:00
Mehdi Amini dc43f78565 Add basic Python bindings for the PassManager and bind libTransforms
This only exposes the ability to round-trip a textual pipeline at the
moment.
To exercise it, we also bind the libTransforms in a new Python extension. This
does not include any interesting bindings, but it includes all the
mechanism to add separate native extensions and load them dynamically.
As such passes in libTransforms are only registered after `import
mlir.transforms`.
To support this global registration, the TableGen backend is also
extended to bind to the C API the group registration for passes.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D90819
2020-11-10 19:55:21 +00:00
Alex Zinenko fd407e1f1e [mlir] ODS-backed python binding generator for custom op classes
Introduce an ODS/Tablegen backend producing Op wrappers for Python bindings
based on the ODS operation definition. Usage:

  mlir-tblgen -gen-python-op-bindings -Iinclude <path/to/Ops.td> \
              -bind-dialect=<dialect-name>

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D90960
2020-11-10 10:58:29 +01:00
Alex Zinenko 6c7e6b2c9a [mlir] Support slicing for operands in results in Python bindings
Slicing, that is element access with `[being🔚step]` structure, is
a common Python idiom for sequence-like containers. It is also necessary
to support custom accessor for operations with variadic operands and
results (an operation an return a slice of its operands that correspond
to the given variadic group).

Add generic utility to support slicing in Python bindings and use it
for operation operands and results.

Depends On D90923

Reviewed By: stellaraccident, mehdi_amini

Differential Revision: https://reviews.llvm.org/D90936
2020-11-10 10:46:21 +01:00
Alex Zinenko 4669ea3bd8 [mlir] Add initial Python bindings for DenseInt/FPElementsAttr
Enumerating elements in these classes is necessary to enable custom
operand accessors for variadic operands.

Depends On D90919

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D90923
2020-11-09 15:23:54 +01:00
Alex Zinenko c3a6e7c9b7 [mlir] Expose operation attributes to Python bindings
Operations in a MLIR have a dictionary of attributes attached. Expose
those to Python bindings through a pseudo-container that can be indexed
either by attribute name, producing a PyAttribute, or by a contiguous
index for enumeration purposes, producing a PyNamedAttribute.

Depends On D90917

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D90919
2020-11-09 14:59:56 +01:00
Stella Laurenzo 08c1a0dda4 [mlir][CAPI] Proposal: Always building a libMLIRPublicAPI.so (re-apply).
Re-applies the reverted https://reviews.llvm.org/D90824 now that the link issue on BFD has been resolved.

This reverts commit bb9b5d3971.

Differential Revision: https://reviews.llvm.org/D91044
2020-11-08 16:57:51 -08:00
Alex Zinenko b9c353fabb [mlir] Use PyValue instead of PyOpResult in Python operand container
The PyOpOperands container was erroneously constructing objects for
individual operands as PyOpResult. Operands in fact are just values,
which may or may not be results of another operation. The code would
eventually crash if the operand was a block argument. Add a test that
exercises the behavior that previously led to crashes.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D90917
2020-11-06 19:02:35 +01:00
Alex Zinenko bb9b5d3971 Revert "[mlir][CAPI] Proposal: Always building a libMLIRPublicAPI.so."
This reverts commit 80fe2f61fa.

Broke linkage with GNU ld. See original review thread for more details.
2020-11-06 18:59:58 +01:00
Stella Laurenzo 80fe2f61fa [mlir][CAPI] Proposal: Always building a libMLIRPublicAPI.so.
We were discussing on discord regarding the need for extension-based systems like Python to dynamically link against MLIR (or else you can only have one extension that depends on it). Currently, when I set that up, I piggy-backed off of the flag that enables build libLLVM.so and libMLIR.so and depended on libMLIR.so from the python extension if shared library building was enabled. However, this is less than ideal.

In the current setup, libMLIR.so exports both all symbols from the C++ API and the C-API. The former is a kitchen sink and the latter is curated. We should be splitting them and for things that are properly factored to depend on the C-API, they should have the option to *only* depend on the C-API, and we should build that shared library no matter what. Its presence isn't just an optimization: it is a key part of the system.

To do this right, I needed to:

* Introduce visibility macros into mlir-c/Support.h. These should work on both *nix and windows as-is.
* Create a new libMLIRPublicAPI.so with just the mlir-c object files.
* Compile the C-API with -fvisibility=hidden.
* Conditionally depend on the libMLIR.so from libMLIRPublicAPI.so if building libMLIR.so (otherwise, also links against the static libs and will produce a mondo libMLIRPublicAPI.so).
* Disable re-exporting of static library symbols that come in as transitive deps.

This gives us a dynamic linked C-API layer that is minimal and should work as-is on all platforms. Since we don't support libMLIR.so building on Windows yet (and it is not very DLL friendly), this will fall back to a mondo build of libMLIRPublicAPI.so, which has its uses (it is also the most size conscious way to go if you happen to know exactly what you need).

Sizes (release/stripped, Ubuntu 20.04):

Shared library build:
	libMLIRPublicAPI.so: 121Kb
	_mlir.cpython-38-x86_64-linux-gnu.so: 1.4Mb
	mlir-capi-ir-test: 135Kb
	libMLIR.so: 21Mb

Static build:
	libMLIRPublicAPI.so: 5.5Mb (since this is a "static" build, this includes the MLIR implementation as non-exported code).
	_mlir.cpython-38-x86_64-linux-gnu.so: 1.4Mb
	mlir-capi-ir-test: 44Kb

Things like npcomp and circt which bring their own dialects/transforms/etc would still need the shared library build and code that links against libMLIR.so (since it is all C++ interop stuff), but hopefully things that only depend on the public C-API can just have the one narrow dep.

I spot checked everything with nm, and it looks good in terms of what is exporting/importing from each layer.

I'm not in a hurry to land this, but if it is controversial, I'll probably split off the Support.h and API visibility macro changes, since we should set that pattern regardless.

Reviewed By: mehdi_amini, benvanik

Differential Revision: https://reviews.llvm.org/D90824
2020-11-06 09:00:56 -08:00
Mehdi Amini 72dcd902e7 Add a custom MLIRBindingsPythonExtension cmake target to group all Python bindings (NFC)
This target will depend on each individual extension and represent "all"
Python bindings in the repo. User projects can get a finer grain control by
depending directly on some individual targets as needed.
2020-11-05 20:06:08 +00:00
Mehdi Amini 7f977086eb Fix MLIR Python bindings build (remove inexistant source from CMake list, NFC) 2020-11-05 20:06:07 +00:00
Mehdi Amini 24b3b2cd74 Refactor MLIR python extension CMake boilerplate in a reusable function (NFC)
Differential Revision: https://reviews.llvm.org/D90816
2020-11-05 19:57:12 +00:00
Mehdi Amini a1229c9518 Always link the MLIR python bindings native extension to libMLIR.so
The Python bindings now require -DLLVM_BUILD_LLVM_DYLIB=ON to build.
This change is needed to be able to build multiple Python native
extension without having each of them embedding a copy of MLIR, which
would make them incompatible with each other. Instead they should all
link to the same copy of MLIR.

Differential Revision: https://reviews.llvm.org/D90813
2020-11-05 19:57:11 +00:00
Mehdi Amini 5b29d26b21 Refactor PyPrintAccumulatorm, PyFileAccumulator, and PySinglePartStringAccumulator from IRModules.cpp to PybindUtils.h
These are reusable utilities across bindings.

Differential Revision: https://reviews.llvm.org/D90737
2020-11-04 18:46:36 +00:00
Stella Laurenzo 8260db752c [mlir][Python] Return and accept OpView for all functions.
* All functions that return an Operation now return an OpView.
* All functions that accept an Operation now accept an _OperationBase, which both Operation and OpView extend and can resolve to the backing Operation.
* Moves user-facing instance methods from Operation -> _OperationBase so that both can have the same API.
* Concretely, this means that if there are custom op classes defined (i.e. in Python), any iteration or creation will return the appropriate instance (i.e. if you get/create an std.addf, you will get an instance of the mlir.dialects.std.AddFOp class, getting full access to any custom API it exposes).
* Refactors all __eq__ methods after realizing the proper way to do this for _OperationBase.

Differential Revision: https://reviews.llvm.org/D90584
2020-11-03 22:48:34 -08:00
Stella Laurenzo af66cd173f [mlir][Python] Context managers for Context, InsertionPoint, Location.
* Finishes support for Context, InsertionPoint and Location to be carried by the thread using context managers.
* Introduces type casters and utilities so that DefaultPyMlirContext and DefaultPyLocation in method signatures does the right thing (allows explicit or gets from the thread context).
* Extend the rules for the thread context stack to handle nesting, appropriately inheriting and clearing depending on whether the context is the same.
* Refactors all method signatures to follow the new convention on trailing parameters for defaulting parameters (loc, ip, context). When the objects are carried in the thread context, this allows most explicit uses of these values to be elided.
* Removes the style guide section on putting accessors to construct global objects on the PyMlirContext: this style fails to make good use of the new facility since it is often the only thing remaining needing an MlirContext.
* Moves Module parse/creation from mlir.ir.Context to static methods on mlir.ir.Module.
* Moves Context.create_operation to a static Operation.create method.
* Moves Type parsing from mlir.ir.Context to static methods on mlir.ir.Type.
* Moves Attribute parsing from mlir.ir.Context to static methods on mlir.ir.Attribute.
* Move Location factory methods from mlir.ir.Context to static methods on mlir.ir.Location.
* Refactors the std dialect fake "ODS" generated code to take advantage of the new scheme.

Differential Revision: https://reviews.llvm.org/D90547
2020-11-01 19:00:39 -08:00
Stella Laurenzo c645ea5e29 Add InsertionPoint and context managers to the Python API.
* Removes index based insertion. All insertion now happens through the insertion point.
* Introduces thread local context managers for implicit creation relative to an insertion point.
* Introduces (but does not yet use) binding the Context to the thread local context stack. Intent is to refactor all methods to take context optionally and have them use the default if available.
* Adds C APIs for mlirOperationGetParentOperation(), mlirOperationGetBlock() and mlirBlockGetTerminator().
* Removes an assert in PyOperation creation that was incorrectly constraining. There is already a TODO to rework the keepAlive field that it was guarding and without the assert, it is no worse than the current state.

Differential Revision: https://reviews.llvm.org/D90368
2020-10-29 17:50:13 -07:00
Kazuaki Ishizaki 41b09f4eff [mlir] NFC: fix trivial typos
fix typos in comments and documents

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D90089
2020-10-29 04:05:22 +09:00
Mehdi Amini 72023442c1 Add a `mlirModuleGetBody()` accessor to the C API and bind it in Python
Getting the body of a Module is a common need which justifies a
dedicated accessor instead of forcing users to go through the
region->blocks->front unwrapping manually.

Differential Revision: https://reviews.llvm.org/D90287
2020-10-28 17:53:52 +00:00
Stella Laurenzo 013b9322de [mlir][Python] Custom python op view wrappers for building and traversing.
* Still rough edges that need more sugar but the bones are there. Notes left in the test case for things that can be improved.
* Does not actually yield custom OpViews yet for traversing. Will rework that in a followup.

Differential Revision: https://reviews.llvm.org/D89932
2020-10-27 12:23:34 -07:00
Stella Laurenzo 74a58ec9c2 [mlir][CAPI][Python] Plumb OpPrintingFlags to C and Python APIs.
* Adds a new MlirOpPrintingFlags type and supporting accessors.
* Adds a new mlirOperationPrintWithFlags function.
* Adds a full featured python Operation.print method with all options and the ability to print directly to files/stdout in text or binary.
* Adds an Operation.get_asm which delegates to print and returns a str or bytes.
* Reworks Operation.__str__ to be based on get_asm.

Differential Revision: https://reviews.llvm.org/D89848
2020-10-21 12:14:06 -07:00
Alex Zinenko f6f27115e6 [mlir] Fix copy-pasted docstrings in Python bindings
Docstrings for `__str__` method in many classes was recycling the constant
string defined for `Type`, without being types themselves. Use proper
docstrings instead. Since they are succint, use string literals instead of
top-level constants to avoid further mistakes.

Differential Revision: https://reviews.llvm.org/D89780
2020-10-21 09:49:23 +02:00
Alex Zinenko 31782cd219 [mlir] Use the correct base class for Attributes in Python bindings
The pybind class typedef for concrete attribute classes was erroneously
deriving all of them from PyAttribute instead of the provided base class. This
has not been triggering any error because only one level of the hierarchy is
currently exposed.

Differential Revision: https://reviews.llvm.org/D89779
2020-10-21 09:49:23 +02:00
Alex Zinenko 580915d6a2 [mlir] Expose Value hierarchy to Python bindings
Values are ubiquitous in the IR, in particular block argument and operation
results are Values. Define Python classes for BlockArgument, OpResult and their
common ancestor Value. Define pseudo-container classes for lists of block
arguments and operation results, and use these containers to access the
corresponding values in blocks and operations.

Differential Revision: https://reviews.llvm.org/D89778
2020-10-21 09:49:22 +02:00
Stella Laurenzo 0e6beb2996 [mlir][Python] Add python binding to create DenseElementsAttribute.
* Interops with Python buffers/numpy arrays to create.
* Also cleans up 'get' factory methods on some types to be consistent.
* Adds mlirAttributeGetType() to C-API to facilitate error handling and other uses.
* Punts on a lot of features of the ElementsAttribute hierarchy for now.
* Does not yet support bool or string attributes.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D89363
2020-10-19 22:29:35 -07:00
Stella Laurenzo ad958f648e [mlir][Python] Add missing capsule->module and Context.create_module.
* Extends Context/Operation interning to cover Module as well.
* Implements Module.context, Attribute.context, Type.context, and Location.context back-references (facilitated testing and also on the TODO list).
* Adds method to create an empty Module.
* Discovered missing in npcomp.

Differential Revision: https://reviews.llvm.org/D89294
2020-10-13 13:10:33 -07:00
Stella Laurenzo 75ae846de6 [mlir] Make Python bindings installable.
* Links against libMLIR.so if the project is built for DYLIBs.
* Puts things in the right place in build and install time python/ trees so that RPaths line up.
* Adds install actions to install both the extension and sources.
* Copies py source files to the build directory to match (consistent layout between build/install time and one place to point a PYTHONPATH for tests and interactive use).
* Finally, "import mlir" from an installed LLVM just works.

Differential Revision: https://reviews.llvm.org/D89167
2020-10-12 15:17:03 -07:00
zhanghb97 2fc0d4a8e8 [mlir] Add Float Attribute, Integer Attribute and Bool Attribute subclasses to python bindings.
Based on PyAttribute and PyConcreteAttribute classes, this patch implements the bindings of Float Attribute, Integer Attribute and Bool Attribute subclasses.
This patch also defines the `mlirFloatAttrDoubleGetChecked` C API which is bound with the `FloatAttr.get_typed` python method.

Differential Revision: https://reviews.llvm.org/D88531
2020-10-03 00:32:51 +08:00
Stella Laurenzo 543922cd36 Adds MLIR C-API for marshaling Python capsules.
* Providing stable, C-accessible definitions for bridging MLIR Python<->C APIs, we eliminate inter-extension dependencies (i.e. they can all share a diamond dependency on the MLIR C-API).
* Just provides accessors for context and module right now.
* Needed in NPComp in ~a week or so for high level Torch APIs.

Differential Revision: https://reviews.llvm.org/D88426
2020-09-29 10:48:53 -07:00
Stella Laurenzo 76753a597b Add FunctionType to MLIR C and Python bindings.
Differential Revision: https://reviews.llvm.org/D88416
2020-09-28 09:56:48 -07:00
Stella Laurenzo b522f09d96 Remove MLIR C-API explicit registration of standard ops.
* Added mlirRegisterAllDialects() to the python API until a more complete registration design emerges for it.

Differential Revision: https://reviews.llvm.org/D88155
2020-09-23 09:23:11 -07:00
Stella Laurenzo c1ded6a759 Add mlir python APIs for creating operations, regions and blocks.
* The API is a bit more verbose than I feel like it needs to be. In a follow-up I'd like to abbreviate some things and look in to creating aliases for common accessors.
* There is a lingering lifetime hazard between the module and newly added operations. We have the facilities now to solve for this but I will do that in a follow-up.
* We may need to craft a more limited API for safely referencing successors when creating operations. We need more facilities to really prove that out and should defer for now.

Differential Revision: https://reviews.llvm.org/D87996
2020-09-23 07:57:50 -07:00
Stella Laurenzo 4cf754c4bc Implement python iteration over the operation/region/block hierarchy.
* Removes the half-completed prior attempt at region/block mutation in favor of new approach to ownership.
* Will re-add mutation more correctly in a follow-on.
* Eliminates the detached state on blocks and regions, simplifying the ownership hierarchy.
* Adds both iterator and index based access at each level.

Differential Revision: https://reviews.llvm.org/D87982
2020-09-23 07:57:50 -07:00
Stella Laurenzo 7abb0ff7e0 Add Operation to python bindings.
* Fixes a rather egregious bug with respect to the inability to return arbitrary objects from py::init (was causing aliasing of multiple py::object -> native instance).
* Makes Modules and Operations referencable types so that they can be reliably depended on.
* Uniques python operation instances within a context. Opens the door for further accounting.
* Next I will retrofit region and block to be dependent on the operation, and I will attempt to model the API to avoid detached regions/blocks, which will simplify things a lot (in that world, only operations can be detached).
* Added quite a bit of test coverage to check for leaks and reference issues.
* Supercedes: https://reviews.llvm.org/D87213

Differential Revision: https://reviews.llvm.org/D87958
2020-09-23 07:57:50 -07:00
Stella Laurenzo 85185b61b6 First pass on MLIR python context lifetime management.
* Per thread https://llvm.discourse.group/t/revisiting-ownership-and-lifetime-in-the-python-bindings/1769
* Reworks contexts so it is always possible to get back to a py::object that holds the reference count for an arbitrary MlirContext.
* Retrofits some of the base classes to automatically take a reference to the context, elimintating keep_alives.
* More needs to be done, as discussed, when moving on to the operations/blocks/regions.

Differential Revision: https://reviews.llvm.org/D87886
2020-09-18 12:17:50 -07:00
Alex Zinenko 855ec517a3 [mlir] Model StringRef in C API
Numerous MLIR functions return instances of `StringRef` to refer to a
non-owning fragment of a string (usually owned by the context). This is a
relatively simple class that is defined in LLVM. Provide a simple wrapper in
the MLIR C API that contains the pointer and length of the string fragment and
use it for Standard attribute functions that return StringRef instead of the
previous, callback-based mechanism.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D87677
2020-09-16 16:04:36 +02:00
Stella Laurenzo 7403e3ee32 Extend PyConcreteType to support intermediate base classes.
* Resolves todos from D87091.
* Also modifies PyConcreteAttribute to follow suite (should be useful for ElementsAttr and friends).
* Adds a test to ensure that the ShapedType base class functions as expected.

Differential Revision: https://reviews.llvm.org/D87208
2020-09-06 23:39:47 -07:00
zhanghb97 54d432aa6b [mlir] Add Shaped Type, Tensor Type and MemRef Type to python bindings.
Based on the PyType and PyConcreteType classes, this patch implements the bindings of Shaped Type, Tensor Type and MemRef Type subclasses.
The Tensor Type and MemRef Type are bound as ranked and unranked separately.
This patch adds the ***GetChecked C API to make sure the python side can get a valid type or a nullptr.
Shaped type is not a kind of standard types, it is the base class for vectors, memrefs and tensors, this patch binds the PyShapedType class as the base class of Vector Type, Tensor Type and MemRef Type subclasses.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D87091
2020-09-06 11:45:54 -07:00
ZHANG Hongbin 1d99472875 [mlir] Add Complex Type, Vector Type and Tuple Type subclasses to python bindings
Based on the PyType and PyConcreteType classes, this patch implements the bindings of Complex Type, Vector Type and Tuple Type subclasses.
For the convenience of type checking, this patch defines a `mlirTypeIsAIntegerOrFloat` function to check whether the given type is an integer or float type.
These three subclasses in this patch have similar binding strategy:
- The function pointer `isaFunction` points to `mlirTypeIsA***`.
- The `mlir***TypeGet` C API is bound with the `get_***` method in the python side.
- The Complex Type and Vector Type check whether the given type is an integer or float type.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D86785
2020-09-02 05:46:00 +00:00
Stella Laurenzo 2d1362e09a Add Location, Region and Block to MLIR Python bindings.
* This is just enough to create regions/blocks and iterate over them.
* Does not yet implement the preferred iteration strategy (python pseudo containers).
* Refinements need to come after doing basic mappings of operations and values so that the whole hierarchy can be used.

Differential Revision: https://reviews.llvm.org/D86683
2020-08-28 15:26:05 -07:00
zhanghb97 1f6c4d829c [mlir] Add Index Type, Floating Point Type and None Type subclasses to python bindings.
Based on the PyType and PyConcreteType classes, this patch implements the bindings of Index Type, Floating Point Type and None Type subclasses.
These three subclasses share the same binding strategy:
- The function pointer `isaFunction` points to `mlirTypeIsA***`.
- The `mlir***TypeGet` C API is bound with the `***Type` constructor in the python side.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D86466
2020-08-24 18:54:54 +00:00
Stella Laurenzo 3137c29926 Add initial python bindings for attributes.
* Generic mlir.ir.Attribute class.
* First standard attribute (mlir.ir.StringAttr), following the same pattern as generic vs standard types.
* NamedAttribute class.

Differential Revision: https://reviews.llvm.org/D86250
2020-08-23 22:16:23 -07:00
Alex Zinenko da56297462 [mlir] expose standard attributes to C API
Provide C API for MLIR standard attributes. Since standard attributes live
under lib/IR in core MLIR, place the C APIs in the IR library as well (standard
ops will go in a separate library).

Affine map and integer set attributes are only exposed as placeholder types
with IsA support due to the lack of C APIs for the corresponding types.

Integer and floating point attribute APIs expecting APInt and APFloat are not
exposed pending decision on how to support APInt and APFloat.

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D86143
2020-08-19 18:50:19 +02:00
Stella Laurenzo d29d1e2ffd Add python bindings for Type and IntegerType.
* The binding for Type is trivial and should be non-controversial.
* The way that I define the IntegerType should serve as a pattern for what I want to do next.
* I propose defining the rest of the standard types in this fashion and then generalizing for dialect types as necessary.
* Essentially, creating/accessing a concrete Type (vs interacting with the string form) is done by "casting" to the concrete type (i.e. IntegerType can be constructed with a Type and will throw if the cast is illegal).
* This deviates from some of our previous discussions about global objects but I think produces a usable API and we should go this way.

Differential Revision: https://reviews.llvm.org/D86179
2020-08-19 09:23:44 -07:00
Stella Laurenzo 95b77f2eac Adds __str__ support to python mlir.ir.MlirModule.
* Also raises an exception on parse error.
* Removes placeholder smoketest.
* Adds docstrings.

Differential Revision: https://reviews.llvm.org/D86046
2020-08-17 09:46:33 -07:00
zhanghb97 fcd2969da9 Initial MLIR python bindings based on the C API.
* Basic support for context creation, module parsing and dumping.

Differential Revision: https://reviews.llvm.org/D85481
2020-08-16 19:34:25 -07:00
Stella Laurenzo 722475a375 Initial boiler-plate for python bindings.
Summary:
* Native '_mlir' extension module.
* Python mlir/__init__.py trampoline module.
* Lit test that checks a message.
* Uses some cmake configurations that have worked for me in the past but likely needs further elaboration.

Subscribers: mgorny, mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, stephenneuendorffer, Joonsoo, grosul1, Kayjukh, jurahul, msifontes

Tags: #mlir

Differential Revision: https://reviews.llvm.org/D83279
2020-07-09 12:03:58 -07:00