Commit Graph

138 Commits

Author SHA1 Message Date
Nicolas Vasilache 72040bf7c8 Update Linalg to use std.view
Now that a view op has graduated to the std dialect, we can update Linalg to use it and remove ops that have become obsolete. As a byproduct, the linalg buffer and associated ops can also disappear.

PiperOrigin-RevId: 279073591
2019-11-07 06:33:10 -08:00
Nicolas Vasilache 9e7e297da3 Lower vector transfer ops to loop.for operations.
This allows mixing linalg operations with vector transfer operations (with additional modifications to affine ops) and is a step towards solving tensorflow/mlir#189.

PiperOrigin-RevId: 275543361
2019-10-18 14:10:10 -07:00
Nicolas Vasilache 5b03e692f6 Decouple Linalg promotion from Linalg tiling - NFC
This CL creates a new Linalg promotion pass that operates on SubViewOp and decouples it from Linalg tiling. This is mostly moving code around.

PiperOrigin-RevId: 275329213
2019-10-17 13:41:17 -07:00
Nicolas Vasilache 31c5a41a30 Consistent use of int in mlir_runner_utils.cpp
This should fix the OSS build by only using int in template types.

PiperOrigin-RevId: 274843584
2019-10-15 11:04:45 -07:00
Nicolas Vasilache abf5c60af9 Add conversion for splat of vectors of 2+D
This CL adds a missing lowering for splat of multi-dimensional vectors.
Additional support is also added to the runtime utils library to allow printing memrefs with such vectors.

PiperOrigin-RevId: 274794723
2019-10-15 06:53:08 -07:00
Alex Zinenko 5e7959a353 Use llvm.func to define functions with wrapped LLVM IR function type
This function-like operation allows one to define functions that have wrapped
LLVM IR function type, in particular variadic functions. The operation was
added in parallel to the existing lowering flow, this commit only switches the
flow to use it.

Using a custom function type makes the LLVM IR dialect type system more
consistent and avoids complex conversion rules for functions that previously
had to use the built-in function type instead of a wrapped LLVM IR dialect type
and perform conversions during the analysis.

PiperOrigin-RevId: 273910855
2019-10-10 01:34:06 -07:00
Nicolas Vasilache 171637d4f0 Fix Windows linkage error
This CL fixes bad macro names usage in mlir_runner_utils.h.
The macro mlir_runner_utils_EXPORTS now matches what is defined in CMakeLists.txt.

PiperOrigin-RevId: 273773931
2019-10-09 10:38:31 -07:00
Nicolas Vasilache 3b4f133fb7 Start a minimal mlir_utils runtime library for testing debugging purposes
Now that MLIR has a standardized StridedMemRef descriptor, it becomes very easy to interact with external library functions and build utilities directly in C++.
This CL introduces basic printing support in a libmlir_utils.so.
Unit tests are rewritten using this feature and also to improve coverage.

For now, C mandates that we have a unique function for each MemRef element type and rank.
In a future a simple unranked descriptor can be introduced to only require uniqu'ing by element type.

PiperOrigin-RevId: 273304741
2019-10-07 09:06:55 -07:00
Nicolas Vasilache e36337a998 Unify Linalg types by using strided memrefs
This CL finishes the implementation of the Linalg + Affine type unification of the [strided memref RFC](https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio).
As a consequence, the !linalg.view type, linalg::DimOp, linalg::LoadOp and linalg::StoreOp can now disappear and Linalg can use standard types everywhere.

PiperOrigin-RevId: 272187165
2019-10-01 05:23:21 -07:00
Nicolas Vasilache 6543e99fe5 Fix JitRunner.cpp Error creation pattern and reactivate tests.
linalg_integration_test.mlir and simple.mlir were temporarily disabled due to an OSS-only failure.

The issue is that, once created, an llvm::Error must be explicitly checked before it can be discarded or overwritten.

This CL fixes the issue and reenable the test.

PiperOrigin-RevId: 271589651
2019-09-27 09:56:40 -07:00
Jacques Pienaar 7385d87895 Disable failing tests
PiperOrigin-RevId: 271460509
2019-09-26 16:42:35 -07:00
Alex Zinenko 99be3351b8 Drop support for memrefs from JitRunner
The support for functions taking and returning memrefs of floats was introduced
in the first version of the runner, created before MLIR had reliable lowering
of allocation/deallocation to library calls.  It forcibly runs MLIR
transformation convering affine, loop and standard dialects into the LLVM
dialect, unlike the other runner flows that accept the LLVM dialect directly.
Memref support leads to more complex layering and is generally fragile.  Drop
it in favor of functions returning a scalar, or library-based function calls to
print memrefs and other data structures.

PiperOrigin-RevId: 271330839
2019-09-26 05:42:01 -07:00
Mehdi Amini 765d60fd4d Add missing lowering to CFG in mlir-cpu-runner + related cleanup
- the list of passes run by mlir-cpu-runner included -lower-affine and
  -lower-to-llvm but was missing -lower-to-cfg (because -lower-affine at
  some point used to lower straight to CFG); add -lower-to-cfg in
  between. IR with affine ops can now be run by mlir-cpu-runner.

- update -lower-to-cfg to be consistent with other passes (create*Pass methods
  were changed to return unique ptrs, but -lower-to-cfg appears to have been
  missed).

- mlir-cpu-runner was unable to parse custom form of affine op's - fix
  link options

- drop unnecessary run options from test/mlir-cpu-runner/simple.mlir
  (none of the test cases had loops)

- -convert-to-llvmir was changed to -lower-to-llvm at some point, but the
  create pass method name wasn't updated (this pass converts/lowers to LLVM
  dialect as opposed to LLVM IR). Fix this.

(If we prefer "convert", the cmd-line options could be changed to
"-convert-to-llvm/cfg" then.)

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#115

PiperOrigin-RevId: 266666909
2019-09-01 11:33:22 -07:00
Jacques Pienaar 06e8101034 Add mechanism to dump JIT-compiled objects to files
This commit introduces the bits to be able to dump JIT-compile
objects to external files by passing an object cache to OrcJit.
The new functionality is tested in mlir-cpu-runner under the flag
`dump-object-file`.

Closes tensorflow/mlir#95

PiperOrigin-RevId: 266439265
2019-08-30 13:02:10 -07:00
Nicolas Vasilache 7f42b3d721 Add lowering of linalg.copy to an external C++ library and a test.
This CL extends support for lowering of linalg to external C++ libraries with CopyOp. Currently this can only work when the permutation maps in the copies are identity. Future support for permutations will be added later.

PiperOrigin-RevId: 265093025
2019-08-23 11:09:53 -07:00
Nicolas Vasilache 36f48063dd Add alignment support to linalg.buffer_alloc
This CL adds an integer attribute to linalg.buffer_alloc and lowering to LLVM.
The alignment is constrained to be a positive power of 2.

Lowering to LLVM produces the pattern:
```
%[[alloc:.*]] = llvm.call @malloc(%[[s]]) : (!llvm.i64) -> !llvm<"i8*">
%[[cast:.*]] = llvm.bitcast %[[alloc]] : !llvm<"i8*"> to !llvm.i64
%[[rem:.*]] = llvm.urem %[[cast]], %[[c16]] : !llvm.i64
%[[drem:.*]] = llvm.sub %[[c16]], %[[rem]] : !llvm.i64
%[[off:.*]] = llvm.urem %[[drem]], %[[c16]] : !llvm.i64
llvm.getelementptr %{{.*}}[%[[off]]] : (!llvm<"i8*">, !llvm.i64) -> !llvm<"i8*">
```

where `ptr` is aligned on `align` by computing the address
`ptr + (align - ptr % align) % align`.

To allow dealloc op to still be able to free memory, additional information is needed in
the buffer type. The buffer type is thus extended with an extra i8* for the base allocation address.

PiperOrigin-RevId: 264244455
2019-08-19 14:37:18 -07:00
Nicolas Vasilache 9bf69e6a2e Refactor linalg lowering to LLVM
The linalg.view type used to be lowered to a struct containing a data pointer, offset, sizes/strides information. This was problematic when passing to external functions due to ABI, struct padding and alignment issues.

The linalg.view type is now lowered to LLVMIR as a *pointer* to a struct containing the data pointer, offset and sizes/strides. This simplifies the interfacing with external library functions and makes it trivial to add new functions without creating a shim that would go from a value type struct to a pointer type.

The consequences are that:
1. lowering explicitly uses llvm.alloca in lieu of llvm.undef and performs the proper llvm.load/llvm.store where relevant.
2. the shim creation function `getLLVMLibraryCallDefinition` disappears.
3. views are passed by pointer, scalars are passed by value. In the future, other structs will be passed by pointer (on a per-need basis).

PiperOrigin-RevId: 264183671
2019-08-19 10:21:40 -07:00
Nicolas Vasilache 59b473c231 External library name mangling support for linalg.
This CL introduces the ability to generate the external library name for Linalg operations.
The problem is that neither mlir or C support overloading and we want a simplified form of name mangling that is still reasonable to read.
This CL creates the name of the external call that Linalg expects from the operation name and the type of its arguments.

The interface library names are updated and use new cases are added for FillOp.

PiperOrigin-RevId: 262556833
2019-08-09 07:33:58 -07:00
Nicolas Vasilache 1304331926 Automated rollback of commit 3708f53219
PiperOrigin-RevId: 260136255
2019-07-26 11:05:17 -07:00
Nicolas Vasilache 3708f53219 Add sgemm specializations - NFC
This CL adds a few specializations for sgemm.
A minor change to alpha is made in cblas_interface.cpp to be compatible with actual BLAS calls.

For now this is for internal testing purposes only.

PiperOrigin-RevId: 260129027
2019-07-26 05:41:23 -07:00
Nicolas Vasilache 00b48e1a9f Fix linalg_matmul_impl interfacing with sgemm
This CL provides a fix that makes linal_matmul_impl compliant with the BLAS interface. Before this CL it would compute either C += A * B when called with cblas.cpp:cblas_sgemm implementation and C = A * B with other implementations.

PiperOrigin-RevId: 260117367
2019-07-26 03:34:21 -07:00
Nicolas Vasilache e78ea03b24 Replace linalg.for by loop.for
With the introduction of the Loop dialect, uses of the `linalg.for` operation can now be subsumed 1-to-1 by `loop.for`.
This CL performs the replacement and tests are updated accordingly.

PiperOrigin-RevId: 258322565
2019-07-16 13:44:57 -07:00
Nicolas Vasilache cab671d166 Lower affine control flow to std control flow to LLVM dialect
This CL splits the lowering of affine to LLVM into 2 parts:
1. affine -> std
2. std -> LLVM

The conversions mostly consists of splitting concerns between the affine and non-affine worlds from existing conversions.
Short-circuiting of affine `if` conditions was never tested or exercised and is removed in the process, it can be reintroduced later if needed.

LoopParametricTiling.cpp is updated to reflect the newly added ForOp::build.

PiperOrigin-RevId: 257794436
2019-07-12 08:44:28 -07:00
Mahesh Ravishankar 25094e90bd Resolving buffer operand of linalg.view doesnt have the information
about the buffer size. This is needed to resolve the operand
correctly. Add that information to view op
serialization/deserialization

Also modify the parsing of buffer type by splitting at 'x' to
side-step issues with StringRef number parsing.

PiperOrigin-RevId: 256188319
2019-07-02 10:28:59 -07:00
Mahesh Ravishankar 266841751f Add buffer size information to Linalg::BufferType. If the size is
constant then it is represented as <size x elementType>. If the size
is not a compile time constant, then it is represented as
<? x elementType>.

PiperOrigin-RevId: 255619400
2019-06-28 10:10:17 -07:00
Lei Zhang e31c47ee8b Export symbols in cpu runner cblas library
By default MSVC does not export any symbol and does not create a companion
.lib for a .dll. This will cause problems when trying to link against the
library.

PiperOrigin-RevId: 254033454
2019-06-19 23:07:54 -07:00
Mahesh Ravishankar 54b35cec08 Add a definition of the library function to use when Linalg ops are
lowered to LLVM, instead of expecting one to exist in the Module

PiperOrigin-RevId: 253097382
2019-06-19 23:01:12 -07:00
Nicolas Vasilache a8a4d35d3f Add a lowering for Linalg matmul to LLVM
This CL adds a lowering to LLVM for MamulOp and a corresponding integration test.

View descriptor manipulation is moved from MLIR's LLVM dialect to C++ code compiled on the side. To this end a separation is introduced between `cblas.cpp` and `cblas_interface.cpp`, the latter operating on view types whose ABI correspond to the LLVM signature generated by MLIR.

An intermediary step is introduced that allocates a new descriptor on the MLIR side for the purpose of passing it to LLVM. The reason for this extra step is that the ABI for by-value ViewType objects wants aligned descriptors, e.g.:
```
extern "C" void linalg_dot_impl(ViewType<float, 1> X, ViewType<float, 1> Y,
                                BaseViewType<float> Z) {
   ...
}
```
produces LLVM IR with the signature:
```
%struct.ViewType = type { %struct.BaseViewType, [1 x i64], [1 x i64] }
%struct.BaseViewType = type { float*, i64 }

define void @linalg_dot_impl(%struct.ViewType* byval align 8, %struct.ViewType* byval align 8, float*, i64) tensorflow/mlir#0 {
...
}
```

We don't seem to be able to make such aligned  allocations in the MLIR -> LLVM converter atm.
Going through a level of indirection allows the test to pass.
The temporary tradeoff is that the MLIR shims have to be written by hand.
They will disappear in the future.

PiperOrigin-RevId: 252670672
2019-06-19 22:58:46 -07:00
River Riddle 1ebbb135cc Disable the mlir-cpu-runner tests on win32. llvm orc does not support the COFF rtld.
--

PiperOrigin-RevId: 250556116
2019-06-01 20:08:12 -07:00
Nicolas Vasilache 0eac031fac Add lowering linalg.for to LLVM IR
This CL adds lowering of linalg.for to LLVM IR and adds an IR test.
    This also replaces the usage of affine.for with linalg.for and enables the LLVM IR path in the integration test.

--

PiperOrigin-RevId: 250503798
2019-06-01 20:06:40 -07:00
Mehdi Amini 70f85c0bbf Fix MacOS test: use %shlibext in lit command line to expand to .dylib on MacOS and .so on Linux
--

PiperOrigin-RevId: 249113478
2019-05-20 13:50:19 -07:00
Nicolas Vasilache 6aa5cc8b06 Cleanup linalg integration test
This CL performs post-commit cleanups.
    It adds the ability to specify which shared libraries to load dynamically in ExecutionEngine. The linalg integration test is updated to use a shared library.
    Additional minor cleanups related to LLVM lowering of Linalg are also included.

--

PiperOrigin-RevId: 248346589
2019-05-20 13:43:13 -07:00
Nicolas Vasilache 5c64d2a6c4 Pipe Linalg to a cblas call via mlir-cpu-runner
This CL extends the execution engine to allow the additional resolution of symbols names
    that have been registered explicitly. This allows linking static library symbols that have not been explicitly exported with the -rdynamic linking flag (which is deemed too intrusive).

--

PiperOrigin-RevId: 247969504
2019-05-20 13:39:02 -07:00
Nicolas Vasilache 33449c3e6c Pipe Linalg to LLVM via mlir-cpu-runner
This CL adds support for functions in the Linalg dialect to run with mlir-cpu-runner.
    For this purpose, this CL adds BufferAllocOp, BufferDeallocOp, LoadOp and StoreOp to the Linalg dialect as well as their lowering to LLVM. To avoid collisions with mlir::LoadOp/StoreOp (which should really become mlir::affine::LoadOp/StoreOp), the mlir::linalg namespace is added.

    The execution uses a dummy linalg_dot function that just returns for now. In the future a proper library call will be used.

--

PiperOrigin-RevId: 247476061
2019-05-10 19:26:18 -07:00
Dimitrios Vytiniotis 79bd6badb2 Remove global LLVM CLI variables from library code
Plus move parsing code into the MLIR CPU runner binary.

PiperOrigin-RevId: 240786709
2019-03-29 17:50:23 -07:00
Alex Zinenko d9cc3c31cc ExecutionEngine OptUtils: support -On flags in string-based initialization
Original implementation of OutUtils provided two different LLVM IR module
transformers to be used with the MLIR ExecutionEngine: OptimizingTransformer
parameterized by the optimization levels (similar to -O3 flags) and
LLVMPassesTransformer parameterized by the string formatted similarly to
command line options of LLVM's "opt" tool without support for -O* flags.
Introduce such support by declaring the flags inside the parser and by
populating the pass managers similarly to what "opt" does.  Remove the
additional flags from mlir-cpu-runner as they can now be wrapped into
`-llvm-opts` together with other LLVM-related flags.

PiperOrigin-RevId: 236107292
2019-03-29 16:49:44 -07:00
Alex Zinenko 4bb31f7377 ExecutionEngine: provide utils for running CLI-configured LLVM passes
A recent change introduced a possibility to run LLVM IR transformation during
JIT-compilation in the ExecutionEngine.  Provide helper functions that
construct IR transformers given either clang-style optimization levels or a
list passes to run.  The latter wraps the LLVM command line option parser to
parse strings rather than actual command line arguments.  As a result, we can
run either of

    mlir-cpu-runner -O3 input.mlir
    mlir-cpu-runner -some-mlir-pass -llvm-opts="-llvm-pass -other-llvm-pass"

to combine different transformations.  The transformer builder functions are
provided as a separate library that depends on LLVM pass libraries unlike the
main execution engine library.  The library can be used for integrating MLIR
execution engine into external frameworks.

PiperOrigin-RevId: 234173493
2019-03-29 16:29:41 -07:00
Alex Zinenko 5a4403787f Simple CPU runner
This implements a simple CPU runner based on LLVM Orc JIT.  The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly.  Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.

For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation.  In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes.  This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.

Provide a binary for the runner and a test that exercises it.

PiperOrigin-RevId: 230876363
2019-03-29 15:36:08 -07:00