
    uki$o              
      H   d Z ddlmZ ddlmZ ddlZddlmZ ddlm	Z	 ddl
Z
ddlZddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZm Z  ddl!m"Z" ddl!m#Z$ ddl%m&Z' ddl(m)Z) ddl*m+Z+ ddl,m-Z- d Z. G d d      Z/ e
j`                         Z1dZ2d Z3d Z4d  Z5d! Z6d" Z7d# Z8d$ Z9d% Z: ejv                  d&      Z<d'e<_=        ej|                  j                  e<       d( Z@d) ZAe<j                  e@       e<j                  eA       d* ZDej                   G d+ d&             ZFd/d,ZG e"j                  e<eG        e'j                  e2e7e9e:d'-        ej                   ee'j                  e2e7e9e:d'.             y)0zrThe implementation of custom partitioning APIs.

It was moved out of ``jax.experimental`` to avoid import cycles.
    )annotations)partialN)Any)Callable)api)api_util)config)core)custom_api_util)dispatch)errors)linear_util)mesh)sharding_impls)	tree_util)
xla_bridge)sdy_sharding_rule_to_mlirSdyShardingRulestr_to_sdy_sharding_rule)mlir)partial_eval)
xla_client)ir)hlo)Shardingc                     t        j                  |       j                  |i |}|j                          |j                  rt        d      |j                  S )Nz4keyword arguments could not be resolved to positions)inspect	signaturebindapply_defaultskwargs	TypeErrorargs)funr#   r!   bas       W/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/custom_partitioning.py_resolve_kwargsr'   3   sL    "w""D3F3"YY
J
KK77N    c                      e Zd Zd Zd Zd Zy)_ShardingCallbackInfoc
                    || _         || _        || _        || _        || _        || _        || _        || _        |	| _        y N)	propagate_user_sharding	partitionto_mesh_pspec_shardingin_treeout_treeinfer_sharding_from_operandsmodule_contextr   static_args)
selfr-   r.   r/   r0   r1   r2   r3   r   r4   s
             r&   __init__z_ShardingCallbackInfo.__init__>   sH     $;D DN"8DDLDM(DD%(DDI"Dr(   c           
     h    t        || j                  |t        |j                                           S r,   )_to_jax_sharded_shaper/   len
dimensions)r5   sshardings      r&   unflatten_arg_shapez)_ShardingCallbackInfo.unflatten_arg_shapeK   s,     	4&&xQ\\^1DE r(   c           
         | j                   j                  t        ||      D cg c]  \  }}| j                  ||       c}}      S c c}}w r,   )r0   	unflattenzipr=   )r5   
arg_shapesarg_shardingsr;   r<   s        r&   unflatten_arg_shapesz*_ShardingCallbackInfo.unflatten_arg_shapesP   sN    <<!!  #:}=	
8 $$Q1	
 	
s   A	
N)__name__
__module____qualname__r6   r=   rC    r(   r&   r*   r*   <   s    #
r(   r*   CustomSPMDPartitioningc                f    t        j                  | j                         | j                               S r,   )r
   ShapedArrayr:   numpy_dtype)r;   s    r&   _to_jax_shaperL   ^   s!    			!,,.!--/	::r(   c                j    t        j                  | j                         | j                         |      S )N)r<   )r   ShapeDtypeStructr:   rK   )r;   r<   s     r&   r8   r8   b   s(    			llnammo
 r(   c                l    | j                         r t        j                  j                  | |      S |d   S )Nr   )is_tuplexcHloShardingtuple_sharding)shaperesult_shardingss     r&   _pack_result_shardingrV   h   s/    
^^>>((0@AAAr(   c                    t        | j                  |      |      D cg c](  \  }}t        |t        |j	                                     * c}}S c c}}w r,   )r@   flatten_up_to_to_hlo_shardingr9   r:   )tree	shardingsshapesr<   rT   s        r&   _flatten_shardingr]   o   sR     !


Y
'

(E xU%5%5%7!89
  
s   -Ac           
        t         |   }|j                  | S |j                         r!|j                         }| j	                         }n|f}| f}|j
                  j                  t        ||      D cg c]  \  }}|j                  ||       c}}      } |j                  g |j                  |j                  | }	t        |j
                  |	|      }
t        ||
      S c c}}w r,   )_sharding_callbacksr-   rP   tuple_shapestuple_elementsr1   r?   r@   r=   r4   r   r]   rV   )user_shardingrT   backend_stringinfouser_shapesuser_shardingsr;   r<   
user_shaperesult_shardingrU   s              r&   ,_custom_partitioning_propagate_user_shardingri   x   s    	^	,$	!!)
^^$$&K"113N(K#%N}}&& !n=a 
"
"1h
/* 1D00 $./ '
mm_k3	u&6	77s   3C$
c                Z    t        | t              st        d      | j                  |      S )Nz/Custom Partitioning rules must return Sharding.)
isinstancer   
ValueError_to_xla_hlo_sharding)r<   num_dimensionss     r&   rY   rY      s)    	Hh	'
F
GG		&	&~	66r(   c                Z   t         |   }|j                         r!|j                         }|j                         }n|f}|f} |j                  g |j
                  |j                  |j                  | |      |j                  j                  t        ||      D 	cg c]  \  }}	|j                  ||	       c}	}       \  }
}}}|j                  }t        |j                  ||      }t        |j                  ||       }t        ||       D 	cg c]  \  }	}t        |	j!                  |            ! }}	}t        ||      D 	cg c]  \  }	}t        |	j!                  |            ! }}	} t#        j$                  |t'        |
j(                  j+                                     |j                  j                  |       }|j,                  D cg c]  }|j(                  |j.                  f c}|D cg c]  }|j(                  |j.                  f c}k7  r-t1        dt3        |j,                        dt3        |            t5        j6                  |
      }t9        j:                  |
j(                  j+                               5  t=        j>                  |d|j@                  |jB                  |jE                  tG        |
jH                                    }d d d        tK        ||      }t=        jL                        ||fS c c}	}w c c}}	w c c}}	w c c}w c c}w # 1 sw Y   IxY w)N)axis_envzMismatch in result shapes. z vs tmp_xla_computation)name	platformsbackendaxis_context)'r_   rP   r`   ra   r.   r4   r   rC   r1   r?   r@   r=   r3   r]   r0   rL   tiler   
make_jaxprlistrT   items	out_avalsdtyperl   reprr   SPMDAxisContextr
   extend_axis_env_ndr   build_mlir_module_helperrs   rt   extend_manual	frozenset
axis_namesrV   module_to_bytecode)rA   rB   result_shaperh   rc   rd   result_shapesrU   r;   r<   r   lower_fnr3   
tiled_argstiled_resultsclosed_jaxprotru   modules                       r&   _custom_partitioning_partitionr      s   	^	,$ --/M&557!OM')3A4>> 
4
4
ii
4 
M:
4 mm "%]4D!E!X &&q(3	
40$/= &&.&
mm_m5#DLL-L- ]J7
(A HMM!$%*  -}=
(A HMM!$%-  M4

8H8H8J3KL||j), $0#9#9:a:#01a12
&&'m)<	>   //5,tzz//12 **" **&&!//	$//0JKF *,8HI/		 	 	(-	HHM ;1 s+   L$L$LL5LAL!!L*c                   t         |   }|j                         r|j                         }n|f} |j                  g |j                  |j
                  |j                  | |      |j                  j                  |D cg c]  }t        |       c}       }t        |j                  ||      }t        ||      S c c}w r,   )r_   rP   r`   r2   r4   r   rC   r1   r?   rL   r]   rV   )	rA   rB   r   rc   rd   r   r;   rh   rU   s	            r&   1_custom_partitioning_infer_sharding_from_operandsr      s     
^	,$ --/M!OM5D55 
ii 
M: mmGA}Q/GH	/ '
mm_m5	|-=	>>	 Hs   >B=custom_partitioningTc        	        *    ~~~~~~~~| j                   S r,   )rz   )
callr0   r1   r-   r.   r2   decode_shardingssharding_ruler4   avalss
             r&   "_custom_partitioning_abstract_evalr      s#     x0)"$4m	r(   c        	        B    ~~~~~~~~ t        j                  |       |	 S r,   )r
   jaxpr_as_fun)
r   r0   r1   r-   r.   r2   r   r   r4   r#   s
             r&   _custom_partitioning_implr      s0     x0)"$4k=	 		4	 $	''r(   c                x    t        d t        j                  |       D              rt        j                  d      y )Nc              3  P   K   | ]  }t        |t        j                           y wr,   )rk   r
   Tracer).0leafs     r&   	<genexpr>z%_check_for_tracers.<locals>.<genexpr>   s     L4D$++	&Ls   $&zFound a JAX Tracer object passed as an argument to acustom_partitioning function in a position indicated as static bystatic_argnums. )anyr   tree_leavesr   UnexpectedTracerError)xs    r&   _check_for_tracersr      s9    L93H3H3KLL

&
&	  Mr(   c                  Z    e Zd ZU dZd
dZej                  Zded<   	 	 	 ddddddZ	d	 Z
y)r   a'  Inserts a CustomCallOp into the XLA graph with custom SPMD lowering rules.

  .. code-block:: python

    @custom_partitioning
    def f(*args):
      return ...

    def propagate_user_sharding(mesh, user_shape):
      '''Update the sharding of the op from a user's shape.sharding.'''
      user_sharding = jax.tree.map(lambda x: x.sharding, user_shape)

    def partition(mesh, arg_shapes, result_shape):
      def lower_fn(*args):
        ... builds computation on per-device shapes ...
      result_shardings = jax.tree.map(lambda x: x.sharding, result_shape)
      arg_shardings = jax.tree.map(lambda x: x.sharding, arg_shapes)
      # result_sharding and arg_shardings may optionally be modified and the
      # partitioner will insert collectives to reshape.
      return mesh, lower_fn, result_sharding, arg_shardings

    def infer_sharding_from_operands(mesh, arg_shapes, shape):
      '''Compute the result sharding from the sharding of the operands.'''
      arg_shardings = jax.tree.map(lambda x: x.sharding, arg_shapes)


    f.def_partition(partition, propagate_user_sharding,
                    infer_sharding_from_operands=infer_sharding_from_operands,
                    sharding_rule='i j -> 'i j')

  The args to ``def_partition`` are as follows:

  * ``propagate_user_sharding``: Callable which takes the sharding of a user (in the dag)
    and returns a suggestion for a new `NamedSharding`. The default value is None.
    A trivial implementation is just to return the input sharding.
  * ``partition``: Callable which takes the SPMD suggested partition shapes and
    partition specs and returns the mesh, a per-shard lowering function, and the final
    input and output sharding specs (the SPMD partitioner will repartition the
    inputs to match). The mesh is returned to allow configuring axis_names for
    collectives when no mesh is provided.
  * ``infer_sharding_from_operands``: Callable which computes an output ``NamedSharding``
    from the ``NamedSharding`` chosen for each argument.
  * ``decode_shardings``: When set to True, convert input ``GSPMDSharding``s to
    ``NamedSharding`` if possible. This may not be possible if the user does not
    provide a contextual mesh.
  * ``sharding_rule``: an SdyShardingRule object, an Einsum-like notation string
    that describes the sharding rule, or a Callable that produces either of
    these. We call the index labels in Einsum notation factors in our sharding
    rule. We borrow the idea from the einops.rearrange string , to use a space
    separator between factors and allow multiple letters factor names. By
    default, a factor corresponds to a passthrough/elementwise dimension.
    Factors corresponding to other dimensions can be specified via keyword
    arguments described below. See
    `jax-shardy-guide <https://colab.sandbox.google.com/github/openxla/shardy/blob/main/docs/getting_started_jax.ipynb>`_
    for more details and examples.
  * ``reduction_factors``: A tuple of strings, specifying the reduction factors
    for a string `sharding_rule`. A reduction factor corresponds to a dimension
    that appears in operands but not in the result, such as the contracting
    dimensions in a matmul operation. If a reduction factor is sharded, the
    result would need to be all-reduced along the same axes.
  * ``need_replication_factors``: A tuple of strings, specifying the
    need_replication factors for a string `sharding_rule`. A need_replication
    factor corresponds to a dimension that shouldn't be sharded to support
    the implementation.
  * ``permutation_factors``: A tuple of strings, specifying the permutation
    factors for a string `sharding_rule`. A permutation factor corresponds to a
    dimension that would trigger collective permute if it is sharded.
  * ``factor_sizes``: A dictionary of variable keyword arguments, specifying
    the sizes of the factors that are only used in compound factors in a string
    `sharding_rule`.

  When config.use_shardy_partitioner.value is True, `sharding_rule` is used;
  otherwise, `propagate_user_sharding` and `infer_sharding_from_operands` are
  used.

  Positional arguments can be specified as static using static_argnums. JAX uses
  :code:`inspect.signature(fun)` to resolve these positional arguments.

  Examples:

    As an example, assume we want to enhance the existing ``jax.numpy.fft.fft``. This function computes
    the discrete Fourier transform of an N-dimensional input along the last dimension, and is batched
    along the first N-1 dimensions.
    By default, however, it will ignore the sharding of the input and gather the input on all devices.
    However, since ``jax.numpy.fft.fft`` is batched along the first N-1 dimensions,
    this is unnecessary. We will create a new ``my_fft`` op that, instead, does not alter the sharding
    along the first `N-1` dimensions, and only gathers the input along the last dimension if needed.

    .. code-block:: python

      import jax
      from jax.sharding import NamedSharding
      from jax.experimental.custom_partitioning import custom_partitioning
      from jax.experimental.pjit import pjit
      from jax.sharding import PartitionSpec as P
      from jax.sharding import Mesh
      from jax.numpy.fft import fft
      import regex as re
      import numpy as np

      # Pattern to detect all-gather or dynamic-slice in the generated HLO
      _PATTERN = '(dynamic-slice|all-gather)'

      # For an N-D input, keeps sharding along the first N-1 dimensions
      # but replicate along the last dimension
      def supported_sharding(sharding, shape):
          rank = len(shape.shape)
          max_shared_dims = min(len(sharding.spec), rank-1)
          names = tuple(sharding.spec[:max_shared_dims]) + tuple(None for _ in range(rank - max_shared_dims))
          return NamedSharding(sharding.mesh, P(*names))

      def partition(mesh, arg_shapes, result_shape):
          result_shardings = jax.tree.map(lambda x: x.sharding, result_shape)
          arg_shardings = jax.tree.map(lambda x: x.sharding, arg_shapes)
          return mesh, fft,               supported_sharding(arg_shardings[0], arg_shapes[0]),               (supported_sharding(arg_shardings[0], arg_shapes[0]),)

      def infer_sharding_from_operands(mesh, arg_shapes, result_shape):
          arg_shardings = jax.tree.map(lambda x: x.sharding, arg_shapes)
          return supported_sharding(arg_shardings[0], arg_shapes[0])

      @custom_partitioning
      def my_fft(x):
          return fft(x)

      # Use Einsum-like notation to specify the sharding rule.
      my_fft.def_partition(
        infer_sharding_from_operands=infer_sharding_from_operands,
        partition=partition,
        sharding_rule='...i -> ...i')
      # Use SdyShardingRule object to specify the sharding rule.
      my_fft.def_partition(
        infer_sharding_from_operands=infer_sharding_from_operands,
        partition=partition,
        sharding_rule=SdyShardingRule(operand_mappings=((BATCHING, 'i'),), result_mappings=((BATCHING, 'i'),))))

    Now create a 2D array sharded along the first axis, pass it through ``my_fft``
    and notice how it is still sharded as expected, and identical to the output
    of ``fft``. However, inspecting the HLO
    (using ``lower(x).compile().runtime_executable().hlo_modules()``) reveals that
    ``my_fft`` does not create any all-gather or dynamic-slice, while ``fft`` does.

    .. code-block::

      with Mesh(np.array(jax.devices()), ('x',)):
        x = np.asarray(np.random.randn(32*1024, 1024), dtype=np.complex64)
        y = pjit(lambda x: x, in_shardings=None, out_shardings=P('x'))(x)
        pjit_my_fft = pjit(my_fft, in_shardings=P('x'), out_shardings=P('x'))
        pjit_fft    = pjit(fft,    in_shardings=P('x'), out_shardings=P('x'))
        print(pjit_my_fft(y))
        print(pjit_fft(y))
        # dynamic-slice or all-gather are not present in the HLO for my_fft, because x is a 2D array
        assert(re.search(_PATTERN, pjit_my_fft.lower(x).compile().runtime_executable().hlo_modules()[0].to_string()) is None)
        # dynamic-slice or all-gather are present in the HLO for fft
        assert(re.search(_PATTERN, pjit_fft.lower(x).compile().runtime_executable().hlo_modules()[0].to_string())    is not None)

    .. code-block::

      # my_fft
      [[-38.840824   +0.j        -40.649452  +11.845365j
      ...
        -1.6937828  +0.8402481j  15.999859   -4.0156755j]]

      # jax.numpy.fft.fft
      [[-38.840824   +0.j        -40.649452  +11.845365j
        ...
        -1.6937828  +0.8402481j  15.999859   -4.0156755j]]

    Because of the logic in ``supported_sharding``, ``my_fft`` also works on 1-dimensional arrays.
    However, in this case, the HLO of ``my_fft`` does show a dynamic-slice, since the last dimension
    is the dimension along which FFTs are calculated and needs to be replicated on all devices before
    the computation can be done.

    .. code-block::

      with Mesh(np.array(jax.devices()), ('x',)):
        x = np.asarray(np.random.randn(32*1024*1024), dtype=np.complex64)
        y = pjit(lambda x: x, in_shardings=None, out_shardings=P('x'))(x)
        pjit_my_fft = pjit(my_fft, in_shardings=P('x'), out_shardings=P('x'))
        pjit_fft    = pjit(fft,    in_shardings=P('x'), out_shardings=P('x'))
        print(pjit_my_fft(y))
        print(pjit_fft(y))
        # dynamic-slice or all-gather are present in the HLO for my_fft, because x is a 1D array
        assert(re.search(_PATTERN, pjit_my_fft.lower(x).compile().runtime_executable().hlo_modules()[0].to_string()) is None)
        # dynamic-slice or all-gather are present in the HLO for fft
        assert(re.search(_PATTERN, pjit_fft.lower(x).compile().runtime_executable().hlo_modules()[0].to_string())    is not None)

    .. code-block::

      # my_fft
      [    7.217285   +0.j     -3012.4937  +4287.635j   -405.83594 +3042.984j
      ...  1422.4502  +7271.4297j  -405.84033 -3042.983j
      -3012.4963  -4287.6343j]

      # jax.numpy.fft.fft
      [    7.217285   +0.j     -3012.4937  +4287.635j   -405.83594 +3042.984j
      ...  1422.4502  +7271.4297j  -405.84033 -3042.983j
      -3012.4963  -4287.6343j]

  rG   c                X    || _         d | _        || _        d | _        d | _        d | _        y r,   )r$   r.   static_argnumsr-   r2   r   )r5   r$   r   s      r&   r6   zcustom_partitioning.__init__  s0    DHDN(D#'D (,D%Dr(   r   __getattr__Nreduction_factorsneed_replication_factorspermutation_factorsc               T   || _         || _        || _        || _        | t	        |t
              st	        |t              rT|	}
t        |      dkD  r||
d<   t        |      dkD  r||
d<   t        |      dkD  r||
d<   |
rt        d|
       || _	        |S t        |f|||d|	| _	        |S )Nr   r   r   r   zUnknown keyword arguments: r   )r.   r-   r2   r   rk   r   r   r9   rl   r   r   )r5   r.   r2   r-   r   r   r   r   r   factor_sizessharding_rule_dicts              r&   def_partitionz!custom_partitioning.def_partition  s    
 DN#:D (DD%,DM8!D=/2'		!	#2C./	%	&	*9Q56	 	!A	%4G01	67I6JKLL(d  4
-#;1	
 d r(   c                (   t        | j                  |      t        j                  d| j                  i | j                        }| j                  rt        | j                        t        fdt              D              t        t                    D cg c]	  }|vs| }}t        j                  t        j                  | j                  |      |d      \  }}t        fd| j                  D              }t        |       n%d}t        j                  | j                  |      }}t        j                  |      \  }	}
t        j                   ||
      \  }}|	D cg c]  }t#        j$                  |       }}t&        j(                  j*                  j,                  }t#        j.                  |j0                  j3                               5  t5        j6                  ||      \  }}}d d d        t              rJ t#        j8                  t5        j:                        d      }d }d }d }t<        j>                  j@                  r<| jB                  #| jD                  | jF                  tI        d	      | jB                  }n| jD                  }| jF                  }tK        jL                  g ||	|| jN                  ||| jP                  ||
 |       |d
	}t        jR                   |       |      S c c}w c c}w # 1 sw Y   xY w)Nr   )r   c              3  4   K   | ]  \  }}|v r|n|  y wr,   rG   )r   ir   r   s      r&   r   z/custom_partitioning.__call__.<locals>.<genexpr>  s!     Otq!^+12Os   )
debug_infoF)require_static_args_hashablec              3  (   K   | ]	  }|     y wr,   rG   )r   r   r#   s     r&   r   z/custom_partitioning.__call__.<locals>.<genexpr>  s     ?a$q'?s   rG   zShardy is used, but sharding propagation callbacks instead of sharding_rule are provided. Need to provide sharding_rule to migrate to Shardy.)	r   r.   r-   r2   r   r   r0   r1   r4   )*r'   r$   r   r   r   settuple	enumerateranger9   argnums_partiallu	wrap_initr   r   tree_flattenflatten_fun_nokwargsr
   get_avalmesh_libthread_resourcesenvphysical_meshr~   rT   ry   petrace_to_jaxpr_dynamicClosedJaxprconvert_constvars_jaxprr	   use_shardy_partitionervaluer   r-   r2   NotImplementedErrorcustom_partitioning_pr   r.   r   tree_unflatten)r5   r#   r!   debugr   dyn_argnumsf_dyn_argsr4   	args_flatr0   flat_funr1   r   in_avalsr   jaxpr_constsclosed_callr-   r2   r   out_flatr   s    `                      @r&   __call__zcustom_partitioning.__call__  s   488T62D 5txx $b/3/B/BDE 4../nOyOOd %c$i 0L1A^4KQLkL--
,,txxE
2

',	lb( ?4+>+>??k%k\\$((u=t(b"//9Iw!66r7CHh*34Qa 4H4$$((66D		 	 !1!1!3	4 G228XFeQG6{?""2#=#=e#DbIK"#' M$$**



$''3--9!!
 	

 ((m $ < <%)%F%F"$)) 		 .. 7%A..#H ##HJ99g M 5G Gs   	K=&K=+LLL)rG   )NNTN)rD   rE   rF   __doc__r6   r   forward_attrr   __annotations__r   r   rG   r(   r&   r   r     s@    HT %11+s1BFCG"&=?-/R<;:r(   c       	           | j                   j                  }t        |t        j                        rft        |j                        t        |j                  j                        k(  r1 t        j                  t        j                  |      d      | g|
 S t        j                  j                  j                   t        |t        j"                        rt|j$                  t'        d      |j(                  }|t        j*                  t-        j.                        j1                  |j2                        |j                        n3t        |t        j                        r|j                  j4                  nd rt7              dk(  r1 t        j                  t        j                  |      d      | g|
 S dfd}t9        ||||||| j                   |		      }t;        t=        |            }|t>        tA        |d      <   | j                   jC                  |       |jD                  D cg c]  }t        jF                  |       }}tI        jJ                  |tM        |
      tN        jP                  jS                  tT              tN        jV                  jS                  d      t        jX                  d      tN        jZ                  jS                  g       tN        jP                  jS                  |      d d 		      }||j\                  D cg c]  }t        jF                  |       }}t_        |      rr |g |	|| }t        |tL        t`        f      rt7        |      dk(  r|\  }}ni }t        |t:              rtc        |fi |}nt        |td              stg        d
      ti        |||      |jj                  d<   |jl                  S c c}w c c}w )NT)multiple_resultsz9Please file a bug at https://github.com/jax-ml/jax/issues   c                   | | S j                   ssJ t        j                  |       S t        j                  |       d   }t        j                  g |d|t        |      z
  z   }t        j                  |      S )Nr   r,   )emptyr   GSPMDShardingparse_flatten_op_shardingPartitionSpecr9   NamedSharding)hlo_shardingndimpspecr   devicesr   s      r&   r/   zB_custom_partitioning_lowering_rule.<locals>.to_mesh_pspec_shardingY  s    zz)   ))'<@@44dE((R%R7dSZ>O3PRE''e44r(   utf8F   )call_target_namehas_side_effectapi_versioncalled_computationsbackend_configoperand_layoutsresult_layoutszgsharding_rule callable must produce either an SdyShardingRule object or an Einsum-like notation string.zsdy.sharding_rule)r   zxc.HloSharding | None)7r3   ru   rk   r   r}   r   manual_axesr   r   r   	lower_funr
   r   r   r   r   r   ShardingContextdevice_assignmentAssertionErrorabstract_meshMeshnparrayreshape
axis_sizes_flat_devices_tupler9   r*   stridr_   bytesadd_keepaliverz   aval_to_ir_typer   CustomCallOprx   r   
StringAttrget_CUSTOM_PARTITIONING_CALL_NAMEBoolAttri32_attr	ArrayAttrr   callabler   r   r   rl   r   
attributesresults)ctxr   r0   r1   r-   r.   r2   r   r   r4   valuesru   amr/   sharding_callback_infokeyr;   result_typesoutvalue_typesr   r   r   s          `             @@r&   "_custom_partitioning_lowering_ruler  :  sI    ##00,~==>	,
"
"#s<+<+<+G+G'HHI4>>$++D1DI#WPVWW		"	"	&	&	4	4$n<<=,,G
EG G		#	#B	~]]288G,44R]]C==*d, > >?33GG	CLA%84>>$$88;F>DF F	5 11H'("C$6$6kK 	B%&'#,BeC() ""#9:37>>Ba$&&q)B,B
6l}}(()GHkkooe,--",,**2.]]&&s+		# 48MMBq4''*BKB#R[R$RR\Rm	MD%=	1c-6HA6M,9))	M3	'0UBTU-9 % & & +D[,+0CNN&'	7 C Cs   5OO)+can_side_effecting_have_replicated_sharding)rr   prop_user_shardingr.   r2   r  )r  zmlir.LoweringRuleContext)Kr   
__future__r   	functoolsr   r   typingr   collections.abcr   weakrefnumpyr   jax._srcr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   xb*jax._src.custom_partitioning_sharding_ruler   r   r   jax._src.interpretersr   r   r   jax._src.libr   rQ   jax._src.lib.mlirr   jax._src.lib.mlir.dialectsr   jax._src.shardingr   r'   r*   WeakValueDictionaryr_   r  rL   r8   rV   r]   ri   rY   r   r   	Primitiver   r   %prim_requires_devices_during_loweringaddr   r   def_abstract_evaldef_implr   register_custom_decorator_typer   r  register_lowering register_custom_call_partitionerregister_plugin_callbacksrG   r(   r&   <module>r2     s  
 #    $       $   & % #  % { { & 4 )   * & : 2g113 !9 ;8274In?& ''<= )-  &  . . 2 23H I	(  ' '(J K   8 9 //n: n: 0n:b	N`   ,9; $ # #"0"504   
+++G0%V48	r(   