import{S as so,i as oo,s as ro,e as s,k as p,w as g,t as c,M as no,c as o,d as e,m as f,a as r,x as _,h,b as l,G as a,g as m,y as v,q as $,o as b,B as y,v as io,L as fs}from"../../chunks/vendor-hf-doc-builder.js";import{D as O}from"../../chunks/Docstring-hf-doc-builder.js";import{C as zt}from"../../chunks/CodeBlock-hf-doc-builder.js";import{I as ot}from"../../chunks/IconCopyLink-hf-doc-builder.js";import{E as ps}from"../../chunks/ExampleCodeBlock-hf-doc-builder.js";function lo(W){let u,T,x,d,j;return d=new zt({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=s("p"),T=c("Example:"),x=p(),g(d.$$.fragment)},l(i){u=o(i,"P",{});var w=r(u);T=h(w,"Example:"),w.forEach(e),x=f(i),_(d.$$.fragment,i)},m(i,w){m(i,u,w),a(u,T),m(i,x,w),v(d,i,w),j=!0},p:fs,i(i){j||($(d.$$.fragment,i),j=!0)},o(i){b(d.$$.fragment,i),j=!1},d(i){i&&e(u),i&&e(x),y(d,i)}}}function mo(W){let u,T,x,d,j;return d=new zt({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=s("p"),T=c("Example:"),x=p(),g(d.$$.fragment)},l(i){u=o(i,"P",{});var w=r(u);T=h(w,"Example:"),w.forEach(e),x=f(i),_(d.$$.fragment,i)},m(i,w){m(i,u,w),a(u,T),m(i,x,w),v(d,i,w),j=!0},p:fs,i(i){j||($(d.$$.fragment,i),j=!0)},o(i){b(d.$$.fragment,i),j=!1},d(i){i&&e(u),i&&e(x),y(d,i)}}}function po(W){let u,T,x,d,j;return d=new zt({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=s("p"),T=c("Example:"),x=p(),g(d.$$.fragment)},l(i){u=o(i,"P",{});var w=r(u);T=h(w,"Example:"),w.forEach(e),x=f(i),_(d.$$.fragment,i)},m(i,w){m(i,u,w),a(u,T),m(i,x,w),v(d,i,w),j=!0},p:fs,i(i){j||($(d.$$.fragment,i),j=!0)},o(i){b(d.$$.fragment,i),j=!1},d(i){i&&e(u),i&&e(x),y(d,i)}}}function fo(W){let u,T,x,d,j,i,w,Qt,ta,$e,V,ea,Xt,aa,sa,be,B,H,Yt,rt,oa,Zt,ra,ye,Et,na,xe,C,J,te,nt,ia,ee,la,we,P,ma,Mt,pa,fa,At,ca,ha,je,qt,da,Te,it,ke,Pt,ua,ze,lt,Ee,L,U,ae,mt,ga,se,_a,Me,E,va,It,$a,ba,Dt,ya,xa,Bt,wa,ja,Ae,Ct,Ta,qe,pt,Pe,S,K,oe,ft,ka,re,za,Ie,Q,Ea,Lt,Ma,Aa,De,ct,Be,R,X,ne,ht,qa,ie,Pa,Ce,N,Y,le,dt,Ia,me,Da,Le,k,ut,Ba,pe,Ca,La,gt,Sa,St,Ra,Na,Fa,Rt,_t,Ga,Nt,vt,Se,z,$t,Oa,fe,Wa,Va,F,Ha,Ft,Ja,Ua,Gt,Ka,Qa,Xa,Ot,bt,Ya,Wt,yt,Re,M,xt,Za,ce,ts,es,Z,Ne,G,tt,he,wt,as,de,ss,Fe,A,jt,os,ue,rs,ns,et,Ge,q,Tt,is,ge,ls,ms,at,Oe;return i=new ot({}),rt=new ot({}),nt=new ot({}),it=new zt({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`}}),lt=new zt({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)`}}),mt=new ot({}),pt=new zt({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`}}),ft=new ot({}),ct=new zt({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())`}}),ht=new ot({}),dt=new ot({}),ut=new O({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_181/src/optimum/fx/optimization/transformations.py#L87"}}),_t=new O({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_181/src/optimum/fx/optimization/transformations.py#L110",returnDescription:`
<p>The transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),vt=new O({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_181/src/optimum/fx/optimization/transformations.py#L97",returnDescription:`
<p>The transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),$t=new O({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_181/src/optimum/fx/optimization/transformations.py#L131"}}),bt=new O({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_181/src/optimum/fx/optimization/transformations.py#L152",returnDescription:`
<p>The transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),yt=new O({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_181/src/optimum/fx/optimization/transformations.py#L139",returnDescription:`
<p>The reverse transformed module.</p>
`,returnType:`
<p><code>torch.fx.GraphModule</code></p>
`}}),xt=new O({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_181/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_181/src/optimum/fx/optimization/transformations.py#L375",returnDescription:`
<p>The composition transformation object.</p>
`}}),Z=new ps({props:{anchor:"optimum.fx.optimization.compose.example",$$slots:{default:[lo]},$$scope:{ctx:W}}}),wt=new ot({}),jt=new O({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_181/src/optimum/fx/optimization/transformations.py#L179"}}),et=new ps({props:{anchor:"optimum.fx.optimization.MergeLinears.example",$$slots:{default:[mo]},$$scope:{ctx:W}}}),Tt=new O({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_181/src/optimum/fx/optimization/transformations.py#L306"}}),at=new ps({props:{anchor:"optimum.fx.optimization.ChangeTrueDivToMulByInverse.example",$$slots:{default:[po]},$$scope:{ctx:W}}}),{c(){u=s("meta"),T=p(),x=s("h1"),d=s("a"),j=s("span"),g(i.$$.fragment),w=p(),Qt=s("span"),ta=c("Optimization"),$e=p(),V=s("p"),ea=c("The "),Xt=s("code"),aa=c("optimum.fx.optimization"),sa=c(" module provides a set of torch.fx graph transformations, along with classes and functions to write your own transformations and compose them."),be=p(),B=s("h2"),H=s("a"),Yt=s("span"),g(rt.$$.fragment),oa=p(),Zt=s("span"),ra=c("The transformation guide"),ye=p(),Et=s("p"),na=c("In \u{1F917} Optimum, there are two kinds of transformations: reversible and non-reversible transformations."),xe=p(),C=s("h3"),J=s("a"),te=s("span"),g(nt.$$.fragment),ia=p(),ee=s("span"),la=c("Write a non-reversible transformation"),we=p(),P=s("p"),ma=c("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 "),Mt=s("a"),pa=c("Transformation"),fa=c(" and implement the "),At=s("a"),ca=c("transform()"),ha=c(" method."),je=p(),qt=s("p"),da=c("For instance, the following transformation changes all the multiplications to additions:"),Te=p(),g(it.$$.fragment),ke=p(),Pt=s("p"),ua=c("After implementing it, your transformation can be used as a regular function:"),ze=p(),g(lt.$$.fragment),Ee=p(),L=s("h3"),U=s("a"),ae=s("span"),g(mt.$$.fragment),ga=p(),se=s("span"),_a=c("Write a reversible transformation"),Me=p(),E=s("p"),va=c("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 "),It=s("a"),$a=c("ReversibleTransformation"),ba=c(" and implement the "),Dt=s("a"),ya=c("transform()"),xa=c(" and "),Bt=s("a"),wa=c("reverse()"),ja=c(" methods."),Ae=p(),Ct=s("p"),Ta=c("For instance, the following transformation is reversible:"),qe=p(),g(pt.$$.fragment),Pe=p(),S=s("h3"),K=s("a"),oe=s("span"),g(ft.$$.fragment),ka=p(),re=s("span"),za=c("Composing transformations together"),Ie=p(),Q=s("p"),Ea=c("As applying mutilple transformations in chain is needed more often that not, "),Lt=s("a"),Ma=c("compose()"),Aa=c(" is provided. It is an utility function that allows you to create a transformation by chaining multiple other transformations."),De=p(),g(ct.$$.fragment),Be=p(),R=s("h2"),X=s("a"),ne=s("span"),g(ht.$$.fragment),qa=p(),ie=s("span"),Pa=c("The Optimization API"),Ce=p(),N=s("h3"),Y=s("a"),le=s("span"),g(dt.$$.fragment),Ia=p(),me=s("span"),Da=c("Main classes and functions"),Le=p(),k=s("div"),g(ut.$$.fragment),Ba=p(),pe=s("p"),Ca=c("A torch.fx graph transformation."),La=p(),gt=s("p"),Sa=c("It  must implemement the "),St=s("a"),Ra=c("transform()"),Na=c(` method, and be used as a
callable.`),Fa=p(),Rt=s("div"),g(_t.$$.fragment),Ga=p(),Nt=s("div"),g(vt.$$.fragment),Se=p(),z=s("div"),g($t.$$.fragment),Oa=p(),fe=s("p"),Wa=c("A torch.fx graph transformation that is reversible."),Va=p(),F=s("p"),Ha=c("It must implemement the "),Ft=s("a"),Ja=c("transform()"),Ua=c(` and
`),Gt=s("a"),Ka=c("reverse()"),Qa=c(" methods, and be used as a callable."),Xa=p(),Ot=s("div"),g(bt.$$.fragment),Ya=p(),Wt=s("div"),g(yt.$$.fragment),Re=p(),M=s("div"),g(xt.$$.fragment),Za=p(),ce=s("p"),ts=c("Composes a list of transformations together."),es=p(),g(Z.$$.fragment),Ne=p(),G=s("h3"),tt=s("a"),he=s("span"),g(wt.$$.fragment),as=p(),de=s("span"),ss=c("Transformations"),Fe=p(),A=s("div"),g(jt.$$.fragment),os=p(),ue=s("p"),rs=c("Transformation that merges linear layers that take the same input into one big linear layer."),ns=p(),g(et.$$.fragment),Ge=p(),q=s("div"),g(Tt.$$.fragment),is=p(),ge=s("p"),ls=c(`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.`),ms=p(),g(at.$$.fragment),this.h()},l(t){const n=no('[data-svelte="svelte-1phssyn"]',document.head);u=o(n,"META",{name:!0,content:!0}),n.forEach(e),T=f(t),x=o(t,"H1",{class:!0});var kt=r(x);d=o(kt,"A",{id:!0,class:!0,href:!0});var _e=r(d);j=o(_e,"SPAN",{});var ve=r(j);_(i.$$.fragment,ve),ve.forEach(e),_e.forEach(e),w=f(kt),Qt=o(kt,"SPAN",{});var cs=r(Qt);ta=h(cs,"Optimization"),cs.forEach(e),kt.forEach(e),$e=f(t),V=o(t,"P",{});var We=r(V);ea=h(We,"The "),Xt=o(We,"CODE",{});var hs=r(Xt);aa=h(hs,"optimum.fx.optimization"),hs.forEach(e),sa=h(We," module provides a set of torch.fx graph transformations, along with classes and functions to write your own transformations and compose them."),We.forEach(e),be=f(t),B=o(t,"H2",{class:!0});var Ve=r(B);H=o(Ve,"A",{id:!0,class:!0,href:!0});var ds=r(H);Yt=o(ds,"SPAN",{});var us=r(Yt);_(rt.$$.fragment,us),us.forEach(e),ds.forEach(e),oa=f(Ve),Zt=o(Ve,"SPAN",{});var gs=r(Zt);ra=h(gs,"The transformation guide"),gs.forEach(e),Ve.forEach(e),ye=f(t),Et=o(t,"P",{});var _s=r(Et);na=h(_s,"In \u{1F917} Optimum, there are two kinds of transformations: reversible and non-reversible transformations."),_s.forEach(e),xe=f(t),C=o(t,"H3",{class:!0});var He=r(C);J=o(He,"A",{id:!0,class:!0,href:!0});var vs=r(J);te=o(vs,"SPAN",{});var $s=r(te);_(nt.$$.fragment,$s),$s.forEach(e),vs.forEach(e),ia=f(He),ee=o(He,"SPAN",{});var bs=r(ee);la=h(bs,"Write a non-reversible transformation"),bs.forEach(e),He.forEach(e),we=f(t),P=o(t,"P",{});var Vt=r(P);ma=h(Vt,"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 "),Mt=o(Vt,"A",{href:!0});var ys=r(Mt);pa=h(ys,"Transformation"),ys.forEach(e),fa=h(Vt," and implement the "),At=o(Vt,"A",{href:!0});var xs=r(At);ca=h(xs,"transform()"),xs.forEach(e),ha=h(Vt," method."),Vt.forEach(e),je=f(t),qt=o(t,"P",{});var ws=r(qt);da=h(ws,"For instance, the following transformation changes all the multiplications to additions:"),ws.forEach(e),Te=f(t),_(it.$$.fragment,t),ke=f(t),Pt=o(t,"P",{});var js=r(Pt);ua=h(js,"After implementing it, your transformation can be used as a regular function:"),js.forEach(e),ze=f(t),_(lt.$$.fragment,t),Ee=f(t),L=o(t,"H3",{class:!0});var Je=r(L);U=o(Je,"A",{id:!0,class:!0,href:!0});var Ts=r(U);ae=o(Ts,"SPAN",{});var ks=r(ae);_(mt.$$.fragment,ks),ks.forEach(e),Ts.forEach(e),ga=f(Je),se=o(Je,"SPAN",{});var zs=r(se);_a=h(zs,"Write a reversible transformation"),zs.forEach(e),Je.forEach(e),Me=f(t),E=o(t,"P",{});var st=r(E);va=h(st,"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 "),It=o(st,"A",{href:!0});var Es=r(It);$a=h(Es,"ReversibleTransformation"),Es.forEach(e),ba=h(st," and implement the "),Dt=o(st,"A",{href:!0});var Ms=r(Dt);ya=h(Ms,"transform()"),Ms.forEach(e),xa=h(st," and "),Bt=o(st,"A",{href:!0});var As=r(Bt);wa=h(As,"reverse()"),As.forEach(e),ja=h(st," methods."),st.forEach(e),Ae=f(t),Ct=o(t,"P",{});var qs=r(Ct);Ta=h(qs,"For instance, the following transformation is reversible:"),qs.forEach(e),qe=f(t),_(pt.$$.fragment,t),Pe=f(t),S=o(t,"H3",{class:!0});var Ue=r(S);K=o(Ue,"A",{id:!0,class:!0,href:!0});var Ps=r(K);oe=o(Ps,"SPAN",{});var Is=r(oe);_(ft.$$.fragment,Is),Is.forEach(e),Ps.forEach(e),ka=f(Ue),re=o(Ue,"SPAN",{});var Ds=r(re);za=h(Ds,"Composing transformations together"),Ds.forEach(e),Ue.forEach(e),Ie=f(t),Q=o(t,"P",{});var Ke=r(Q);Ea=h(Ke,"As applying mutilple transformations in chain is needed more often that not, "),Lt=o(Ke,"A",{href:!0});var Bs=r(Lt);Ma=h(Bs,"compose()"),Bs.forEach(e),Aa=h(Ke," is provided. It is an utility function that allows you to create a transformation by chaining multiple other transformations."),Ke.forEach(e),De=f(t),_(ct.$$.fragment,t),Be=f(t),R=o(t,"H2",{class:!0});var Qe=r(R);X=o(Qe,"A",{id:!0,class:!0,href:!0});var Cs=r(X);ne=o(Cs,"SPAN",{});var Ls=r(ne);_(ht.$$.fragment,Ls),Ls.forEach(e),Cs.forEach(e),qa=f(Qe),ie=o(Qe,"SPAN",{});var Ss=r(ie);Pa=h(Ss,"The Optimization API"),Ss.forEach(e),Qe.forEach(e),Ce=f(t),N=o(t,"H3",{class:!0});var Xe=r(N);Y=o(Xe,"A",{id:!0,class:!0,href:!0});var Rs=r(Y);le=o(Rs,"SPAN",{});var Ns=r(le);_(dt.$$.fragment,Ns),Ns.forEach(e),Rs.forEach(e),Ia=f(Xe),me=o(Xe,"SPAN",{});var Fs=r(me);Da=h(Fs,"Main classes and functions"),Fs.forEach(e),Xe.forEach(e),Le=f(t),k=o(t,"DIV",{class:!0});var I=r(k);_(ut.$$.fragment,I),Ba=f(I),pe=o(I,"P",{});var Gs=r(pe);Ca=h(Gs,"A torch.fx graph transformation."),Gs.forEach(e),La=f(I),gt=o(I,"P",{});var Ye=r(gt);Sa=h(Ye,"It  must implemement the "),St=o(Ye,"A",{href:!0});var Os=r(St);Ra=h(Os,"transform()"),Os.forEach(e),Na=h(Ye,` method, and be used as a
callable.`),Ye.forEach(e),Fa=f(I),Rt=o(I,"DIV",{class:!0});var Ws=r(Rt);_(_t.$$.fragment,Ws),Ws.forEach(e),Ga=f(I),Nt=o(I,"DIV",{class:!0});var Vs=r(Nt);_(vt.$$.fragment,Vs),Vs.forEach(e),I.forEach(e),Se=f(t),z=o(t,"DIV",{class:!0});var D=r(z);_($t.$$.fragment,D),Oa=f(D),fe=o(D,"P",{});var Hs=r(fe);Wa=h(Hs,"A torch.fx graph transformation that is reversible."),Hs.forEach(e),Va=f(D),F=o(D,"P",{});var Ht=r(F);Ha=h(Ht,"It must implemement the "),Ft=o(Ht,"A",{href:!0});var Js=r(Ft);Ja=h(Js,"transform()"),Js.forEach(e),Ua=h(Ht,` and
`),Gt=o(Ht,"A",{href:!0});var Us=r(Gt);Ka=h(Us,"reverse()"),Us.forEach(e),Qa=h(Ht," methods, and be used as a callable."),Ht.forEach(e),Xa=f(D),Ot=o(D,"DIV",{class:!0});var Ks=r(Ot);_(bt.$$.fragment,Ks),Ks.forEach(e),Ya=f(D),Wt=o(D,"DIV",{class:!0});var Qs=r(Wt);_(yt.$$.fragment,Qs),Qs.forEach(e),D.forEach(e),Re=f(t),M=o(t,"DIV",{class:!0});var Jt=r(M);_(xt.$$.fragment,Jt),Za=f(Jt),ce=o(Jt,"P",{});var Xs=r(ce);ts=h(Xs,"Composes a list of transformations together."),Xs.forEach(e),es=f(Jt),_(Z.$$.fragment,Jt),Jt.forEach(e),Ne=f(t),G=o(t,"H3",{class:!0});var Ze=r(G);tt=o(Ze,"A",{id:!0,class:!0,href:!0});var Ys=r(tt);he=o(Ys,"SPAN",{});var Zs=r(he);_(wt.$$.fragment,Zs),Zs.forEach(e),Ys.forEach(e),as=f(Ze),de=o(Ze,"SPAN",{});var to=r(de);ss=h(to,"Transformations"),to.forEach(e),Ze.forEach(e),Fe=f(t),A=o(t,"DIV",{class:!0});var Ut=r(A);_(jt.$$.fragment,Ut),os=f(Ut),ue=o(Ut,"P",{});var eo=r(ue);rs=h(eo,"Transformation that merges linear layers that take the same input into one big linear layer."),eo.forEach(e),ns=f(Ut),_(et.$$.fragment,Ut),Ut.forEach(e),Ge=f(t),q=o(t,"DIV",{class:!0});var Kt=r(q);_(Tt.$$.fragment,Kt),is=f(Kt),ge=o(Kt,"P",{});var ao=r(ge);ls=h(ao,`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.`),ao.forEach(e),ms=f(Kt),_(at.$$.fragment,Kt),Kt.forEach(e),this.h()},h(){l(u,"name","hf:doc:metadata"),l(u,"content",JSON.stringify(co)),l(d,"id","optimization"),l(d,"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(d,"href","#optimization"),l(x,"class","relative group"),l(H,"id","the-transformation-guide"),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","#the-transformation-guide"),l(B,"class","relative group"),l(J,"id","write-a-nonreversible-transformation"),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","#write-a-nonreversible-transformation"),l(C,"class","relative group"),l(Mt,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.Transformation"),l(At,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(U,"id","write-a-reversible-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-reversible-transformation"),l(L,"class","relative group"),l(It,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.ReversibleTransformation"),l(Dt,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(Bt,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.ReversibleTransformation.reverse"),l(K,"id","composing-transformations-together"),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","#composing-transformations-together"),l(S,"class","relative group"),l(Lt,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.compose"),l(X,"id","the-optimization-api"),l(X,"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(X,"href","#the-optimization-api"),l(R,"class","relative group"),l(Y,"id","optimum.fx.optimization.Transformation"),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","#optimum.fx.optimization.Transformation"),l(N,"class","relative group"),l(St,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(Rt,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Nt,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(k,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Ft,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.Transformation.transform"),l(Gt,"href","/docs/optimum/pr_181/en/fx/optimization#optimum.fx.optimization.ReversibleTransformation.reverse"),l(Ot,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),l(Wt,"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(M,"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,"id","optimum.fx.optimization.MergeLinears"),l(tt,"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(tt,"href","#optimum.fx.optimization.MergeLinears"),l(G,"class","relative group"),l(A,"class","docstring border-l-2 border-t-2 pl-4 pt-3.5 border-gray-100 rounded-tl-xl mb-6 mt-8"),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")},m(t,n){a(document.head,u),m(t,T,n),m(t,x,n),a(x,d),a(d,j),v(i,j,null),a(x,w),a(x,Qt),a(Qt,ta),m(t,$e,n),m(t,V,n),a(V,ea),a(V,Xt),a(Xt,aa),a(V,sa),m(t,be,n),m(t,B,n),a(B,H),a(H,Yt),v(rt,Yt,null),a(B,oa),a(B,Zt),a(Zt,ra),m(t,ye,n),m(t,Et,n),a(Et,na),m(t,xe,n),m(t,C,n),a(C,J),a(J,te),v(nt,te,null),a(C,ia),a(C,ee),a(ee,la),m(t,we,n),m(t,P,n),a(P,ma),a(P,Mt),a(Mt,pa),a(P,fa),a(P,At),a(At,ca),a(P,ha),m(t,je,n),m(t,qt,n),a(qt,da),m(t,Te,n),v(it,t,n),m(t,ke,n),m(t,Pt,n),a(Pt,ua),m(t,ze,n),v(lt,t,n),m(t,Ee,n),m(t,L,n),a(L,U),a(U,ae),v(mt,ae,null),a(L,ga),a(L,se),a(se,_a),m(t,Me,n),m(t,E,n),a(E,va),a(E,It),a(It,$a),a(E,ba),a(E,Dt),a(Dt,ya),a(E,xa),a(E,Bt),a(Bt,wa),a(E,ja),m(t,Ae,n),m(t,Ct,n),a(Ct,Ta),m(t,qe,n),v(pt,t,n),m(t,Pe,n),m(t,S,n),a(S,K),a(K,oe),v(ft,oe,null),a(S,ka),a(S,re),a(re,za),m(t,Ie,n),m(t,Q,n),a(Q,Ea),a(Q,Lt),a(Lt,Ma),a(Q,Aa),m(t,De,n),v(ct,t,n),m(t,Be,n),m(t,R,n),a(R,X),a(X,ne),v(ht,ne,null),a(R,qa),a(R,ie),a(ie,Pa),m(t,Ce,n),m(t,N,n),a(N,Y),a(Y,le),v(dt,le,null),a(N,Ia),a(N,me),a(me,Da),m(t,Le,n),m(t,k,n),v(ut,k,null),a(k,Ba),a(k,pe),a(pe,Ca),a(k,La),a(k,gt),a(gt,Sa),a(gt,St),a(St,Ra),a(gt,Na),a(k,Fa),a(k,Rt),v(_t,Rt,null),a(k,Ga),a(k,Nt),v(vt,Nt,null),m(t,Se,n),m(t,z,n),v($t,z,null),a(z,Oa),a(z,fe),a(fe,Wa),a(z,Va),a(z,F),a(F,Ha),a(F,Ft),a(Ft,Ja),a(F,Ua),a(F,Gt),a(Gt,Ka),a(F,Qa),a(z,Xa),a(z,Ot),v(bt,Ot,null),a(z,Ya),a(z,Wt),v(yt,Wt,null),m(t,Re,n),m(t,M,n),v(xt,M,null),a(M,Za),a(M,ce),a(ce,ts),a(M,es),v(Z,M,null),m(t,Ne,n),m(t,G,n),a(G,tt),a(tt,he),v(wt,he,null),a(G,as),a(G,de),a(de,ss),m(t,Fe,n),m(t,A,n),v(jt,A,null),a(A,os),a(A,ue),a(ue,rs),a(A,ns),v(et,A,null),m(t,Ge,n),m(t,q,n),v(Tt,q,null),a(q,is),a(q,ge),a(ge,ls),a(q,ms),v(at,q,null),Oe=!0},p(t,[n]){const kt={};n&2&&(kt.$$scope={dirty:n,ctx:t}),Z.$set(kt);const _e={};n&2&&(_e.$$scope={dirty:n,ctx:t}),et.$set(_e);const ve={};n&2&&(ve.$$scope={dirty:n,ctx:t}),at.$set(ve)},i(t){Oe||($(i.$$.fragment,t),$(rt.$$.fragment,t),$(nt.$$.fragment,t),$(it.$$.fragment,t),$(lt.$$.fragment,t),$(mt.$$.fragment,t),$(pt.$$.fragment,t),$(ft.$$.fragment,t),$(ct.$$.fragment,t),$(ht.$$.fragment,t),$(dt.$$.fragment,t),$(ut.$$.fragment,t),$(_t.$$.fragment,t),$(vt.$$.fragment,t),$($t.$$.fragment,t),$(bt.$$.fragment,t),$(yt.$$.fragment,t),$(xt.$$.fragment,t),$(Z.$$.fragment,t),$(wt.$$.fragment,t),$(jt.$$.fragment,t),$(et.$$.fragment,t),$(Tt.$$.fragment,t),$(at.$$.fragment,t),Oe=!0)},o(t){b(i.$$.fragment,t),b(rt.$$.fragment,t),b(nt.$$.fragment,t),b(it.$$.fragment,t),b(lt.$$.fragment,t),b(mt.$$.fragment,t),b(pt.$$.fragment,t),b(ft.$$.fragment,t),b(ct.$$.fragment,t),b(ht.$$.fragment,t),b(dt.$$.fragment,t),b(ut.$$.fragment,t),b(_t.$$.fragment,t),b(vt.$$.fragment,t),b($t.$$.fragment,t),b(bt.$$.fragment,t),b(yt.$$.fragment,t),b(xt.$$.fragment,t),b(Z.$$.fragment,t),b(wt.$$.fragment,t),b(jt.$$.fragment,t),b(et.$$.fragment,t),b(Tt.$$.fragment,t),b(at.$$.fragment,t),Oe=!1},d(t){e(u),t&&e(T),t&&e(x),y(i),t&&e($e),t&&e(V),t&&e(be),t&&e(B),y(rt),t&&e(ye),t&&e(Et),t&&e(xe),t&&e(C),y(nt),t&&e(we),t&&e(P),t&&e(je),t&&e(qt),t&&e(Te),y(it,t),t&&e(ke),t&&e(Pt),t&&e(ze),y(lt,t),t&&e(Ee),t&&e(L),y(mt),t&&e(Me),t&&e(E),t&&e(Ae),t&&e(Ct),t&&e(qe),y(pt,t),t&&e(Pe),t&&e(S),y(ft),t&&e(Ie),t&&e(Q),t&&e(De),y(ct,t),t&&e(Be),t&&e(R),y(ht),t&&e(Ce),t&&e(N),y(dt),t&&e(Le),t&&e(k),y(ut),y(_t),y(vt),t&&e(Se),t&&e(z),y($t),y(bt),y(yt),t&&e(Re),t&&e(M),y(xt),y(Z),t&&e(Ne),t&&e(G),y(wt),t&&e(Fe),t&&e(A),y(jt),y(et),t&&e(Ge),t&&e(q),y(Tt),y(at)}}}const co={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 ho(W){return io(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class bo extends so{constructor(u){super();oo(this,u,ho,fo,ro,{})}}export{bo as default,co as metadata};
