o
    io                     @   s  d dl Zd dlZd dlZd dlmZmZmZ d dlZddl	m
Z
 ddlmZ er.ddl	mZ ddlmZmZmZmZmZmZ ddlmZmZmZmZmZ dd	lmZ G d
d dejZG dd dejZe Zedde i Z i Z!G dd dZ"G dd dej#Z$de%de%fddZ&e d$de%de'defddZ(e de%defddZ)e de%defd d!Z*e de%defd"d#Z+dS )%    N)CallableTupleList   )_TemplateJITPlugin)IS_AOT_ENABLED)_TemplateAOTPlugin)_parse_register_inputs_parse_register_return_validate_autotune_validate_impl_validate_aot_impl_validate_name_and_namespace)_built_in_to_plugin_field_type
_join_with_numpy_to_plugin_field_type_is_numpy_array_infer_numpy_type)
public_apic                       s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	_PluginNamespacec                    s   t  d|  || _d S )Nztensorrt.plugin.op.)super__init__
_namespace)self	namespace	__class__ Q/home/ubuntu/.local/lib/python3.10/site-packages/tensorrt_bindings/plugin/_lib.pyr   0   s   
z_PluginNamespace.__init__c                 C   s   t | |rJ t| || d S N)hasattrsetattr)r   name
plugin_defr   r   r   define4   s   z_PluginNamespace.definec                 C   s"   t d| jj d| j d| d)N'z
' object 'z' has no attribute ')AttributeErrorr   __name__r   r   r"   r   r   r   __getattr__8   s   z_PluginNamespace.__getattr__c                 C   s   d| j  dS )Nz_PluginNamespace(namespace="z"))r   r   r   r   r   __repr__=   s   z_PluginNamespace.__repr__)r'   
__module____qualname__r   r$   r)   r+   __classcell__r   r   r   r   r   /   s
    r   c                       s,   e Zd Z fddZdd Zdd Z  ZS )_Opc                    s   t  d d S )Nztensorrt.plugin.op)r   r   r*   r   r   r   r   C   s   z_Op.__init__c                 C   s,   t | |r
t| |S t|}t| || |S r   )r    getattrr   r!   )r   r   nsr   r   r   define_or_getF   s
   

z_Op.define_or_getc                 C   s   t d| jj d| d)Nr%   z' object has no attribute ')r&   r   r'   r(   r   r   r   r)   O   s   z_Op.__getattr__)r'   r,   r-   r   r2   r)   r.   r   r   r   r   r/   B   s    	r/   op)symbolc                   @   s:   e Zd Zdd Zdeeej eej ejf fddZ	dS )	PluginDefc                 C   sR   d | _ d | _d | _d | _d | _d | _d | _d | _d | _d | _	d | _
d | _d | _d S r   )	plugin_idregister_func	impl_funcaot_impl_funcautotune_funcautotune_attr_namesinput_tensor_namesinput_attrsimpl_attr_namesaot_impl_attr_namesnum_outputsinput_arg_schemaexpects_tacticr*   r   r   r   r   ]   s   
zPluginDef.__init__returnc              
      s   | j d\g g }|D ]}t|tjstdt| |d | qi }| D ]s\}}|| j	vrGtd| d| j	
  d|||< | j	| }t|tjrt|tjkrtt|d d }	t|	t|jkrtd	t|j d
| d|	 dn|t|urtdt| d
| d| d|| q0dtdgt| j  t| j	
 d d }
dd| d}||
krtd| d|
 d| j tv rt dn'i }| D ]\}}t|tjrd|jf||< qdt|f||< qt|g  | D ]r\}}t|tjrDt|j}|tjkr6 t|| tjj q t||t|  qt|trZ t||  tjj! qt|t"rn t||tjj q t|t#|gt$t|  qdd fdd}|S )N::z+Expected trt.ITensor but got input of type ITensorUnexpected attribute z provided. Expected one of .r   r   zUnexpected dtype 'z' for attribute 'z'. Expected 'z'.zUnexpected type '(T)z, zUnexpected schema z received. Expected 1Fquick_plugin_creation_requesttrt.QuickPluginCreationRequestc                    sJ   | d u r t tjj}n t tjj| }g |fS r   )create_plugintrtPluginFieldCollectionTensorRTPhaseBUILD)rK   plgfieldsinput_tensorsr"   r   plg_creatorr   r   create_plugin_instance   s   
z2PluginDef.__call__.<locals>.create_plugin_instancer   )rK   rL   )%r6   split
isinstancerN   rE   
ValueErrortypeappenditemsr=   keysnpndarraytyping
get_originget_argsdtyper   lenr<   joinQDP_CREATORSget_plugin_registryget_creator_register_plugin_creatorfloat16PluginFieldtobytesPluginFieldTypeUNKNOWNr   strencodeCHARbytesarrayr   )r   argskwargsschema_chunkstattrskeyvalueattr_annotationnp_dtypeexpected_schemaschemaattrs_typesnp_typerW   r   rS   r   __call__l   s   






zPluginDef.__call__N)
r'   r,   r-   r   r   r   rN   rE   	IPluginV3r   r   r   r   r   r5   \   s
    r5   c                   @   s    e Zd Zdd Zdd	ddZdS )
_TemplatePluginCreatorc                 C   s   t j|  || _|| _d| _g }| D ]L\}\}}|rO|tu r.|t 	|dt j
j q|tu r?|t 	|dt j
j q|t 	|tg t|  q|t 	|tg tt|  qt || _d S )NrJ       )rN   IPluginCreatorV3Quickr   r"   plugin_namespaceplugin_versionr]   rp   r\   rl   rn   rr   rs   ro   r_   rt   r   r   rd   rO   field_names)r   r"   r   ry   r   builtintype_r   r   r   r      s4   z_TemplatePluginCreator.__init__NqpcrrL   c              	   C   sf  t | d|  }|}|}i }|D ]\}|j|jvr(td|j d|j  d|j|j }	t|	rTt|	}
|
tjkrJtj	|j
 tjd||j< q|j
|
||j< qt|	tre|j
 d||j< q|	|j
||j< qd }|d u rt|||j}||j||j|j|j|j|j |S |tjjkr|jd u rtd|j dd	}nS|tjjkr|jd u rtd
|j dd}n<|jd u}|jd u}|r|r|tjj krd	}n%|tjj!krd}ntd|j d|rd	}n|rd}n	td|j d|d usJ |rt|||j}||j||j|j|j|j|j |S t"|||j}||j||j#|j|j|j |S )NrD   rF   z, provided to create_plugin. Expected one of rG   )rd   zutf-8z3AOT implementation requested, but not defined for 'z$'. Was @trt.plugin.aot_impl defined?Fz3JIT implementation requested, but not defined for 'z '. Was @trt.plugin.impl defined?TzPlugin 'z' has both AOT and JIT implementations. NetworkDefinitionCreationFlag.PREFER_AOT_PYTHON_PLUGINS or NetworkDefinitionCreationFlag.PREFER_JIT_PYTHON_PLUGINS should be specified.z3' does not have either a AOT or JIT implementation.)$QDP_REGISTRYr"   r=   AssertionErrorr^   r   r   r_   rk   
frombufferdatarm   astype
issubclassrp   decoder   r@   initr7   r>   r8   r;   r:   rB   rN   QuickPluginCreationRequest
STRICT_AOTr9   rZ   r6   
STRICT_JIT
PREFER_AOT
PREFER_JITr   r?   )r   r"   r   fcphaser   descry   fattr_type_annotr   
jit_or_aotrR   aot_definedjit_definedr   r   r   rM      s   







z$_TemplatePluginCreator.create_pluginr   )r   rL   )r'   r,   r-   r   rM   r   r   r   r   r      s    r   r"   r   c                 C   sD   t  }t| ||}||| || d|}|t| d|  < |S )NrJ   rD   )rN   rh   r   register_creatorri   rg   )r"   r   r   plg_registryrV   r   r   r   rj   g  s   rj   Fr6   lazy_registerrC   c                    s   dt f fdd}|S )a(  
    Wraps a function to register and describe a TensorRT plugin's IO characteristics. In addition, a complete plugin at least needs an `trt.plugin.impl` function to be registered.

    This API is only intended to be used as a decorator. The decorated function must have type hints for all inputs as well as return value.

    .. code-block:: text

        (inp0: TensorDesc, inp1: TensorDesc, ..., attr0: SupportedAttrType, attr1: SupportedAttrType, ...) -> Union[TensorDesc, Tuple[TensorDesc]]

    * Input tensors are declared first, each described by a tensor descriptor TensorDesc.
    * Plugin attributes are declared next. "SupportedAttrType" must be one of:
       * Supported built-in types: int, float, str, bool, bytes (Note: Lists/tuples of these types are not supported)
       * 1-D Numpy arrays of the following types: int8, int16, int32, int64, float16, float32, float64, bool. These must be annotated with 'numpy.typing.NDArray[dtype]', where 'dtype' is the expected numpy dtype.
    * If the plugin has only one output, the return annotation could be TensorDesc. Tuple[TensorDesc] could be used for any number of outputs.

    By default, the plugin will be immediately registered in the TRT plugin registry. Use the lazy_register argument to change this.

    Args:
        plugin_id: An ID for the plugin in the form "{namespace}::{name}",
            e.g. "my_project::add_plugin". The namespace is used to avoid collisions
            so using your product/project name is recommended.

        lazy_register: During plugin development/when building engine, lazy registration may be used to delay plugin registration until the plugin is explicitly instantiated using `trt.plugin.op.ns.plugin_name(...)`

    .. code-block:: python
        :linenos:
        :caption: Registration of an elementwise plugin (output has same characteristics as the input)

        import tensorrt.plugin as trtp

        @trtp.register("my::add_plugin")
        def add_plugin_desc(inp0: trtp.TensorDesc, block_size: int) -> Tuple[trtp.TensorDesc]:
            return inp0.like()

    r7   c           
         s    d\}}t|| t|}t||r#tdtjj d| dt|  \}}}}t	 }|_
| |_||_||_||_t| }	|	|_|t<  sQt||| ||| | S )NrD   r%   z' already has a defintion for ')rX   r   r3   r2   r    rZ   r   r'   r	   r5   r6   r7   r<   r=   rA   r
   r@   r   rj   r$   )
r7   	plugin_nsplugin_nameop_namespacetensor_namesr=   rA   r   r#   r@   r   r6   r   r   	decorator  s4   


	zregister.<locals>.decoratorr   )r6   r   r   r   r   r   registers  s   &&r   c                       dt f fdd}|S )a	  
    Wraps a function to define an implementation for a plugin already registered through `trt.plugin.register`.

    This API is only intended to be used as a decorator. The decorated function is not required to have type hints for input arguments or return value;
    however, any type hints specified will be validated against the `trt.plugin.register` signature for consistency.

    The schema for the function is as follows:

    .. code-block:: text

        (inp0: Tensor, inp1: Tensor, ..., attr0: SupportedAttrType, attr1: SupportedAttrType, outputs: Tuple[Tensor], stream: int, tactic: Optional[int]) -> None

    * Input tensors are passed first, each described by a `Tensor`.
    * Plugin attributes are declared next.
       * Not all attributes included in `trt.plugin.register` must be specified here -- they could be a subset.
       * Included attributes will be serialized to the TRT engine. Therefore, only attributes the plugin actually needs to perform inference (within the body of `trt.plugin.impl`) should be included.
    * `tactic` is an optional argument. If the plugin is using custom tactics, it must be specified to receive the tactic value to use for the current execution of the plugin.

    Args:
        plugin_id: The ID for the plugin in the form "{namespace}::{name}", which must match that used during `trt.plugin.register`

    .. code-block:: python
        :linenos:
        :caption: Implementation of an elementwise plugin with an OpenAI Triton kernel

        import tensorrt.plugin as trtp
        import triton
        import triton.language as tl

        @triton.jit
        def add_kernel(x_ptr, y_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
            pid = tl.program_id(0)
            offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
            mask = offsets < n_elements
            x = tl.load(x_ptr + offsets, mask=mask)
            tl.store(y_ptr + offsets, x + 1, mask=mask)

        @trtp.register("my::add_plugin")
        def add_plugin_desc(inp0: trtp.TensorDesc, block_size: int) -> Tuple[trtp.TensorDesc]:
            return inp0.like()

        @trtp.impl("my::add_plugin")
        def add_plugin_impl(inp0: trtp.Tensor, block_size: int, outputs: Tuple[trtp.Tensor], stream: int) -> None:

            n = inp0.numel()
            inp0_t = torch.as_tensor(inp0, device="cuda")
            out_t = torch.as_tensor(outputs[0], device="cuda")

            add_kernel[(triton.cdiv(n, block_size),)](inp0_t, out_t, n, BLOCK_SIZE = block_size)
    r8   c                    sD    t vrtd  dt   }t| |\}}| |_||_||_| S NzPlugin zJ is not registered. Did you register it with tensorrt.plugin.register API?)r   rZ   r   r8   r>   rB   )r8   r#   r>   found_tacticr6   r   r   r     s   
zimpl.<locals>.decoratorr   r6   r   r   r   r   impl  s   5r   c                    r   )aW  
    Wraps a function to define an Ahead-of-Time (AOT) implementation for a plugin already registered through `trt.plugin.register`.

    This API is only intended to be used as a decorator. The decorated function is not required to have type hints for input arguments or return value;
    however, any type hints specified will be validated against the `trt.plugin.register` signature for consistency.

    The schema for the function is as follows:
    .. code-block:: text

        (inp0: TensorDesc, inp1: TensorDesc, ..., attr0: SupportedAttrType, attr1: SupportedAttrType, outputs: Tuple[TensorDesc], tactic: Optional[int]) -> Tuple[str, str, KernelLaunchParams, SymExprs]

    * Input tensors are passed first, each described by a `TensorDesc`.
    * Plugin attributes are declared next.
       * Not all attributes included in `trt.plugin.register` must be specified here -- they could be a subset.
       * NOTE: Plugin attributes are not serialized into the engine when using an AOT implementation.
    * `tactic` is an optional argument. If the plugin is using custom tactics, it must be specified to receive the tactic value to use for the current execution of the plugin.

    Args:
        plugin_id: The ID for the plugin in the form "{namespace}::{name}", which must match that used during `trt.plugin.register`

    :returns:
        - kernel_name: The name of the kernel.
        - compiled_kernel: Compiled form of the kernel. Presently, only PTX is supported.
        - launch_params: The launch parameters for the kernel
        - extra_args: Symbolic expressions for scalar inputs to the kernel, located after the tensor inputs and before the tensor outputs

    .. code-block:: python
        :linenos:
        :caption: Implementation of an elementwise plugin with an OpenAI Triton kernel

        import tensorrt.plugin as trtp
        import triton
        import triton.language as tl

        @triton.jit
        def add_kernel(x_ptr, n_elements, y_ptr, BLOCK_SIZE: tl.constexpr):
            pid = tl.program_id(0)
            offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
            mask = offsets < n_elements
            x = tl.load(x_ptr + offsets, mask=mask)
            tl.store(y_ptr + offsets, x + 1, mask=mask)

        @trtp.register("my::add_plugin")
        def add_plugin_desc(inp0: trtp.TensorDesc, block_size: int) -> Tuple[trtp.TensorDesc]:
            return inp0.like()

        @trtp.aot_impl("my::elemwise_add_plugin")
        def add_plugin_aot_impl(
            inp0: trtp.TensorDesc, block_size: int, single_tactic: bool, outputs: Tuple[trtp.TensorDesc], tactic: int
        ) -> Tuple[Union[str, bytes], Union[str, bytes], trtp.KernelLaunchParams, trtp.SymExprs]:

            type_str = "fp32" if inp0.dtype == trt.float32 else "fp16"

            src = triton.compiler.ASTSource(
                fn=add_kernel,
                signature=f"*{type_str},i32,*{type_str}",
                constants={
                    "BLOCK_SIZE": block_size,
                },
            )

            compiled_kernel = triton.compile(src)

            N = inp0.shape_expr.numel()
            launch_params = trtp.KernelLaunchParams()

            # grid dims
            launch_params.grid_x = trtp.cdiv(N, block_size)
            # block dims
            launch_params.block_x = compiled_kernel.metadata.num_warps * 32
            # shared memory
            launch_params.shared_mem = compiled_kernel.metadata.shared

            extra_args = trtp.SymIntExprs(1)
            extra_args[0] = trtp.SymInt32(N)

            return compiled_kernel.metadata.name, compiled_kernel.asm["ptx"], launch_params, extra_args
    r9   c                    :    t vrtd  dt   }t| |}| |_||_| S r   )r   rZ   r   r9   r?   )r9   r#   r?   r   r   r   r   Y  s   

zaot_impl.<locals>.decoratorr   r   r   r   r   aot_impl	  s   Pr   c                    r   )a  
    Wraps a function to define autotune logic for a plugin already registered through `trt.plugin.register`.

    Autotuning is the process by which TensorRT executes the plugin over IO type/format combinations, and any custom tactics advertised as being supported by the plugin.
    The (type, format, tactic) combination with the lowest latency is used to execute the plugin once the engine is built.

    .. note:: An autotune function is optional. If not specified, TensorRT will assume the plugin only supports input types specified at network creation, output types specifeid through `trt.plugin.register`, and linear formats for all I/O.

    This API is only intended to be used as a decorator. The decorated function is not required to have type hints for input arguments or return value; however, any type hints specified will be validated against the `trt.plugin.register` signature for consistency.

    The schema for the function is as follows:

    .. code-block:: text

        (inp0: TensorDesc, inp1: TensorDesc, ..., attr0: SupportedAttrType, attr1: SupportedAttrType, outputs: Tuple[TensorDesc]) -> List[AutoTuneCombination]

    * Input tensors are passed first, each described by a :class:`TensorDesc`.
    * Plugin attributes are declared next. Not all attributes included in `trt.plugin.register` must be specified here -- they could be a subset.
    * The function should return a list of :class:`AutoTuneCombination`\s.

    Args:
        plugin_id: The ID for the plugin in the form "{namespace}::{name}", which must match that used during `trt.plugin.register`

    .. code-block:: python
        :linenos:
        :caption: An elementwise add plugin which supports both FP32 and FP16 linear I/O and wants to be tuned over 2 custom tactics.

        import tensorrt.plugin as trtp

        @trtp.register("my::add_plugin")
        def add_plugin_desc(inp0: trtp.TensorDesc, block_size: int) -> Tuple[trtp.TensorDesc]:
            return inp0.like()

        @trtp.autotune("my::add_plugin")
        def add_plugin_autotune(inp0: trtp.TensorDesc, block_size: int, outputs: Tuple[trtp.TensorDesc]) -> List[trtp.AutoTuneCombination]:

            return [trtp.AutoTuneCombination("FP32|FP16, FP32|FP16", "LINEAR", [1, 2])]

    .. code-block:: python
        :linenos:
        :caption: Same as above example but using index-by-index construction of an `AutoTuneCombination`

        import tensorrt.plugin as trtp

        @trtp.register("my::add_plugin")
        def add_plugin_desc(inp0: trtp.TensorDesc, block_size: int) -> Tuple[trtp.TensorDesc]:
            return inp0.like()

        @trtp.autotune("my::add_plugin")
        def add_plugin_autotune(inp0: trtp.TensorDesc, block_size: int, outputs: Tuple[trtp.TensorDesc]) -> List[trtp.AutoTuneCombination]:
            c = trtp.AutoTuneCombination()
            c.pos(0, "FP32|FP16", "LINEAR")
            c.pos(1, "FP32|FP16") # index 1 is the output. Omitting format is the same as declaring it to be LINEAR.
            c.tactics([1, 2])
            return [c]
    r:   c                    r   r   )r   rZ   r   r:   r;   )r:   r#   r;   r   r   r   r     s   

zautotune.<locals>.decoratorr   r   r   r   r   autotunej  s   ;r   )F),tensorrtrN   typesra   r   r   r   numpyr_   _plugin_classr   _exportr   r   	_validater	   r
   r   r   r   r   _utilsr   r   r   r   r   r   
ModuleTyper   r/   r3   rg   r   r5   r   r   rp   rj   boolr   r   r   r   r   r   r   r   <module>   s>      OE`