mlir.dialects._shape_ops_gen ============================ .. py:module:: mlir.dialects._shape_ops_gen Attributes ---------- .. autoapisummary:: mlir.dialects._shape_ops_gen._ods_ir Classes ------- .. autoapisummary:: mlir.dialects._shape_ops_gen._Dialect mlir.dialects._shape_ops_gen.AddOp mlir.dialects._shape_ops_gen.AnyOp mlir.dialects._shape_ops_gen.AssumingAllOp mlir.dialects._shape_ops_gen.AssumingOp mlir.dialects._shape_ops_gen.AssumingYieldOp mlir.dialects._shape_ops_gen.BroadcastOp mlir.dialects._shape_ops_gen.ConcatOp mlir.dialects._shape_ops_gen.ConstShapeOp mlir.dialects._shape_ops_gen.ConstSizeOp mlir.dialects._shape_ops_gen.ConstWitnessOp mlir.dialects._shape_ops_gen.CstrBroadcastableOp mlir.dialects._shape_ops_gen.CstrEqOp mlir.dialects._shape_ops_gen.CstrRequireOp mlir.dialects._shape_ops_gen.DebugPrintOp mlir.dialects._shape_ops_gen.DimOp mlir.dialects._shape_ops_gen.DivOp mlir.dialects._shape_ops_gen.FromExtentTensorOp mlir.dialects._shape_ops_gen.FromExtentsOp mlir.dialects._shape_ops_gen.FuncOp mlir.dialects._shape_ops_gen.FunctionLibraryOp mlir.dialects._shape_ops_gen.GetExtentOp mlir.dialects._shape_ops_gen.IndexToSizeOp mlir.dialects._shape_ops_gen.IsBroadcastableOp mlir.dialects._shape_ops_gen.MaxOp mlir.dialects._shape_ops_gen.MeetOp mlir.dialects._shape_ops_gen.MinOp mlir.dialects._shape_ops_gen.MulOp mlir.dialects._shape_ops_gen.NumElementsOp mlir.dialects._shape_ops_gen.RankOp mlir.dialects._shape_ops_gen.ReduceOp mlir.dialects._shape_ops_gen.ReturnOp mlir.dialects._shape_ops_gen.ShapeEqOp mlir.dialects._shape_ops_gen.ShapeOfOp mlir.dialects._shape_ops_gen.SizeToIndexOp mlir.dialects._shape_ops_gen.SplitAtOp mlir.dialects._shape_ops_gen.ToExtentTensorOp mlir.dialects._shape_ops_gen.ValueAsShapeOp mlir.dialects._shape_ops_gen.ValueOfOp mlir.dialects._shape_ops_gen.WithOp mlir.dialects._shape_ops_gen.YieldOp Functions --------- .. autoapisummary:: mlir.dialects._shape_ops_gen.add mlir.dialects._shape_ops_gen.any mlir.dialects._shape_ops_gen.assuming_all mlir.dialects._shape_ops_gen.assuming mlir.dialects._shape_ops_gen.assuming_yield mlir.dialects._shape_ops_gen.broadcast mlir.dialects._shape_ops_gen.concat mlir.dialects._shape_ops_gen.const_shape mlir.dialects._shape_ops_gen.const_size mlir.dialects._shape_ops_gen.const_witness mlir.dialects._shape_ops_gen.cstr_broadcastable mlir.dialects._shape_ops_gen.cstr_eq mlir.dialects._shape_ops_gen.cstr_require mlir.dialects._shape_ops_gen.debug_print mlir.dialects._shape_ops_gen.dim mlir.dialects._shape_ops_gen.div mlir.dialects._shape_ops_gen.from_extent_tensor mlir.dialects._shape_ops_gen.from_extents mlir.dialects._shape_ops_gen.func mlir.dialects._shape_ops_gen.function_library mlir.dialects._shape_ops_gen.get_extent mlir.dialects._shape_ops_gen.index_to_size mlir.dialects._shape_ops_gen.is_broadcastable mlir.dialects._shape_ops_gen.max mlir.dialects._shape_ops_gen.meet mlir.dialects._shape_ops_gen.min mlir.dialects._shape_ops_gen.mul mlir.dialects._shape_ops_gen.num_elements mlir.dialects._shape_ops_gen.rank mlir.dialects._shape_ops_gen.reduce mlir.dialects._shape_ops_gen.return_ mlir.dialects._shape_ops_gen.shape_eq mlir.dialects._shape_ops_gen.shape_of mlir.dialects._shape_ops_gen.size_to_index mlir.dialects._shape_ops_gen.split_at mlir.dialects._shape_ops_gen.to_extent_tensor mlir.dialects._shape_ops_gen.value_as_shape mlir.dialects._shape_ops_gen.value_of mlir.dialects._shape_ops_gen.with_shape mlir.dialects._shape_ops_gen.yield_ Module Contents --------------- .. py:data:: _ods_ir .. py:class:: _Dialect(descriptor: object) Bases: :py:obj:`_ods_ir` .. py:attribute:: DIALECT_NAMESPACE :value: 'shape' .. py:class:: AddOp(lhs, rhs, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Adds two sizes or indices. If either operand is an error it will be propagated to the result. The operands can be of type ``size`` or ``index``. If at least one of the operands can hold an error, i.e. if it is of type ``size``, the result must be of type ``size``. If error propagation is not possible because both operands are of type ``index`` then the result may be of type ``size`` or ``index``. .. py:attribute:: OPERATION_NAME :value: 'shape.add' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: add(lhs, rhs, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: AnyOp(result, inputs, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` This operation takes multiple input shapes or extent tensors and returns some combination of their dimensions. This can be best seen with examples below. The result is undefined, but still side-effect free, in cases where the inputs have differing ranks or differ in extents of shared dimensions. Example: .. code:: mlir %s0 = shape.any [2,?], [?,3] // [2,3] %s1 = shape.any [?,?], [1,2] // [1,2] .. py:attribute:: OPERATION_NAME :value: 'shape.any' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: inputs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: any(result, inputs, *, loc=None, ip=None) -> _ods_ir .. py:class:: AssumingAllOp(inputs, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Used to simplify constraints as any single failing precondition is enough to prevent execution. "assuming" operations represent an execution order restriction to the compiler, information for dependent code to rely on (by assuming), and nothing else. They should not exist after a program is fully lowered and ready to execute. Example: .. code:: mlir %w0 = shape.cstr_broadcastable [2,2], [3,1,2] // Passing %w1 = shape.cstr_broadcastable [2,2], [3,2] // Failure %w2 = shape.cstr_eq [1,2], [1,2], [1,2] // Passing %wf = shape.assuming_all %w0, %w1 // Failure %wt = shape.assuming_all %w0, %w2 // Passing .. py:attribute:: OPERATION_NAME :value: 'shape.assuming_all' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: inputs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: assuming_all(inputs, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: AssumingOp(results_, witness, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Executes the region assuming all witnesses are true. "assuming" operations represent an execution order restriction to the compiler, information for dependent code to rely on (by assuming), and nothing else. They should not exist after a program is fully lowered and ready to execute. .. py:attribute:: OPERATION_NAME :value: 'shape.assuming' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: witness() -> _ods_ir .. py:method:: results_() -> _ods_ir .. py:method:: doRegion() -> _ods_ir .. py:function:: assuming(results_, witness, *, loc=None, ip=None) -> Union[_ods_ir, _ods_ir, AssumingOp] .. py:class:: AssumingYieldOp(operands_, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` This yield operation represents a return operation within the ``shape.assuming`` operation region. The operation takes variable number of operands and produces no results. The operand number and types must match the number and types of parent ``shape.assuming`` results. .. py:attribute:: OPERATION_NAME :value: 'shape.assuming_yield' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operands_() -> _ods_ir .. py:function:: assuming_yield(operands_, *, loc=None, ip=None) -> AssumingYieldOp .. py:class:: BroadcastOp(result, shapes, *, error=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Returns the broadcasted shape for input shapes or extent tensors. The rest of this description is simplified for the 2 input case but can be extended to more inputs. Both operands can be of type ``shape.shape`` or ``tensor``. The result is of type ``shape.shape`` and, if both operands are tensors, may be of type ``tensor``. If the two operand shapes are of different rank the smaller one is padded with 1's from the left. The resulting broadcasted shape is then defined as .. code:: result[i] = lhs[i] if lhs[i] == rhs[i] = lhs[i] if rhs[i] == 1 = rhs[i] if lhs[i] == 1. In case the resulting shape is undefined, i.e. if corresponding extents are different from each other but none is 1, the result is an error shape. Likewise error values are propagated if any of the operands holds an error value. If the result type is an extent tensor (and can therefore not hold the error value) the behavior may be undefined. The optional string attribute can be used to describe the error case. .. py:attribute:: OPERATION_NAME :value: 'shape.broadcast' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shapes() -> _ods_ir .. py:method:: error() -> Optional[_ods_ir] .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: broadcast(result, shapes, *, error=None, loc=None, ip=None) -> _ods_ir .. py:class:: ConcatOp(result, lhs, rhs, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Creates a shape whose dimensions consist of first the dimensions from ``lhs`` followed by the dimensions of ``rhs``. Example: concat([2,3], [4,5]) -> [2,3,4,5] concat([], []) -> [] concat([], [4,5,6]) -> [4,5,6] .. py:attribute:: OPERATION_NAME :value: 'shape.concat' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: concat(result, lhs, rhs, *, loc=None, ip=None) -> _ods_ir .. py:class:: ConstShapeOp(shape, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Creates a constant shape or extent tensor. The individual extents are given as the ``shape`` attribute. The number of these values equals the shape's rank. .. code:: mlir %0 = shape.const_shape [] : !shape.shape %1 = shape.const_shape [1, 2, 3] : !shape.shape %2 = shape.const_shape [4, 5, 6] : tensor<3xindex> .. py:attribute:: OPERATION_NAME :value: 'shape.const_shape' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shape() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: const_shape(shape, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: ConstSizeOp(value, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Creates a ``shape.size`` type representing the constant size given by ``value``. .. code:: mlir %x = shape.const_size 10 .. py:attribute:: OPERATION_NAME :value: 'shape.const_size' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: value() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: const_size(value, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: ConstWitnessOp(passing, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` This operation represents a statically known witness result. This can be often used to canonicalize/fold constraint and assuming code that will always pass. .. code:: mlir %0 = shape.const_shape [1,2,3] %1 = shape.const_shape [1,2,3] %w0 = shape.cstr_eq(%0, %1) // Can be folded to "const_witness true" %w1 = shape.const_witness true %w2 = shape.assuming_all(%w0, %w2) // Can be folded to "const_witness true" .. py:attribute:: OPERATION_NAME :value: 'shape.const_witness' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: passing() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: const_witness(passing, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: CstrBroadcastableOp(shapes, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Given input shapes or extent tensors, return a witness specifying if they are broadcastable. This broadcastable follows the same logic as what shape.broadcast documents. "cstr" operations represent runtime assertions. Example: .. code:: mlir %w0 = shape.cstr_broadcastable [2,2], [3,1,2] // Passing %w1 = shape.cstr_broadcastable [2,2], [3,2] // Failure .. py:attribute:: OPERATION_NAME :value: 'shape.cstr_broadcastable' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shapes() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: cstr_broadcastable(shapes, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: CstrEqOp(shapes, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Given 1 or more input shapes, determine if all shapes are the exact same. "cstr" operations represent runtime assertions. Example: .. code:: mlir %w0 = shape.cstr_eq [1,2], [1,2], [1,2] // Passing %w1 = shape.cstr_eq [2,2], [1,2] // Failure .. py:attribute:: OPERATION_NAME :value: 'shape.cstr_eq' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shapes() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: cstr_eq(shapes, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: CstrRequireOp(pred, msg, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Represents a runtime assertion that an i1 is true. It returns a !shape.witness to order this assertion. For simplicity, prefer using other cstr_* ops if they are available for a given constraint. Example: .. code:: mlir %bool = ... %w0 = shape.cstr_require %bool, "msg" // Passing if `%bool` is true. Since this op can be used to express many different possible assertions (depending on whatever computation calculated ``pred``), the ``msg`` should clarify the nature of the assertion for users. .. py:attribute:: OPERATION_NAME :value: 'shape.cstr_require' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: pred() -> _ods_ir .. py:method:: msg() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: cstr_require(pred, msg, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: DebugPrintOp(output, input, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Prints the input dim or shape and passes through input. Note: This is intended for testing and debugging only. .. py:attribute:: OPERATION_NAME :value: 'shape.debug_print' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: input() -> _ods_ir .. py:method:: output() -> _ods_ir .. py:function:: debug_print(output, input, *, loc=None, ip=None) -> _ods_ir .. py:class:: DimOp(value, index, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Gets the extent indexed by ``dim`` from the shape of the ``value`` operand. If the index is error or out-of-bound then it returns an invalid size if the return type carries error information else the behavior is undefined. This is a convenience op that performs the equivalent of getting the extent of a shape (e.g., ``dim(x, i) == get_extent(shape_of(x), i)``). .. py:attribute:: OPERATION_NAME :value: 'shape.dim' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: value() -> _ods_ir .. py:method:: index() -> _ods_ir .. py:method:: extent() -> _ods_ir .. py:function:: dim(value, index, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: DivOp(lhs, rhs, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Divides two sizes or indices. If either operand is an error it will be propagated to the result. The operands can be of type ``size`` or ``index``. If at least one of the operands can hold an error, i.e. if it is of type ``size``, the result must be of type ``size``. If error propagation is not possible because both operands are of type ``index`` then the result may be of type ``size`` or ``index``. If both operands and result are of type ``index``, their runtime values could be negative. The result is rounded toward negative infinity, i.e. floor(lhs / rhs), such that .. code:: div(lhs, rhs) * rhs + mod(lhs, rhs) = lhs always holds. If any of the values is of type ``size``, the behavior for negative value is undefined. .. py:attribute:: OPERATION_NAME :value: 'shape.div' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: div(lhs, rhs, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: FromExtentTensorOp(input, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Creates a shape from a 1D integral tensor of extents. The rank of the resulting shape equals the number of elements in the tensor, and the extents match the values of the elements. .. py:attribute:: OPERATION_NAME :value: 'shape.from_extent_tensor' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: input() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: from_extent_tensor(input, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: FromExtentsOp(extents, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Creates a shape from multiple SSA values representing the extents of the shape. .. code:: mlir // Rank 2 shape. %s0 = shape.from_extents %a, %b // Rank 0 shape. %s1 = shape.from_extents .. py:attribute:: OPERATION_NAME :value: 'shape.from_extents' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: extents() -> _ods_ir .. py:method:: shape() -> _ods_ir .. py:function:: from_extents(extents, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: FuncOp(sym_name, function_type, *, arg_attrs=None, res_attrs=None, sym_visibility=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` An operation with a name containing a single ``SSACFG`` region which represents a shape transfer function or helper function for shape transfer function. .. py:attribute:: OPERATION_NAME :value: 'shape.func' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: sym_name() -> _ods_ir .. py:method:: function_type() -> _ods_ir .. py:method:: arg_attrs() -> Optional[_ods_ir] .. py:method:: res_attrs() -> Optional[_ods_ir] .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: body() -> _ods_ir .. py:function:: func(sym_name, function_type, *, arg_attrs=None, res_attrs=None, sym_visibility=None, loc=None, ip=None) -> FuncOp .. py:class:: FunctionLibraryOp(sym_name, mapping, *, sym_visibility=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Represents a list of shape functions and the ops whose shape transfer functions they represent. Example: .. code:: mlir shape.function_library { func @same_result_shape(%arg: !shape.value_shape) -> !shape.shape { %0 = shape_of %arg : !shape.value_shape -> !shape.shape return %0 : !shape.shape } } mapping { std.atan = @same_result_shape } .. py:attribute:: OPERATION_NAME :value: 'shape.function_library' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: mapping() -> _ods_ir .. py:method:: body() -> _ods_ir .. py:function:: function_library(sym_name, mapping, *, sym_visibility=None, loc=None, ip=None) -> FunctionLibraryOp .. py:class:: GetExtentOp(shape, dim, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Gets the extent indexed by ``dim`` from the ``shape`` operand. If the shape is an error then it returns an invalid size. .. py:attribute:: OPERATION_NAME :value: 'shape.get_extent' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shape() -> _ods_ir .. py:method:: dim() -> _ods_ir .. py:method:: extent() -> _ods_ir .. py:function:: get_extent(shape, dim, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: IndexToSizeOp(arg, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Converts a standard index to a ``shape.size``. This operation and its inverse, ``size_to_index``, facilitate index conversion between the standard and the shape dialect. The behavior is undefined for negative indices. .. py:attribute:: OPERATION_NAME :value: 'shape.index_to_size' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: index_to_size(arg, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: IsBroadcastableOp(shapes, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Given multiple input shapes or extent tensors, return a predicate specifying if they are broadcastable. This broadcastable follows the same logic as what shape.broadcast documents. Concretely, shape.is_broadcastable returning true implies that shape.broadcast will not give an error, and shape.cstr_broadcastable will not result in an assertion failure. Similarly, false implies an error or assertion failure. Example: .. code:: mlir %true = shape.is_broadcastable [2,2], [3,1,2] %false = shape.is_broadcastable [2,2], [3,2] .. py:attribute:: OPERATION_NAME :value: 'shape.is_broadcastable' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shapes() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: is_broadcastable(shapes, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: MaxOp(lhs, rhs, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Computes the elementwise maximum of two sizes or shapes with equal ranks. If either operand is an error, then an error will be propagated to the result. If the input types mismatch or the ranks do not match, then the result is an error. .. py:attribute:: OPERATION_NAME :value: 'shape.max' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: max(lhs, rhs, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: MeetOp(arg0, arg1, *, error=None, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` An operation that computes the least general shape or dim of input operands. This effectively asserts that corresponding static dimensions are equal. The behavior is to match each element of the shape/size and propagate the most restrictive information, returning an invalid shape if there are contradictory requirements. E.g., using pseudo code .. code:: shape.meet([*], [*]) -> [*] shape.meet([*], [1, ?]) -> [1, ?] shape.meet([1, 2], [1, ?]) -> [1, 2] shape.meet([*], [1, 2]) -> [1, 2] shape.meet([], []) -> [] shape.meet([], [*]) -> [] shape.meet([], [?, ?]) -> [invalid] shape.meet([1, ?], [2, ?, ?]) -> [invalid] ``shape.meet`` also allows specifying an optional error string, that may be used to return an error to the user upon mismatch of dimensions. .. code:: mlir %c = shape.meet %a, %b, error="" : !shape.shape, !shape.shape -> !shape.shape .. py:attribute:: OPERATION_NAME :value: 'shape.meet' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg0() -> _ods_ir .. py:method:: arg1() -> _ods_ir .. py:method:: error() -> Optional[_ods_ir] .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: meet(arg0, arg1, *, error=None, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: MinOp(lhs, rhs, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Computes the elementwise minimum of two sizes or shapes with equal ranks. If either operand is an error, then an error will be propagated to the result. If the input types mismatch or the ranks do not match, then the result is an error. .. py:attribute:: OPERATION_NAME :value: 'shape.min' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: min(lhs, rhs, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: MulOp(lhs, rhs, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Multiplies two sizes or indices. If either operand is an error it will be propagated to the result. The operands can be of type ``size`` or ``index``. If at least one of the operands can hold an error, i.e. if it is of type ``size``, the result must be of type ``size``. If error propagation is not possible because both operands are of type ``index`` then the result may be of type ``size`` or ``index``. .. py:attribute:: OPERATION_NAME :value: 'shape.mul' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: mul(lhs, rhs, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: NumElementsOp(shape, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Returns the number of elements for a given shape which is the product of its extents. If the argument is of type ``shape`` then the result will be of type ``size`` and potential errors will be propagated. Otherwise, if the argument is and extent tensor ``tensor`` then the result will be of type ``index``. .. py:attribute:: OPERATION_NAME :value: 'shape.num_elements' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shape() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: num_elements(shape, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: RankOp(shape, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Returns the rank of the shape or extent tensor, i.e. the number of extents. .. py:attribute:: OPERATION_NAME :value: 'shape.rank' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shape() -> _ods_ir .. py:method:: rank() -> _ods_ir .. py:function:: rank(shape, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: ReduceOp(result, shape, initVals, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` An operation that takes as input a shape or extent tensor, and a number of initial values. This operation has a region that is applied repeatedly for every extent of the input. Starting with the initial values, the individual extents are then aggregated as defined by the associated region. Conceptually this op performs the following reduction: .. code:: res[] = init; for (int i = 0, i < shape.rank(); i++) { res = reduce(i, shape[i], res[0], ..., res[n]); } Where ``reduce`` represents the region attached and the result of the reduce op is the last computed output of the reduce region. As an example, the number of elements can be computed as follows: .. code:: mlir func.func @reduce(%shape : !shape.shape, %init : !shape.size) -> !shape.size { %num_elements = shape.reduce(%shape, %init) -> !shape.size { ^bb0(%index: index, %dim: !shape.size, %acc: !shape.size): %updated_acc = "shape.mul"(%acc, %dim) : (!shape.size, !shape.size) -> !shape.size shape.yield %updated_acc : !shape.size } return %num_elements : !shape.size } .. py:attribute:: OPERATION_NAME :value: 'shape.reduce' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: shape() -> _ods_ir .. py:method:: initVals() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:method:: region() -> _ods_ir .. py:function:: reduce(result, shape, init_vals, *, loc=None, ip=None) -> Union[_ods_ir, _ods_ir, ReduceOp] .. py:class:: ReturnOp(operands_, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` The ``shape.return`` operation represents a return operation within a function. The operation takes variable number of operands and produces no results. .. py:attribute:: OPERATION_NAME :value: 'shape.return' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operands_() -> _ods_ir .. py:function:: return_(operands_, *, loc=None, ip=None) -> ReturnOp .. py:class:: ShapeEqOp(shapes, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Takes one or more shape or extent tensor operands and determines whether they are equal. When extent tensors are compared to shapes they are regarded as their equivalent non-error shapes. Error shapes can be tested for equality like any other shape value, meaning that the error value is equal to itself. .. py:attribute:: OPERATION_NAME :value: 'shape.shape_eq' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: shapes() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: shape_eq(shapes, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: ShapeOfOp(arg, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` The operation takes a value or a shaped operand as an argument and it returns a shape or extent tensor. .. py:attribute:: OPERATION_NAME :value: 'shape.shape_of' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: shape_of(arg, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: SizeToIndexOp(arg, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Converts a ``shape.size`` to a standard index. This operation and its inverse, ``index_to_size``, facilitate index conversion between the standard and the shape dialect. The behavior is undefined for unknown and invalid arguments. .. py:attribute:: OPERATION_NAME :value: 'shape.size_to_index' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: size_to_index(arg, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: SplitAtOp(head, tail, operand, index, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Splits a shape at a given dimension ``index``, returning two shapes. If ``index`` is negative, it is treated as indexing from the back of the shape. This negative-handling behavior is important when handling unranked shapes, where the positive index is not necessarily knowable due to a dynamic number of leading dimensions. If the result is in extent tensor form out of bounds indices result in undefined behavior. Examples: * split_at([4,5,6], index=0) -> [], [4,5,6] * split_at([4,5,6], index=1) -> [4], [5,6] * split_at([4,5,6], index=2) -> [4,5], [6] * split_at([4,5,6], index=3) -> [4,5,6], [] * split_at([4,5,6], index=4) -> error * split_at([4,5,6], index=-1) -> [4,5], [6] * split_at([4,5,6], index=-2) -> [4], [5,6] * split_at([4,5,6], index=-3) -> [], [4,5,6] * split_at([4,5,6], index=-4) -> error Requires: * ``index`` is in the range [-rank(operand),rank(operand)] .. py:attribute:: OPERATION_NAME :value: 'shape.split_at' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: index() -> _ods_ir .. py:method:: head() -> _ods_ir .. py:method:: tail() -> _ods_ir .. py:function:: split_at(head, tail, operand, index, *, loc=None, ip=None) -> _ods_ir .. py:class:: ToExtentTensorOp(result, input, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Converts a shape to a 1D integral tensor of extents. The number of elements in the tensor equals the rank of the shape, and the elements equal the extents of the shape. If the shape represents an error, this op's behavior is undefined. .. py:attribute:: OPERATION_NAME :value: 'shape.to_extent_tensor' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: input() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: to_extent_tensor(result, input, *, loc=None, ip=None) -> _ods_ir .. py:class:: ValueAsShapeOp(result, arg, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` The operations takes a ValueShape and returns a Shape corresponding to the value. If the input value cannot be shape (e.g., not a 1D tensor of integral value representing sizes) then this propagages the error shape. E.g., .. code:: mlir // The following %0 = arith.constant dense<[1,2]> : tensor<2xi32> %shape = shape.value_as_shape %0 : tensor<2xi32> -> !shape.shape // is equivalent to %shape' = shape.const_shape [1, 2] : !shape.shape This operation is the complement of ``shape_of`` wrt ValueShape values. .. py:attribute:: OPERATION_NAME :value: 'shape.value_as_shape' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: value_as_shape(result, arg, *, loc=None, ip=None) -> _ods_ir .. py:class:: ValueOfOp(result, arg, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` The operation takes !shape.value_shape, a.k.a. (value, shape) tuple as an argument, and returns its value. The behavior is undefined for unknown and invalid arguments. .. py:attribute:: OPERATION_NAME :value: 'shape.value_of' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: value_of(result, arg, *, loc=None, ip=None) -> _ods_ir .. py:class:: WithOp(operand, shape, *, results=None, loc=None, ip=None) Bases: :py:obj:`_ods_ir` Returns ValueShape with the shape updated to match the shape operand. That is a new ValueShape tuple is created with value equal to ``operand``'s value and shape equal to ``shape``. If the ValueShape and given ``shape`` are non-conformant, then the returned ValueShape will represent an error of this mismatch. Similarly if either inputs are in an error state, then an error is propagated. Usage: %0 = shape.with_shape %1, %2 : tensor<...>, !shape.shape This is used, for example, where one combines shape function calculations and/or call one shape function from another. E.g., .. code:: mlir func.func @shape_foobah(%a: !shape.value_shape, %b: !shape.value_shape, %c: !shape.value_shape) -> !shape.shape { %0 = call @shape_foo(%a, %b) : (!shape.value_shape, !shape.value_shape) -> !shape.shape %1 = shape.with_shape %b, %0 : !shape.value_shape, !shape.shape %2 = call @shape_bah(%c, %1) : (!shape.value_shape, !shape.value_shape) -> !shape.shape return %2 : !shape.shape } This op need not be a refinement of the shape. In non-error cases the input ValueShape's value and shape are conformant and so too for the output, but the result may be less specified than ``operand``'s shape as ``shape`` is merely used to construct the new ValueShape. If join behavior is desired then a join op should be used. .. py:attribute:: OPERATION_NAME :value: 'shape.with_shape' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: shape() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:function:: with_shape(operand, shape, *, results=None, loc=None, ip=None) -> _ods_ir .. py:class:: YieldOp(operands_, *, loc=None, ip=None) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'shape.yield' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operands_() -> _ods_ir .. py:function:: yield_(operands_, *, loc=None, ip=None) -> YieldOp