import{S as Ns,i as Fs,s as Rs,e as o,k as m,w as g,t as d,M as Ss,c as s,d as e,m as p,a as r,x as _,h as c,b as l,G as a,g as f,y as v,q as $,o as b,B as x,v as Gs,L as ba}from"../../chunks/vendor-hf-doc-builder.js";import{D as M}from"../../chunks/Docstring-hf-doc-builder.js";import{C as pt}from"../../chunks/CodeBlock-hf-doc-builder.js";import{I as mt}from"../../chunks/IconCopyLink-hf-doc-builder.js";import{E as $a}from"../../chunks/ExampleCodeBlock-hf-doc-builder.js";function Vs(L){let u,k,w,h,j;return h=new pt({props:{code:`from transformers import BertModel
from transformers.utils.fx import symbolic_trace
from optimum.fx.optimization import ChangeTrueDivToMulByInverse, MergeLinears, compose

model = BertModel.from_pretrained("bert-base-uncased")
traced = symbolic_trace(
    model,
    input_names=["input_ids", "attention_mask", "token_type_ids"],
)
composition = compose(ChangeTrueDivToMulByInverse(), MergeLinears())
transformed_model = composition(traced)`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> BertModel
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers.utils.fx <span class="hljs-keyword">import</span> symbolic_trace
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> ChangeTrueDivToMulByInverse, MergeLinears, compose

<span class="hljs-meta">&gt;&gt;&gt; </span>model = BertModel.from_pretrained(<span class="hljs-string">&quot;bert-base-uncased&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>traced = symbolic_trace(
<span class="hljs-meta">&gt;&gt;&gt; </span>    model,
<span class="hljs-meta">&gt;&gt;&gt; </span>    input_names=[<span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
<span class="hljs-meta">&gt;&gt;&gt; </span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>composition = compose(ChangeTrueDivToMulByInverse(), MergeLinears())
<span class="hljs-meta">&gt;&gt;&gt; </span>transformed_model = composition(traced)`}}),{c(){u=o("p"),k=d("Example:"),w=m(),g(h.$$.fragment)},l(n){u=s(n,"P",{});var y=r(u);k=c(y,"Example:"),y.forEach(e),w=p(n),_(h.$$.fragment,n)},m(n,y){f(n,u,y),a(u,k),f(n,w,y),v(h,n,y),j=!0},p:ba,i(n){j||($(h.$$.fragment,n),j=!0)},o(n){b(h.$$.fragment,n),j=!1},d(n){n&&e(u),n&&e(w),x(h,n)}}}function Ws(L){let u,k,w,h,j;return h=new pt({props:{code:`from transformers import BertModel
from transformers.utils.fx import symbolic_trace
from optimum.fx.optimization import MergeLinears

model = BertModel.from_pretrained("bert-base-uncased")
traced = symbolic_trace(
    model,
    input_names=["input_ids", "attention_mask", "token_type_ids"],
)
transformation = MergeLinears()
transformed_model = transformation(traced)
restored_model = transformation(transformed_model, reverse=True)`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> BertModel
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers.utils.fx <span class="hljs-keyword">import</span> symbolic_trace
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> MergeLinears

<span class="hljs-meta">&gt;&gt;&gt; </span>model = BertModel.from_pretrained(<span class="hljs-string">&quot;bert-base-uncased&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>traced = symbolic_trace(
<span class="hljs-meta">&gt;&gt;&gt; </span>    model,
<span class="hljs-meta">&gt;&gt;&gt; </span>    input_names=[<span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
<span class="hljs-meta">&gt;&gt;&gt; </span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>transformation = MergeLinears()
<span class="hljs-meta">&gt;&gt;&gt; </span>transformed_model = transformation(traced)
<span class="hljs-meta">&gt;&gt;&gt; </span>restored_model = transformation(transformed_model, reverse=<span class="hljs-literal">True</span>)`}}),{c(){u=o("p"),k=d("Example:"),w=m(),g(h.$$.fragment)},l(n){u=s(n,"P",{});var y=r(u);k=c(y,"Example:"),y.forEach(e),w=p(n),_(h.$$.fragment,n)},m(n,y){f(n,u,y),a(u,k),f(n,w,y),v(h,n,y),j=!0},p:ba,i(n){j||($(h.$$.fragment,n),j=!0)},o(n){b(h.$$.fragment,n),j=!1},d(n){n&&e(u),n&&e(w),x(h,n)}}}function Os(L){let u,k,w,h,j;return h=new pt({props:{code:`from transformers import BertModel
from transformers.utils.fx import symbolic_trace
from optimum.fx.optimization import FuseBiasInLinear

model = BertModel.from_pretrained("bert-base-uncased")
traced = symbolic_trace(
    model,
    input_names=["input_ids", "attention_mask", "token_type_ids"],
)
transformation = FuseBiasInLinear()
transformed_model = transformation(traced)
restored_model = transformation(transformed_model, reverse=True)`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> BertModel
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers.utils.fx <span class="hljs-keyword">import</span> symbolic_trace
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> FuseBiasInLinear

<span class="hljs-meta">&gt;&gt;&gt; </span>model = BertModel.from_pretrained(<span class="hljs-string">&quot;bert-base-uncased&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>traced = symbolic_trace(
<span class="hljs-meta">&gt;&gt;&gt; </span>    model,
<span class="hljs-meta">&gt;&gt;&gt; </span>    input_names=[<span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
<span class="hljs-meta">&gt;&gt;&gt; </span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>transformation = FuseBiasInLinear()
<span class="hljs-meta">&gt;&gt;&gt; </span>transformed_model = transformation(traced)
<span class="hljs-meta">&gt;&gt;&gt; </span>restored_model = transformation(transformed_model, reverse=<span class="hljs-literal">True</span>)`}}),{c(){u=o("p"),k=d("Example:"),w=m(),g(h.$$.fragment)},l(n){u=s(n,"P",{});var y=r(u);k=c(y,"Example:"),y.forEach(e),w=p(n),_(h.$$.fragment,n)},m(n,y){f(n,u,y),a(u,k),f(n,w,y),v(h,n,y),j=!0},p:ba,i(n){j||($(h.$$.fragment,n),j=!0)},o(n){b(h.$$.fragment,n),j=!1},d(n){n&&e(u),n&&e(w),x(h,n)}}}function Hs(L){let u,k,w,h,j;return h=new pt({props:{code:`from transformers import BertModel
from transformers.utils.fx import symbolic_trace
from optimum.fx.optimization import ChangeTrueDivToMulByInverse

model = BertModel.from_pretrained("bert-base-uncased")
traced = symbolic_trace(
    model,
    input_names=["input_ids", "attention_mask", "token_type_ids"],
)
transformation = ChangeTrueDivToMulByInverse()
transformed_model = transformation(traced)
restored_model = transformation(transformed_model, reverse=True)`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> BertModel
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers.utils.fx <span class="hljs-keyword">import</span> symbolic_trace
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> ChangeTrueDivToMulByInverse

<span class="hljs-meta">&gt;&gt;&gt; </span>model = BertModel.from_pretrained(<span class="hljs-string">&quot;bert-base-uncased&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>traced = symbolic_trace(
<span class="hljs-meta">&gt;&gt;&gt; </span>    model,
<span class="hljs-meta">&gt;&gt;&gt; </span>    input_names=[<span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
<span class="hljs-meta">&gt;&gt;&gt; </span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>transformation = ChangeTrueDivToMulByInverse()
<span class="hljs-meta">&gt;&gt;&gt; </span>transformed_model = transformation(traced)
<span class="hljs-meta">&gt;&gt;&gt; </span>restored_model = transformation(transformed_model, reverse=<span class="hljs-literal">True</span>)`}}),{c(){u=o("p"),k=d("Example:"),w=m(),g(h.$$.fragment)},l(n){u=s(n,"P",{});var y=r(u);k=c(y,"Example:"),y.forEach(e),w=p(n),_(h.$$.fragment,n)},m(n,y){f(n,u,y),a(u,k),f(n,w,y),v(h,n,y),j=!0},p:ba,i(n){j||($(h.$$.fragment,n),j=!0)},o(n){b(h.$$.fragment,n),j=!1},d(n){n&&e(u),n&&e(w),x(h,n)}}}function Js(L){let u,k,w,h,j,n,y,me,xa,Be,H,ya,pe,wa,ja,Le,N,J,le,lt,Ta,fe,ka,Ce,Ct,za,Ne,F,U,de,ft,Ea,ce,Ma,Fe,C,Aa,Nt,Ia,Da,Ft,qa,Pa,Re,Rt,Ba,Se,dt,Ge,St,La,Ve,ct,We,R,K,he,ht,Ca,ue,Na,Oe,A,Fa,Gt,Ra,Sa,Vt,Ga,Va,Wt,Wa,Oa,He,Ot,Ha,Je,ut,Ue,S,Q,ge,gt,Ja,_e,Ua,Ke,X,Ka,Ht,Qa,Xa,Qe,_t,Xe,G,Y,ve,vt,Ya,$e,Za,Ye,V,Z,be,$t,to,xe,eo,Ze,T,bt,ao,ye,oo,so,xt,ro,Jt,no,io,mo,Ut,yt,po,Kt,wt,lo,tt,jt,fo,we,co,ho,Qt,Tt,uo,Xt,kt,ta,z,zt,go,je,_o,vo,W,$o,Yt,bo,xo,Zt,yo,wo,jo,te,Et,To,et,Mt,ko,Te,zo,Eo,ee,At,ea,D,It,Mo,ke,Ao,Io,at,aa,O,ot,ze,Dt,Do,Ee,qo,oa,q,qt,Po,Me,Bo,Lo,st,sa,P,Pt,Co,Ae,No,Fo,rt,ra,B,Bt,Ro,Ie,So,Go,nt,na;return n=new mt({}),lt=new mt({}),ft=new mt({}),dt=new pt({props:{code:`from optimum.fx.optimization import Transformation

class ChangeMulToAdd(Transformation):
    def transform(self, graph_module):
        for node in graph_module.graph.nodes:
            if node.op == "call_function" and node.target == operator.mul:
                node.target = operator.add
        return graph_module`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> Transformation

<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">class</span> <span class="hljs-title class_">ChangeMulToAdd</span>(<span class="hljs-title class_ inherited__">Transformation</span>):
<span class="hljs-meta">&gt;&gt;&gt; </span>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">transform</span>(<span class="hljs-params">self, graph_module</span>):
<span class="hljs-meta">&gt;&gt;&gt; </span>        <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> graph_module.graph.nodes:
<span class="hljs-meta">&gt;&gt;&gt; </span>            <span class="hljs-keyword">if</span> node.op == <span class="hljs-string">&quot;call_function&quot;</span> <span class="hljs-keyword">and</span> node.target == operator.mul:
<span class="hljs-meta">&gt;&gt;&gt; </span>                node.target = operator.add
<span class="hljs-meta">&gt;&gt;&gt; </span>        <span class="hljs-keyword">return</span> graph_module`}}),ct=new pt({props:{code:`from transformers import BertModel
from transformers.utils.fx import symbolic_trace

model = BertModel.from_pretrained("bert-base-uncased")
traced = symbolic_trace(
    model,
    input_names=["input_ids", "attention_mask", "token_type_ids"],
)

transformation = ChangeMulToAdd()
transformed_model = transformation(traced)`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> BertModel
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> transformers.utils.fx <span class="hljs-keyword">import</span> symbolic_trace

<span class="hljs-meta">&gt;&gt;&gt; </span>model = BertModel.from_pretrained(<span class="hljs-string">&quot;bert-base-uncased&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>traced = symbolic_trace(
<span class="hljs-meta">&gt;&gt;&gt; </span>    model,
<span class="hljs-meta">&gt;&gt;&gt; </span>    input_names=[<span class="hljs-string">&quot;input_ids&quot;</span>, <span class="hljs-string">&quot;attention_mask&quot;</span>, <span class="hljs-string">&quot;token_type_ids&quot;</span>],
<span class="hljs-meta">&gt;&gt;&gt; </span>)

<span class="hljs-meta">&gt;&gt;&gt; </span>transformation = ChangeMulToAdd()
<span class="hljs-meta">&gt;&gt;&gt; </span>transformed_model = transformation(traced)`}}),ht=new mt({}),ut=new pt({props:{code:`from optimum.fx.optimization import ReversibleTransformation

class MulToMulTimesTwo(ReversibleTransformation):
    def transform(self, graph_module):
        for node in graph_module.graph.nodes:
            if node.op == "call_function" and node.target == operator.mul:
                x, y = node.args
                node.args = (2 * x, y)
        return graph_module

    def reverse(self, graph_module):
        for node in graph_module.graph.nodes:
            if node.op == "call_function" and node.target == operator.mul:
                x, y = node.args
                node.args = (x / 2, y)
        return graph_module`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> ReversibleTransformation

<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">class</span> <span class="hljs-title class_">MulToMulTimesTwo</span>(<span class="hljs-title class_ inherited__">ReversibleTransformation</span>):
<span class="hljs-meta">&gt;&gt;&gt; </span>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">transform</span>(<span class="hljs-params">self, graph_module</span>):
<span class="hljs-meta">&gt;&gt;&gt; </span>        <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> graph_module.graph.nodes:
<span class="hljs-meta">&gt;&gt;&gt; </span>            <span class="hljs-keyword">if</span> node.op == <span class="hljs-string">&quot;call_function&quot;</span> <span class="hljs-keyword">and</span> node.target == operator.mul:
<span class="hljs-meta">&gt;&gt;&gt; </span>                x, y = node.args
<span class="hljs-meta">&gt;&gt;&gt; </span>                node.args = (<span class="hljs-number">2</span> * x, y)
<span class="hljs-meta">&gt;&gt;&gt; </span>        <span class="hljs-keyword">return</span> graph_module

<span class="hljs-meta">&gt;&gt;&gt; </span>    <span class="hljs-keyword">def</span> <span class="hljs-title function_">reverse</span>(<span class="hljs-params">self, graph_module</span>):
<span class="hljs-meta">&gt;&gt;&gt; </span>        <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> graph_module.graph.nodes:
<span class="hljs-meta">&gt;&gt;&gt; </span>            <span class="hljs-keyword">if</span> node.op == <span class="hljs-string">&quot;call_function&quot;</span> <span class="hljs-keyword">and</span> node.target == operator.mul:
<span class="hljs-meta">&gt;&gt;&gt; </span>                x, y = node.args
<span class="hljs-meta">&gt;&gt;&gt; </span>                node.args = (x / <span class="hljs-number">2</span>, y)
<span class="hljs-meta">&gt;&gt;&gt; </span>        <span class="hljs-keyword">return</span> graph_module`}}),gt=new mt({}),_t=new pt({props:{code:`from optimum.fx.optimization import compose
composition = compose(MulToMulTimesTwo(), ChangeMulToAdd())`,highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> optimum.fx.optimization <span class="hljs-keyword">import</span> compose
<span class="hljs-meta">&gt;&gt;&gt; </span>composition = compose(MulToMulTimesTwo(), ChangeMulToAdd())`}}),vt=new mt({}),$t=new mt({}),bt=new M({props:{name:"class optimum.fx.optimization.Transformation",anchor:"optimum.fx.optimization.Transformation",parameters:[],parametersDescription:[{anchor:"optimum.fx.optimization.Transformation.preserves_computation",description:`<strong>preserves_computation</strong> (<code>bool</code>, defaults to <code>False</code>) &#x2014;
Whether the transformation preserves the graph computation or not. If <code>True</code>, the original and the
transformed graph should produce the same outputs.`,name:"preserves_computation"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L88"}}),yt=new M({props:{name:"__call__",anchor:"optimum.fx.optimization.Transformation.__call__",parameters:[{name:"graph_module",val:": GraphModule"},{name:"lint_and_recompile",val:": bool = True"}],parametersDescription:[{anchor:"optimum.fx.optimization.Transformation.__call__.graph_module",description:`<strong>graph_module</strong> (<code>torch.fx.GraphModule</code>) &#x2014;
The module to transform.`,name:"graph_module"},{anchor:"optimum.fx.optimization.Transformation.__call__.lint_and_recompile",description:`<strong>lint_and_recompile</strong> (<code>bool</code>, defaults to <code>True</code>) &#x2014;
Whether the transformed module should be linted and recompiled.
This can be set to <code>False</code> when chaining transformations together to perform this operation only once.`,name:"lint_and_recompile"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L111",returnDescription:`
<p>The transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),wt=new M({props:{name:"get_transformed_nodes",anchor:"optimum.fx.optimization.Transformation.get_transformed_nodes",parameters:[{name:"graph_module",val:": GraphModule"}],parametersDescription:[{anchor:"optimum.fx.optimization.Transformation.get_transformed_nodes.graph_module",description:`<strong>graph_module</strong> (<code>torch.fx.GraphModule</code>) &#x2014;
The graph_module to get the nodes from.`,name:"graph_module"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L164",returnDescription:`
<p>Gives the list of nodes that were transformed by the transformation.</p>
`,returnType:`
<p><code>List[torch.fx.Node]</code></p>
`}}),jt=new M({props:{name:"mark_as_transformed",anchor:"optimum.fx.optimization.Transformation.mark_as_transformed",parameters:[{name:"node",val:": Node"}],parametersDescription:[{anchor:"optimum.fx.optimization.Transformation.mark_as_transformed.node",description:`<strong>node</strong> (<code>torch.fx.Node</code>) &#x2014;
The node to mark as transformed.`,name:"node"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L140"}}),Tt=new M({props:{name:"transform",anchor:"optimum.fx.optimization.Transformation.transform",parameters:[{name:"graph_module",val:": GraphModule"}],parametersDescription:[{anchor:"optimum.fx.optimization.Transformation.transform.graph_module",description:`<strong>graph_module</strong> (<code>torch.fx.GraphModule</code>) &#x2014;
The module to transform.`,name:"graph_module"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L98",returnDescription:`
<p>The transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),kt=new M({props:{name:"transformed",anchor:"optimum.fx.optimization.Transformation.transformed",parameters:[{name:"node",val:": Node"}],parametersDescription:[{anchor:"optimum.fx.optimization.Transformation.transformed.node",description:`<strong>node</strong> (<code>torch.fx.Node</code>) &#x2014;
The node to check.`,name:"node"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L152",returnDescription:`
<p>Specifies whether the node was transformed by this transformation or not.</p>
`,returnType:`
<p><code>bool</code></p>
`}}),zt=new M({props:{name:"class optimum.fx.optimization.ReversibleTransformation",anchor:"optimum.fx.optimization.ReversibleTransformation",parameters:[],parametersDescription:[{anchor:"optimum.fx.optimization.ReversibleTransformation.preserves_computation",description:`<strong>preserves_computation</strong> (<code>bool</code>, defaults to <code>False</code>) &#x2014;
Whether the transformation preserves the graph computation or not. If <code>True</code>, the original and the
transformed graph should produce the same outputs.`,name:"preserves_computation"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L179"}}),Et=new M({props:{name:"__call__",anchor:"optimum.fx.optimization.ReversibleTransformation.__call__",parameters:[{name:"graph_module",val:": GraphModule"},{name:"lint_and_recompile",val:": bool = True"},{name:"reverse",val:": bool = False"}],parametersDescription:[{anchor:"optimum.fx.optimization.ReversibleTransformation.__call__.graph_module",description:`<strong>graph_module</strong> (<code>torch.fx.GraphModule</code>) &#x2014;
The module to transform.`,name:"graph_module"},{anchor:"optimum.fx.optimization.ReversibleTransformation.__call__.lint_and_recompile",description:`<strong>lint_and_recompile</strong> (<code>bool</code>, defaults to <code>True</code>) &#x2014;
Whether the transformed module should be linted and recompiled.
This can be set to <code>False</code> when chaining transformations together to perform this operation only once.`,name:"lint_and_recompile"},{anchor:"optimum.fx.optimization.ReversibleTransformation.__call__.reverse",description:`<strong>reverse</strong> (<code>bool</code>, defaults to <code>False</code>) &#x2014;
If <code>True</code>, the reverse transformation is performed.`,name:"reverse"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L200",returnDescription:`
<p>The transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),Mt=new M({props:{name:"mark_as_restored",anchor:"optimum.fx.optimization.ReversibleTransformation.mark_as_restored",parameters:[{name:"node",val:": Node"}],parametersDescription:[{anchor:"optimum.fx.optimization.ReversibleTransformation.mark_as_restored.node",description:`<strong>node</strong> (<code>torch.fx.Node</code>) &#x2014;
The node to mark as restored.`,name:"node"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L225"}}),At=new M({props:{name:"reverse",anchor:"optimum.fx.optimization.ReversibleTransformation.reverse",parameters:[{name:"graph_module",val:": GraphModule"}],parametersDescription:[{anchor:"optimum.fx.optimization.ReversibleTransformation.reverse.graph_module",description:`<strong>graph_module</strong> (<code>torch.fx.GraphModule</code>) &#x2014;
The module to transform.`,name:"graph_module"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L187",returnDescription:`
<p>The reverse transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),It=new M({props:{name:"optimum.fx.optimization.compose",anchor:"optimum.fx.optimization.compose",parameters:[{name:"*args",val:": Transformation"},{name:"inplace",val:": bool = True"}],parametersDescription:[{anchor:"optimum.fx.optimization.compose.args",description:`<strong>args</strong> (<a href="/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.Transformation">Transformation</a>) &#x2014;
The transformations to compose together.`,name:"args"},{anchor:"optimum.fx.optimization.compose.inplace",description:`<strong>inplace</strong> (<code>bool</code>, defaults to <code>True</code>) &#x2014;
Whether the resulting transformation should be inplace, or create a new graph module.`,name:"inplace"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L504",returnDescription:`
<p>The composition transformation object.</p>
`}}),at=new $a({props:{anchor:"optimum.fx.optimization.compose.example",$$slots:{default:[Vs]},$$scope:{ctx:L}}}),Dt=new mt({}),qt=new M({props:{name:"class optimum.fx.optimization.MergeLinears",anchor:"optimum.fx.optimization.MergeLinears",parameters:[],parametersDescription:[{anchor:"optimum.fx.optimization.MergeLinears.preserves_computation",description:`<strong>preserves_computation</strong> (<code>bool</code>, defaults to <code>False</code>) &#x2014;
Whether the transformation preserves the graph computation or not. If <code>True</code>, the original and the
transformed graph should produce the same outputs.`,name:"preserves_computation"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L240"}}),st=new $a({props:{anchor:"optimum.fx.optimization.MergeLinears.example",$$slots:{default:[Ws]},$$scope:{ctx:L}}}),Pt=new M({props:{name:"class optimum.fx.optimization.FuseBiasInLinear",anchor:"optimum.fx.optimization.FuseBiasInLinear",parameters:[],parametersDescription:[{anchor:"optimum.fx.optimization.FuseBiasInLinear.preserves_computation",description:`<strong>preserves_computation</strong> (<code>bool</code>, defaults to <code>False</code>) &#x2014;
Whether the transformation preserves the graph computation or not. If <code>True</code>, the original and the
transformed graph should produce the same outputs.`,name:"preserves_computation"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L381"}}),rt=new $a({props:{anchor:"optimum.fx.optimization.FuseBiasInLinear.example",$$slots:{default:[Os]},$$scope:{ctx:L}}}),Bt=new M({props:{name:"class optimum.fx.optimization.ChangeTrueDivToMulByInverse",anchor:"optimum.fx.optimization.ChangeTrueDivToMulByInverse",parameters:[],parametersDescription:[{anchor:"optimum.fx.optimization.ChangeTrueDivToMulByInverse.preserves_computation",description:`<strong>preserves_computation</strong> (<code>bool</code>, defaults to <code>False</code>) &#x2014;
Whether the transformation preserves the graph computation or not. If <code>True</code>, the original and the
transformed graph should produce the same outputs.`,name:"preserves_computation"}],source:"https://github.com/huggingface/optimum/blob/vr_302/src/optimum/fx/optimization/transformations.py#L435"}}),nt=new $a({props:{anchor:"optimum.fx.optimization.ChangeTrueDivToMulByInverse.example",$$slots:{default:[Hs]},$$scope:{ctx:L}}}),{c(){u=o("meta"),k=m(),w=o("h1"),h=o("a"),j=o("span"),g(n.$$.fragment),y=m(),me=o("span"),xa=d("Optimization"),Be=m(),H=o("p"),ya=d("The "),pe=o("code"),wa=d("optimum.fx.optimization"),ja=d(" module provides a set of torch.fx graph transformations, along with classes and functions to write your own transformations and compose them."),Le=m(),N=o("h2"),J=o("a"),le=o("span"),g(lt.$$.fragment),Ta=m(),fe=o("span"),ka=d("The transformation guide"),Ce=m(),Ct=o("p"),za=d("In \u{1F917} Optimum, there are two kinds of transformations: reversible and non-reversible transformations."),Ne=m(),F=o("h3"),U=o("a"),de=o("span"),g(ft.$$.fragment),Ea=m(),ce=o("span"),Ma=d("Write a non-reversible transformation"),Fe=m(),C=o("p"),Aa=d("The most basic case of transformations is non-reversible transformations. Those transformations cannot be reversed, meaning that after applying them to a graph module, there is no way to get the original model back. To implement such transformations in \u{1F917} Optimum, it is very easy: you just need to subclass "),Nt=o("a"),Ia=d("Transformation"),Da=d(" and implement the "),Ft=o("a"),qa=d("transform()"),Pa=d(" method."),Re=m(),Rt=o("p"),Ba=d("For instance, the following transformation changes all the multiplications to additions:"),Se=m(),g(dt.$$.fragment),Ge=m(),St=o("p"),La=d("After implementing it, your transformation can be used as a regular function:"),Ve=m(),g(ct.$$.fragment),We=m(),R=o("h3"),K=o("a"),he=o("span"),g(ht.$$.fragment),Ca=m(),ue=o("span"),Na=d("Write a reversible transformation"),Oe=m(),A=o("p"),Fa=d("A reversible transformation implements both the transformation and its reverse, allowing to retrieve the original model from the transformed one. To implement such transformation, you need to subclass "),Gt=o("a"),Ra=d("ReversibleTransformation"),Sa=d(" and implement the "),Vt=o("a"),Ga=d("transform()"),Va=d(" and "),Wt=o("a"),Wa=d("reverse()"),Oa=d(" methods."),He=m(),Ot=o("p"),Ha=d("For instance, the following transformation is reversible:"),Je=m(),g(ut.$$.fragment),Ue=m(),S=o("h3"),Q=o("a"),ge=o("span"),g(gt.$$.fragment),Ja=m(),_e=o("span"),Ua=d("Composing transformations together"),Ke=m(),X=o("p"),Ka=d("As applying mutilple transformations in chain is needed more often that not, "),Ht=o("a"),Qa=d("compose()"),Xa=d(" is provided. It is an utility function that allows you to create a transformation by chaining multiple other transformations."),Qe=m(),g(_t.$$.fragment),Xe=m(),G=o("h2"),Y=o("a"),ve=o("span"),g(vt.$$.fragment),Ya=m(),$e=o("span"),Za=d("The Optimization API"),Ye=m(),V=o("h3"),Z=o("a"),be=o("span"),g($t.$$.fragment),to=m(),xe=o("span"),eo=d("Main classes and functions"),Ze=m(),T=o("div"),g(bt.$$.fragment),ao=m(),ye=o("p"),oo=d("A torch.fx graph transformation."),so=m(),xt=o("p"),ro=d("It  must implemement the "),Jt=o("a"),no=d("transform()"),io=d(` method, and be used as a
callable.`),mo=m(),Ut=o("div"),g(yt.$$.fragment),po=m(),Kt=o("div"),g(wt.$$.fragment),lo=m(),tt=o("div"),g(jt.$$.fragment),fo=m(),we=o("p"),co=d("Marks a node as transformed by this transformation."),ho=m(),Qt=o("div"),g(Tt.$$.fragment),uo=m(),Xt=o("div"),g(kt.$$.fragment),ta=m(),z=o("div"),g(zt.$$.fragment),go=m(),je=o("p"),_o=d("A torch.fx graph transformation that is reversible."),vo=m(),W=o("p"),$o=d("It must implemement the "),Yt=o("a"),bo=d("transform()"),xo=d(` and
`),Zt=o("a"),yo=d("reverse()"),wo=d(" methods, and be used as a callable."),jo=m(),te=o("div"),g(Et.$$.fragment),To=m(),et=o("div"),g(Mt.$$.fragment),ko=m(),Te=o("p"),zo=d("Marks a node as restored back to its original state."),Eo=m(),ee=o("div"),g(At.$$.fragment),ea=m(),D=o("div"),g(It.$$.fragment),Mo=m(),ke=o("p"),Ao=d("Composes a list of transformations together."),Io=m(),g(at.$$.fragment),aa=m(),O=o("h3"),ot=o("a"),ze=o("span"),g(Dt.$$.fragment),Do=m(),Ee=o("span"),qo=d("Transformations"),oa=m(),q=o("div"),g(qt.$$.fragment),Po=m(),Me=o("p"),Bo=d("Transformation that merges linear layers that take the same input into one big linear layer."),Lo=m(),g(st.$$.fragment),sa=m(),P=o("div"),g(Pt.$$.fragment),Co=m(),Ae=o("p"),No=d("Transformation that fuses the bias to the weight in torch.nn.Linear."),Fo=m(),g(rt.$$.fragment),ra=m(),B=o("div"),g(Bt.$$.fragment),Ro=m(),Ie=o("p"),So=d(`Transformation that changes truediv nodes to multiplication by the inverse nodes when the denominator is static.
For example, that is sometimes the case for the scaling factor in attention layers.`),Go=m(),g(nt.$$.fragment),this.h()},l(t){const i=Ss('[data-svelte="svelte-1phssyn"]',document.head);u=s(i,"META",{name:!0,content:!0}),i.forEach(e),k=p(t),w=s(t,"H1",{class:!0});var Lt=r(w);h=s(Lt,"A",{id:!0,class:!0,href:!0});var De=r(h);j=s(De,"SPAN",{});var qe=r(j);_(n.$$.fragment,qe),qe.forEach(e),De.forEach(e),y=p(Lt),me=s(Lt,"SPAN",{});var Pe=r(me);xa=c(Pe,"Optimization"),Pe.forEach(e),Lt.forEach(e),Be=p(t),H=s(t,"P",{});var ia=r(H);ya=c(ia,"The "),pe=s(ia,"CODE",{});var Vo=r(pe);wa=c(Vo,"optimum.fx.optimization"),Vo.forEach(e),ja=c(ia," module provides a set of torch.fx graph transformations, along with classes and functions to write your own transformations and compose them."),ia.forEach(e),Le=p(t),N=s(t,"H2",{class:!0});var ma=r(N);J=s(ma,"A",{id:!0,class:!0,href:!0});var Wo=r(J);le=s(Wo,"SPAN",{});var Oo=r(le);_(lt.$$.fragment,Oo),Oo.forEach(e),Wo.forEach(e),Ta=p(ma),fe=s(ma,"SPAN",{});var Ho=r(fe);ka=c(Ho,"The transformation guide"),Ho.forEach(e),ma.forEach(e),Ce=p(t),Ct=s(t,"P",{});var Jo=r(Ct);za=c(Jo,"In \u{1F917} Optimum, there are two kinds of transformations: reversible and non-reversible transformations."),Jo.forEach(e),Ne=p(t),F=s(t,"H3",{class:!0});var pa=r(F);U=s(pa,"A",{id:!0,class:!0,href:!0});var Uo=r(U);de=s(Uo,"SPAN",{});var Ko=r(de);_(ft.$$.fragment,Ko),Ko.forEach(e),Uo.forEach(e),Ea=p(pa),ce=s(pa,"SPAN",{});var Qo=r(ce);Ma=c(Qo,"Write a non-reversible transformation"),Qo.forEach(e),pa.forEach(e),Fe=p(t),C=s(t,"P",{});var ae=r(C);Aa=c(ae,"The most basic case of transformations is non-reversible transformations. Those transformations cannot be reversed, meaning that after applying them to a graph module, there is no way to get the original model back. To implement such transformations in \u{1F917} Optimum, it is very easy: you just need to subclass "),Nt=s(ae,"A",{href:!0});var Xo=r(Nt);Ia=c(Xo,"Transformation"),Xo.forEach(e),Da=c(ae," and implement the "),Ft=s(ae,"A",{href:!0});var Yo=r(Ft);qa=c(Yo,"transform()"),Yo.forEach(e),Pa=c(ae," method."),ae.forEach(e),Re=p(t),Rt=s(t,"P",{});var Zo=r(Rt);Ba=c(Zo,"For instance, the following transformation changes all the multiplications to additions:"),Zo.forEach(e),Se=p(t),_(dt.$$.fragment,t),Ge=p(t),St=s(t,"P",{});var ts=r(St);La=c(ts,"After implementing it, your transformation can be used as a regular function:"),ts.forEach(e),Ve=p(t),_(ct.$$.fragment,t),We=p(t),R=s(t,"H3",{class:!0});var la=r(R);K=s(la,"A",{id:!0,class:!0,href:!0});var es=r(K);he=s(es,"SPAN",{});var as=r(he);_(ht.$$.fragment,as),as.forEach(e),es.forEach(e),Ca=p(la),ue=s(la,"SPAN",{});var os=r(ue);Na=c(os,"Write a reversible transformation"),os.forEach(e),la.forEach(e),Oe=p(t),A=s(t,"P",{});var it=r(A);Fa=c(it,"A reversible transformation implements both the transformation and its reverse, allowing to retrieve the original model from the transformed one. To implement such transformation, you need to subclass "),Gt=s(it,"A",{href:!0});var ss=r(Gt);Ra=c(ss,"ReversibleTransformation"),ss.forEach(e),Sa=c(it," and implement the "),Vt=s(it,"A",{href:!0});var rs=r(Vt);Ga=c(rs,"transform()"),rs.forEach(e),Va=c(it," and "),Wt=s(it,"A",{href:!0});var ns=r(Wt);Wa=c(ns,"reverse()"),ns.forEach(e),Oa=c(it," methods."),it.forEach(e),He=p(t),Ot=s(t,"P",{});var is=r(Ot);Ha=c(is,"For instance, the following transformation is reversible:"),is.forEach(e),Je=p(t),_(ut.$$.fragment,t),Ue=p(t),S=s(t,"H3",{class:!0});var fa=r(S);Q=s(fa,"A",{id:!0,class:!0,href:!0});var ms=r(Q);ge=s(ms,"SPAN",{});var ps=r(ge);_(gt.$$.fragment,ps),ps.forEach(e),ms.forEach(e),Ja=p(fa),_e=s(fa,"SPAN",{});var ls=r(_e);Ua=c(ls,"Composing transformations together"),ls.forEach(e),fa.forEach(e),Ke=p(t),X=s(t,"P",{});var da=r(X);Ka=c(da,"As applying mutilple transformations in chain is needed more often that not, "),Ht=s(da,"A",{href:!0});var fs=r(Ht);Qa=c(fs,"compose()"),fs.forEach(e),Xa=c(da," is provided. It is an utility function that allows you to create a transformation by chaining multiple other transformations."),da.forEach(e),Qe=p(t),_(_t.$$.fragment,t),Xe=p(t),G=s(t,"H2",{class:!0});var ca=r(G);Y=s(ca,"A",{id:!0,class:!0,href:!0});var ds=r(Y);ve=s(ds,"SPAN",{});var cs=r(ve);_(vt.$$.fragment,cs),cs.forEach(e),ds.forEach(e),Ya=p(ca),$e=s(ca,"SPAN",{});var hs=r($e);Za=c(hs,"The Optimization API"),hs.forEach(e),ca.forEach(e),Ye=p(t),V=s(t,"H3",{class:!0});var ha=r(V);Z=s(ha,"A",{id:!0,class:!0,href:!0});var us=r(Z);be=s(us,"SPAN",{});var gs=r(be);_($t.$$.fragment,gs),gs.forEach(e),us.forEach(e),to=p(ha),xe=s(ha,"SPAN",{});var _s=r(xe);eo=c(_s,"Main classes and functions"),_s.forEach(e),ha.forEach(e),Ze=p(t),T=s(t,"DIV",{class:!0});var E=r(T);_(bt.$$.fragment,E),ao=p(E),ye=s(E,"P",{});var vs=r(ye);oo=c(vs,"A torch.fx graph transformation."),vs.forEach(e),so=p(E),xt=s(E,"P",{});var ua=r(xt);ro=c(ua,"It  must implemement the "),Jt=s(ua,"A",{href:!0});var $s=r(Jt);no=c($s,"transform()"),$s.forEach(e),io=c(ua,` method, and be used as a
callable.`),ua.forEach(e),mo=p(E),Ut=s(E,"DIV",{class:!0});var bs=r(Ut);_(yt.$$.fragment,bs),bs.forEach(e),po=p(E),Kt=s(E,"DIV",{class:!0});var xs=r(Kt);_(wt.$$.fragment,xs),xs.forEach(e),lo=p(E),tt=s(E,"DIV",{class:!0});var ga=r(tt);_(jt.$$.fragment,ga),fo=p(ga),we=s(ga,"P",{});var ys=r(we);co=c(ys,"Marks a node as transformed by this transformation."),ys.forEach(e),ga.forEach(e),ho=p(E),Qt=s(E,"DIV",{class:!0});var ws=r(Qt);_(Tt.$$.fragment,ws),ws.forEach(e),uo=p(E),Xt=s(E,"DIV",{class:!0});var js=r(Xt);_(kt.$$.fragment,js),js.forEach(e),E.forEach(e),ta=p(t),z=s(t,"DIV",{class:!0});var I=r(z);_(zt.$$.fragment,I),go=p(I),je=s(I,"P",{});var Ts=r(je);_o=c(Ts,"A torch.fx graph transformation that is reversible."),Ts.forEach(e),vo=p(I),W=s(I,"P",{});var oe=r(W);$o=c(oe,"It must implemement the "),Yt=s(oe,"A",{href:!0});var ks=r(Yt);bo=c(ks,"transform()"),ks.forEach(e),xo=c(oe,` and
`),Zt=s(oe,"A",{href:!0});var zs=r(Zt);yo=c(zs,"reverse()"),zs.forEach(e),wo=c(oe," methods, and be used as a callable."),oe.forEach(e),jo=p(I),te=s(I,"DIV",{class:!0});var Es=r(te);_(Et.$$.fragment,Es),Es.forEach(e),To=p(I),et=s(I,"DIV",{class:!0});var _a=r(et);_(Mt.$$.fragment,_a),ko=p(_a),Te=s(_a,"P",{});var Ms=r(Te);zo=c(Ms,"Marks a node as restored back to its original state."),Ms.forEach(e),_a.forEach(e),Eo=p(I),ee=s(I,"DIV",{class:!0});var As=r(ee);_(At.$$.fragment,As),As.forEach(e),I.forEach(e),ea=p(t),D=s(t,"DIV",{class:!0});var se=r(D);_(It.$$.fragment,se),Mo=p(se),ke=s(se,"P",{});var Is=r(ke);Ao=c(Is,"Composes a list of transformations together."),Is.forEach(e),Io=p(se),_(at.$$.fragment,se),se.forEach(e),aa=p(t),O=s(t,"H3",{class:!0});var va=r(O);ot=s(va,"A",{id:!0,class:!0,href:!0});var Ds=r(ot);ze=s(Ds,"SPAN",{});var qs=r(ze);_(Dt.$$.fragment,qs),qs.forEach(e),Ds.forEach(e),Do=p(va),Ee=s(va,"SPAN",{});var Ps=r(Ee);qo=c(Ps,"Transformations"),Ps.forEach(e),va.forEach(e),oa=p(t),q=s(t,"DIV",{class:!0});var re=r(q);_(qt.$$.fragment,re),Po=p(re),Me=s(re,"P",{});var Bs=r(Me);Bo=c(Bs,"Transformation that merges linear layers that take the same input into one big linear layer."),Bs.forEach(e),Lo=p(re),_(st.$$.fragment,re),re.forEach(e),sa=p(t),P=s(t,"DIV",{class:!0});var ne=r(P);_(Pt.$$.fragment,ne),Co=p(ne),Ae=s(ne,"P",{});var Ls=r(Ae);No=c(Ls,"Transformation that fuses the bias to the weight in torch.nn.Linear."),Ls.forEach(e),Fo=p(ne),_(rt.$$.fragment,ne),ne.forEach(e),ra=p(t),B=s(t,"DIV",{class:!0});var ie=r(B);_(Bt.$$.fragment,ie),Ro=p(ie),Ie=s(ie,"P",{});var Cs=r(Ie);So=c(Cs,`Transformation that changes truediv nodes to multiplication by the inverse nodes when the denominator is static.
For example, that is sometimes the case for the scaling factor in attention layers.`),Cs.forEach(e),Go=p(ie),_(nt.$$.fragment,ie),ie.forEach(e),this.h()},h(){l(u,"name","hf:doc:metadata"),l(u,"content",JSON.stringify(Us)),l(h,"id","optimization"),l(h,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(h,"href","#optimization"),l(w,"class","relative group"),l(J,"id","the-transformation-guide"),l(J,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(J,"href","#the-transformation-guide"),l(N,"class","relative group"),l(U,"id","write-a-nonreversible-transformation"),l(U,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(U,"href","#write-a-nonreversible-transformation"),l(F,"class","relative group"),l(Nt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.Transformation"),l(Ft,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(K,"id","write-a-reversible-transformation"),l(K,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(K,"href","#write-a-reversible-transformation"),l(R,"class","relative group"),l(Gt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.ReversibleTransformation"),l(Vt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(Wt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.ReversibleTransformation.reverse"),l(Q,"id","composing-transformations-together"),l(Q,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(Q,"href","#composing-transformations-together"),l(S,"class","relative group"),l(Ht,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.compose"),l(Y,"id","the-optimization-api"),l(Y,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(Y,"href","#the-optimization-api"),l(G,"class","relative group"),l(Z,"id","optimum.fx.optimization.Transformation"),l(Z,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(Z,"href","#optimum.fx.optimization.Transformation"),l(V,"class","relative group"),l(Jt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(Ut,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Kt,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(tt,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Qt,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Xt,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(T,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Yt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(Zt,"href","/docs/optimum/pr_302/en/fx/optimization#optimum.fx.optimization.ReversibleTransformation.reverse"),l(te,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(et,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(ee,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(z,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(D,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(ot,"id","optimum.fx.optimization.MergeLinears"),l(ot,"class","header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full"),l(ot,"href","#optimum.fx.optimization.MergeLinears"),l(O,"class","relative group"),l(q,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(P,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(B,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8")},m(t,i){a(document.head,u),f(t,k,i),f(t,w,i),a(w,h),a(h,j),v(n,j,null),a(w,y),a(w,me),a(me,xa),f(t,Be,i),f(t,H,i),a(H,ya),a(H,pe),a(pe,wa),a(H,ja),f(t,Le,i),f(t,N,i),a(N,J),a(J,le),v(lt,le,null),a(N,Ta),a(N,fe),a(fe,ka),f(t,Ce,i),f(t,Ct,i),a(Ct,za),f(t,Ne,i),f(t,F,i),a(F,U),a(U,de),v(ft,de,null),a(F,Ea),a(F,ce),a(ce,Ma),f(t,Fe,i),f(t,C,i),a(C,Aa),a(C,Nt),a(Nt,Ia),a(C,Da),a(C,Ft),a(Ft,qa),a(C,Pa),f(t,Re,i),f(t,Rt,i),a(Rt,Ba),f(t,Se,i),v(dt,t,i),f(t,Ge,i),f(t,St,i),a(St,La),f(t,Ve,i),v(ct,t,i),f(t,We,i),f(t,R,i),a(R,K),a(K,he),v(ht,he,null),a(R,Ca),a(R,ue),a(ue,Na),f(t,Oe,i),f(t,A,i),a(A,Fa),a(A,Gt),a(Gt,Ra),a(A,Sa),a(A,Vt),a(Vt,Ga),a(A,Va),a(A,Wt),a(Wt,Wa),a(A,Oa),f(t,He,i),f(t,Ot,i),a(Ot,Ha),f(t,Je,i),v(ut,t,i),f(t,Ue,i),f(t,S,i),a(S,Q),a(Q,ge),v(gt,ge,null),a(S,Ja),a(S,_e),a(_e,Ua),f(t,Ke,i),f(t,X,i),a(X,Ka),a(X,Ht),a(Ht,Qa),a(X,Xa),f(t,Qe,i),v(_t,t,i),f(t,Xe,i),f(t,G,i),a(G,Y),a(Y,ve),v(vt,ve,null),a(G,Ya),a(G,$e),a($e,Za),f(t,Ye,i),f(t,V,i),a(V,Z),a(Z,be),v($t,be,null),a(V,to),a(V,xe),a(xe,eo),f(t,Ze,i),f(t,T,i),v(bt,T,null),a(T,ao),a(T,ye),a(ye,oo),a(T,so),a(T,xt),a(xt,ro),a(xt,Jt),a(Jt,no),a(xt,io),a(T,mo),a(T,Ut),v(yt,Ut,null),a(T,po),a(T,Kt),v(wt,Kt,null),a(T,lo),a(T,tt),v(jt,tt,null),a(tt,fo),a(tt,we),a(we,co),a(T,ho),a(T,Qt),v(Tt,Qt,null),a(T,uo),a(T,Xt),v(kt,Xt,null),f(t,ta,i),f(t,z,i),v(zt,z,null),a(z,go),a(z,je),a(je,_o),a(z,vo),a(z,W),a(W,$o),a(W,Yt),a(Yt,bo),a(W,xo),a(W,Zt),a(Zt,yo),a(W,wo),a(z,jo),a(z,te),v(Et,te,null),a(z,To),a(z,et),v(Mt,et,null),a(et,ko),a(et,Te),a(Te,zo),a(z,Eo),a(z,ee),v(At,ee,null),f(t,ea,i),f(t,D,i),v(It,D,null),a(D,Mo),a(D,ke),a(ke,Ao),a(D,Io),v(at,D,null),f(t,aa,i),f(t,O,i),a(O,ot),a(ot,ze),v(Dt,ze,null),a(O,Do),a(O,Ee),a(Ee,qo),f(t,oa,i),f(t,q,i),v(qt,q,null),a(q,Po),a(q,Me),a(Me,Bo),a(q,Lo),v(st,q,null),f(t,sa,i),f(t,P,i),v(Pt,P,null),a(P,Co),a(P,Ae),a(Ae,No),a(P,Fo),v(rt,P,null),f(t,ra,i),f(t,B,i),v(Bt,B,null),a(B,Ro),a(B,Ie),a(Ie,So),a(B,Go),v(nt,B,null),na=!0},p(t,[i]){const Lt={};i&2&&(Lt.$$scope={dirty:i,ctx:t}),at.$set(Lt);const De={};i&2&&(De.$$scope={dirty:i,ctx:t}),st.$set(De);const qe={};i&2&&(qe.$$scope={dirty:i,ctx:t}),rt.$set(qe);const Pe={};i&2&&(Pe.$$scope={dirty:i,ctx:t}),nt.$set(Pe)},i(t){na||($(n.$$.fragment,t),$(lt.$$.fragment,t),$(ft.$$.fragment,t),$(dt.$$.fragment,t),$(ct.$$.fragment,t),$(ht.$$.fragment,t),$(ut.$$.fragment,t),$(gt.$$.fragment,t),$(_t.$$.fragment,t),$(vt.$$.fragment,t),$($t.$$.fragment,t),$(bt.$$.fragment,t),$(yt.$$.fragment,t),$(wt.$$.fragment,t),$(jt.$$.fragment,t),$(Tt.$$.fragment,t),$(kt.$$.fragment,t),$(zt.$$.fragment,t),$(Et.$$.fragment,t),$(Mt.$$.fragment,t),$(At.$$.fragment,t),$(It.$$.fragment,t),$(at.$$.fragment,t),$(Dt.$$.fragment,t),$(qt.$$.fragment,t),$(st.$$.fragment,t),$(Pt.$$.fragment,t),$(rt.$$.fragment,t),$(Bt.$$.fragment,t),$(nt.$$.fragment,t),na=!0)},o(t){b(n.$$.fragment,t),b(lt.$$.fragment,t),b(ft.$$.fragment,t),b(dt.$$.fragment,t),b(ct.$$.fragment,t),b(ht.$$.fragment,t),b(ut.$$.fragment,t),b(gt.$$.fragment,t),b(_t.$$.fragment,t),b(vt.$$.fragment,t),b($t.$$.fragment,t),b(bt.$$.fragment,t),b(yt.$$.fragment,t),b(wt.$$.fragment,t),b(jt.$$.fragment,t),b(Tt.$$.fragment,t),b(kt.$$.fragment,t),b(zt.$$.fragment,t),b(Et.$$.fragment,t),b(Mt.$$.fragment,t),b(At.$$.fragment,t),b(It.$$.fragment,t),b(at.$$.fragment,t),b(Dt.$$.fragment,t),b(qt.$$.fragment,t),b(st.$$.fragment,t),b(Pt.$$.fragment,t),b(rt.$$.fragment,t),b(Bt.$$.fragment,t),b(nt.$$.fragment,t),na=!1},d(t){e(u),t&&e(k),t&&e(w),x(n),t&&e(Be),t&&e(H),t&&e(Le),t&&e(N),x(lt),t&&e(Ce),t&&e(Ct),t&&e(Ne),t&&e(F),x(ft),t&&e(Fe),t&&e(C),t&&e(Re),t&&e(Rt),t&&e(Se),x(dt,t),t&&e(Ge),t&&e(St),t&&e(Ve),x(ct,t),t&&e(We),t&&e(R),x(ht),t&&e(Oe),t&&e(A),t&&e(He),t&&e(Ot),t&&e(Je),x(ut,t),t&&e(Ue),t&&e(S),x(gt),t&&e(Ke),t&&e(X),t&&e(Qe),x(_t,t),t&&e(Xe),t&&e(G),x(vt),t&&e(Ye),t&&e(V),x($t),t&&e(Ze),t&&e(T),x(bt),x(yt),x(wt),x(jt),x(Tt),x(kt),t&&e(ta),t&&e(z),x(zt),x(Et),x(Mt),x(At),t&&e(ea),t&&e(D),x(It),x(at),t&&e(aa),t&&e(O),x(Dt),t&&e(oa),t&&e(q),x(qt),x(st),t&&e(sa),t&&e(P),x(Pt),x(rt),t&&e(ra),t&&e(B),x(Bt),x(nt)}}}const Us={local:"optimization",sections:[{local:"the-transformation-guide",sections:[{local:"write-a-nonreversible-transformation",title:"Write a non-reversible transformation"},{local:"write-a-reversible-transformation",title:"Write a reversible transformation"},{local:"composing-transformations-together",title:"Composing transformations together"}],title:"The transformation guide"},{local:"the-optimization-api",sections:[{local:"optimum.fx.optimization.Transformation",title:"Main classes and functions"},{local:"optimum.fx.optimization.MergeLinears",title:"Transformations"}],title:"The Optimization API"}],title:"Optimization"};function Ks(L){return Gs(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class er extends Ns{constructor(u){super();Fs(this,u,Ks,Js,Rs,{})}}export{er as default,Us as metadata};
