longpipe 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/index.cjs +92 -92
- package/dist/index.d.cts +17 -5
- package/dist/index.d.ts +17 -5
- package/dist/index.js +92 -92
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var w=[{model:"xs",dtype:"f16",resolution:{w:384,h:216},skipFrames:2},{model:"small",dtype:"f16",resolution:{w:384,h:216},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:512,h:288},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:640,h:360},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:1280,h:720},skipFrames:0}];var le=false;function be(a){le=a;}function x(a){let t=`[longpipe/${a}]`,e=((...r)=>{le&&console.log(t,...r);});return e.warn=(...r)=>{le&&console.warn(t,...r);},e}var P=x("adaptive"),Mt=2e3,Dt=1e4,Rt=30,Ht=20,Lt=5e3,Vt=.3,Nt=15e3,G=class{constructor(t){this.opts=t;this.currentPresetIdx=w.findIndex(e=>e.model===t.initialModel),this.lastSwapAt=performance.now();}opts;timer=null;currentPresetIdx;lastSwapAt=0;overshootStart=0;headroomStart=0;start(){P(`started; backend=${this.opts.backendKind} initial=${this.opts.initialModel} idx=${this.currentPresetIdx}`),this.timer=setInterval(()=>{this.tick().catch(t=>P("tick failed:",t));},Mt);}stop(){this.timer&&clearInterval(this.timer),this.timer=null;}async tick(){if(typeof document<"u"&&document.hidden)return;let t=performance.now();if(t-this.lastSwapAt<Dt)return;let e=await this.opts.getStats();if(e.fps<Ht?(this.overshootStart===0&&(this.overshootStart=t),t-this.overshootStart>=Lt&&this.tryDowngrade(e.fps)):this.overshootStart=0,this.opts.backendKind==="webgpu"&&e.modelMs>0){let r=1e3/Rt*Vt;e.modelMs<r?(this.headroomStart===0&&(this.headroomStart=t),t-this.headroomStart>=Nt&&this.tryUpgrade(e.modelMs,r)):this.headroomStart=0;}}tryDowngrade(t){if(this.currentPresetIdx<=0)return;let e=this.currentPresetIdx-1;P(`downgrade ${w[this.currentPresetIdx].model} \u2192 ${w[e].model} (fps=${t})`),this.swap(e);}tryUpgrade(t,e){if(this.currentPresetIdx>=w.length-1)return;let r=this.currentPresetIdx+1;P(`upgrade ${w[this.currentPresetIdx].model} \u2192 ${w[r].model} (modelMs=${t.toFixed(1)} < ${e.toFixed(1)})`),this.swap(r);}async swap(t){let e=w[t];this.lastSwapAt=performance.now(),this.overshootStart=0,this.headroomStart=0;try{let r=this.opts.buildWeightsUrl(this.opts.weightsBaseUrl,e.model),n=await fetch(r);if(!n.ok)throw new Error(`weights fetch failed: ${n.status} ${r}`);let i=await n.arrayBuffer();await this.opts.swapPreset(e.model,i),this.currentPresetIdx=t,P(`swap to ${e.model} done`);}catch(r){P("swap failed:",r),this.opts.onError?.({message:`adaptive preset swap failed: ${r.message??String(r)}`,source:"adaptive",recoverable:true,cause:r});}}};async function ve(a){let t,e=false;if(a instanceof HTMLVideoElement){if(t=a.currentSrc||a.src,!t)throw new Error("background video: HTMLVideoElement has no src")}else if(a instanceof Blob)t=URL.createObjectURL(a),e=true;else if(typeof a=="string")t=a;else throw new Error("background video: unsupported input shape");let r=document.createElement("video");r.crossOrigin="anonymous",r.muted=true,r.loop=true,r.playsInline=true,r.src=t,await new Promise((l,f)=>{r.addEventListener("loadeddata",()=>l(),{once:true}),r.addEventListener("error",()=>f(new Error(`background video: failed to load ${t}`)),{once:true});});try{await r.play();}catch(l){throw new Error(`background video: play() rejected \u2014 ${l.message}`)}let n=new MessageChannel,i=n.port1,o=n.port2,u=false,s=r.requestVideoFrameCallback?.bind(r);if(s){let l=(f,h)=>{if(!u){try{let v=new VideoFrame(r,{timestamp:h.mediaTime*1e6});i.postMessage({frame:v},[v]);}catch{}s(l);}};s(l);}else {let l=()=>{if(!u){try{let f=new VideoFrame(r,{timestamp:performance.now()*1e3});i.postMessage({frame:f},[f]);}catch{}requestAnimationFrame(l);}};requestAnimationFrame(l);}return {port:o,transferList:[o],cleanup:()=>{u=true,i.close(),r.pause(),r.removeAttribute("src"),r.load(),e&&URL.revokeObjectURL(t);}}}var ce=4,de=8,xe=16;async function fe(a){if(typeof a=="string")return a==="none"?{background:{kind:"none"}}:a==="blur"?{background:{kind:"blur",sigma:de}}:{background:{kind:"image",bitmap:await ye(a)}};if(a instanceof ImageBitmap)return {background:{kind:"image",bitmap:a}};if(typeof HTMLImageElement<"u"&&a instanceof HTMLImageElement)return {background:{kind:"image",bitmap:await createImageBitmap(a)}};if(typeof HTMLVideoElement<"u"&&a instanceof HTMLVideoElement)return await we(a);let t=a;if(t.color!==void 0)return {background:{kind:"color",rgb:$t(t.color)}};if(t.blur!==void 0)return {background:{kind:"blur",sigma:jt(t.blur)}};if(t.image!==void 0)return {background:{kind:"image",bitmap:await qt(t.image)}};if(t.video!==void 0)return await we(t.video);throw new Error(`background: unrecognized input shape \u2014 ${k(a)}`)}async function we(a){let t;if(typeof a=="string")t=a;else if(typeof HTMLVideoElement<"u"&&a instanceof HTMLVideoElement)t=a;else if(a&&typeof a=="object"&&"data"in a&&"type"in a)t=a.data instanceof Blob?a.data:new Blob([a.data],{type:a.type});else throw new Error(`background.video: unrecognized shape \u2014 ${k(a)}`);let e=await ve(t);return {background:{kind:"video",port:e.port},transferList:e.transferList,cleanup:e.cleanup}}function $t(a){if(typeof a=="string"){let t=a.trim().replace(/^#/,"");if(/^[0-9a-fA-F]{6}$/.test(t))return [parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255];if(/^[0-9a-fA-F]{3}$/.test(t))return [parseInt(t[0]+t[0],16)/255,parseInt(t[1]+t[1],16)/255,parseInt(t[2]+t[2],16)/255];throw new Error(`background.color: hex must be #rgb or #rrggbb, got ${k(a)}`)}if(!Array.isArray(a)||a.length!==3||!a.every(t=>typeof t=="number"&&Number.isFinite(t)&&t>=0&&t<=1))throw new Error(`background.color: expected hex string or [r, g, b] floats in [0, 1], got ${k(a)}`);return [a[0],a[1],a[2]]}function jt(a){if(a===true)return de;if("sigma"in a){if(typeof a.sigma!="number"||!Number.isFinite(a.sigma)||a.sigma<0)throw new Error(`background.blur.sigma must be a non-negative number, got ${a.sigma}`);return a.sigma}if("strength"in a){let t=a.strength;if(typeof t=="number"){let e=Math.max(0,Math.min(1,t));return ce+(xe-ce)*e}if(t==="low")return ce;if(t==="medium")return de;if(t==="high")return xe;throw new Error(`background.blur.strength must be 'low' | 'medium' | 'high' | number, got ${k(t)}`)}throw new Error(`background.blur: must be true, { strength }, or { sigma } \u2014 got ${k(a)}`)}async function qt(a){if(a instanceof ImageBitmap)return a;if(typeof HTMLImageElement<"u"&&a instanceof HTMLImageElement)return createImageBitmap(a);if(typeof a=="string")return ye(a);if(a&&typeof a=="object"&&"data"in a&&"type"in a){let t=a.data instanceof Blob?a.data:new Blob([a.data],{type:a.type});return createImageBitmap(t)}throw new Error(`background.image: unrecognized shape \u2014 ${k(a)}`)}async function ye(a){let t=await fetch(a);if(!t.ok)throw new Error(`background: failed to load image from ${a} (HTTP ${t.status})`);let e=await t.blob();return createImageBitmap(e)}function k(a){return a===null?"null":typeof a!="object"?typeof a+"("+String(a)+")":`${a.constructor?.name??"Object"} ${JSON.stringify(a).slice(0,80)}`}function ke(){return {input:"MediaStreamTrackProcessor"in self?"mstp":"rvfc-postmessage",output:"MediaStreamTrackGenerator"in self?"mstg":Xt()?"transfer-capture":"bitmap-shuttle"}}var E=null;function Xt(){return E!==null||(E=!/Firefox/.test(navigator.userAgent)),E}function Ce(a,t,e){let r=[a];return e==="passthrough"&&r.push(...t.getAudioTracks()),new MediaStream(r)}var F=x("worker_controller"),A=class{worker;listeners=new Map;persistentEvents=new Set;constructor(t){this.worker=t,this.worker.addEventListener("message",this.handleMessage.bind(this)),F("constructed; message listener attached");}handleMessage(t){let{request_id:e,res:r}=t.data,n=this.listeners.get(e);F("msg received: request_id=",e,"handler?",!!n,"persistent?",this.persistentEvents.has(e)),n&&(n(r),this.persistentEvents.has(e)||this.listeners.delete(e));}addPersistentListener(t,e){this.persistentEvents.add(t),this.listeners.set(t,e),F("addPersistentListener:",t);}removePersistentListener(t){this.persistentEvents.delete(t),this.listeners.delete(t);}sendMessage(t,e,r=[]){let n=crypto.randomUUID();return F("sendMessage:",t,"request_id=",n,"transferables=",r.length),new Promise(i=>{this.listeners.set(n,u=>i(u));let o={cmd:t,data:e,request_id:n};this.worker.postMessage(o,r);})}terminate(){this.worker.terminate(),this.listeners.clear(),this.persistentEvents.clear();}};var Pe=x("input-postmessage/main");function Te(a){let t=document.createElement("video");t.srcObject=a,t.muted=true,t.autoplay=true,t.playsInline=true,t.play().catch(d=>{Pe.warn("video.play() rejected:",d);});let e=t.requestVideoFrameCallback?.bind(t);if(!e)throw new Error("setupPostMessageInput: requestVideoFrameCallback not supported on this browser");let r=new MessageChannel,n=r.port1,i=r.port2,o=false,u=(d,l)=>{if(!o){try{let f=new VideoFrame(t,{timestamp:l.mediaTime*1e6});n.postMessage({frame:f},[f]);}catch(f){Pe.warn("VideoFrame() failed; skipping frame:",f);}e(u);}};return e(u),{port:i,transferList:[i],cleanup:()=>{o=true,n.close(),t.srcObject=null,t.pause();}}}function Ue(a){let t=a.getVideoTracks();if(t.length===0)throw new Error("setupMstpInput: input MediaStream has no video tracks");let e=t[0],r=self.MediaStreamTrackProcessor;if(!r)throw new Error("setupMstpInput: MediaStreamTrackProcessor not supported on this browser");let i=new r({track:e}).readable;return {readable:i,transferList:[i],cleanup:()=>{i.cancel().catch(()=>{});}}}function Ie(a,t){switch(a){case "mstp":{let e=Ue(t);return {initFields:{inputReadable:e.readable},transferList:e.transferList,cleanup:e.cleanup}}case "rvfc-postmessage":{let e=Te(t);return {initFields:{inputPort:e.port},transferList:e.transferList,cleanup:e.cleanup}}}}var Kt=x("bitmap-shuttle/main"),Yt=30;function Be(a,t=Yt){let e=document.createElement("canvas");e.width=a.w,e.height=a.h;let r=e.getContext("bitmaprenderer");if(!r)throw new Error("setupBitmapShuttleOutput: bitmaprenderer context not available");let i=e.captureStream(t).getVideoTracks();if(i.length===0)throw new Error("setupBitmapShuttleOutput: captureStream produced no video tracks");let o=i[0],u=new MessageChannel,s=u.port1,d=u.port2,l=false,f=null,h=()=>{},v=3,I=0;return s.onmessage=B=>{if(l){if(I++,I<v){B.data.bmp.close();return}h();}try{r.transferFromImageBitmap(B.data.bmp);}catch(b){Kt.warn("transferFromImageBitmap failed:",b);}},s.start(),{videoTrack:o,port:d,transferList:[d],startPassthrough:B=>{if(l)return;l=true;let b=document.createElement("video");b.srcObject=B,b.muted=true,b.playsInline=true,b.play().catch(()=>{}),f=b;let W="requestVideoFrameCallback"in b?C=>{b.requestVideoFrameCallback(C);}:C=>{requestAnimationFrame(C);},S=()=>{if(l){if(b.videoWidth===0){W(S);return}createImageBitmap(b,{resizeWidth:e.width,resizeHeight:e.height,resizeQuality:"medium"}).then(C=>{if(!l){C.close();return}try{r.transferFromImageBitmap(C);}catch{}W(S);}).catch(()=>{W(S);});}};W(S),h=()=>{l=false,f&&(f.srcObject=null,f.pause(),f=null);};},cleanup:()=>{h(),s.onmessage=null,s.close(),o.stop();}}}function We(){let a=self.MediaStreamTrackGenerator;if(!a)throw new Error("setupMstgOutput: MediaStreamTrackGenerator not supported on this browser");let t=new a({kind:"video"}),e=t.writable;return {videoTrack:t,writable:e,transferList:[e],cleanup:()=>{e.abort().catch(()=>{}),t.stop();}}}function Se(a,t=30){let e=document.createElement("canvas");e.width=a.w,e.height=a.h;let n=e.captureStream(t).getVideoTracks();if(n.length===0)throw new Error("setupTransferCaptureOutput: captureStream produced no video tracks");let i=n[0],o=e.transferControlToOffscreen();return {videoTrack:i,canvas:o,transferList:[o],cleanup:()=>{i.stop();}}}function Ge(a,t){switch(a){case "mstg":{let e=We();return {videoTrack:e.videoTrack,initFields:{outputWritable:e.writable},transferList:e.transferList,cleanup:e.cleanup}}case "transfer-capture":{let e=Se(t);return {videoTrack:e.videoTrack,initFields:{outputCanvas:e.canvas},transferList:e.transferList,cleanup:e.cleanup}}case "bitmap-shuttle":{let e=Be(t);return {videoTrack:e.videoTrack,initFields:{outputPort:e.port},transferList:e.transferList,startPassthrough:e.startPassthrough,cleanup:e.cleanup}}}}var he=`var ao=Object.defineProperty;var no=(s,t,r)=>t in s?ao(s,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[t]=r;var i=(s,t,r)=>no(s,typeof t!="symbol"?t+"":t,r);var it=!1;function lt(s){it=s}function U(s){let t=\`[longpipe/\${s}]\`,r=((...e)=>{it&&console.log(t,...e)});return r.warn=(...e)=>{it&&console.warn(t,...e)},r}var at=[{model:"xs",dtype:"f16",resolution:{w:384,h:216},skipFrames:2},{model:"small",dtype:"f16",resolution:{w:384,h:216},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:512,h:288},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:640,h:360},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:1280,h:720},skipFrames:0}],so={fast:0,balanced:2,quality:4};function V(s){return s==="auto"?null:at[so[s]]}var N=class{constructor(t,r,e,o){i(this,"op");this.op=t.ops.BilinearUpsample(r,{outH:e,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var $=class{constructor(t,r,e,o){i(this,"op");this.op=t.ops.BicubicUpsample(r,{outH:e,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var X=class{constructor(t,r,e,o){i(this,"presenter");this.presenter=t.presenters.CompositeSolid(r,e,o)}run(){this.presenter.run()}};var j=class{constructor(t,r,e,o){i(this,"presenter");this.presenter=t.presenters.CompositeImage(r,e,o)}run(){this.presenter.run()}};var q=class{constructor(t,r,e){i(this,"downs",[]);i(this,"ups",[]);let o=uo(e),a=r;for(let n=0;n<o;n++){let u=t.ops.BilinearUpsample(a,{outH:Math.max(1,Math.floor(a.h/2)),outW:Math.max(1,Math.floor(a.w/2))});this.downs.push(u),a=u.output}for(let n=o-1;n>=1;n--){let u=this.downs[n-1].output,p=t.ops.BilinearUpsample(a,{outH:u.h,outW:u.w});this.ups.push(p),a=p.output}}get output(){return this.ups.length>0?this.ups[this.ups.length-1].output:this.downs[0].output}run(){for(let t of this.downs)t.run();for(let t of this.ups)t.run()}};function uo(s){let t=Math.max(1,3*s);return Math.max(2,Math.min(6,Math.round(Math.log2(t))))}var K=class{constructor(t,r,e,o){i(this,"blur");i(this,"presenter");this.blur=new q(t,r,o),this.presenter=t.presenters.CompositeImageBilinear(r,e,this.blur.output)}run(){this.blur.run(),this.presenter.run()}};var Y=class{constructor(t){i(this,"backend",t);i(this,"displayInput");i(this,"image");i(this,"passthroughCompositor");i(this,"network",null);i(this,"networkInput",null);i(this,"upscaler",null);i(this,"compositor",null);i(this,"upscalerMode","bilinear");i(this,"bgConfig",{mode:"solid",color:[0,0,0]});let r=t.canvas;this.displayInput=t.ops.Input(r.height,r.width),this.image=this.displayInput.output,this.passthroughCompositor=t.presenters.CompositePassthrough(this.image)}attachNetwork(t,r,e){this.network=t,this.networkInput=r,this.upscalerMode=e.upscaler,this.bgConfig=e.background,this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()}hasNetwork(){return this.network!==null}setSource(t){this.networkInput?.setSource(t),this.displayInput.setSource(t)}setUpscaler(t){t!==this.upscalerMode&&(this.upscalerMode=t,this.network&&(this.upscaler=this.makeUpscaler(),this.compositor=this.makeCompositor()))}setBackground(t){this.bgConfig=t,this.network&&(this.compositor=this.makeCompositor())}run(){this.runModel(),this.runDisplay()}runDisplay(){if(!this.compositor)throw new Error("RenderOp.runDisplay called before attachNetwork");this.displayInput.run(),this.compositor.run()}runPassthrough(){this.displayInput.run(),this.passthroughCompositor.run()}runModel(){if(!this.network||!this.networkInput||!this.upscaler)throw new Error("RenderOp.runModel called before attachNetwork");this.networkInput.run(),this.network.run(),this.upscaler.run()}makeUpscaler(){if(!this.network)throw new Error("makeUpscaler called with no network");let{backend:t,network:r,image:e}=this;return this.upscalerMode==="bicubic"?new $(t,r.output,e.h,e.w):new N(t,r.output,e.h,e.w)}makeCompositor(){if(!this.upscaler)throw new Error("makeCompositor called before upscaler exists");let{backend:t,image:r,upscaler:e,bgConfig:o}=this;switch(o.mode){case"solid":return new X(t,r,e.output,o.color);case"image":return new j(t,r,e.output,o.image);case"blur":return new K(t,r,e.output,o.sigma)}}};var po=s=>typeof s=="object"&&s!==null&&typeof s.offset=="number"&&typeof s.length=="number";function ct(s){if(s.byteLength<4)throw new Error("weights buffer too small");let t=new DataView(s,0,4).getUint32(0,!0),r=4+t;if(s.byteLength<r)throw new Error("weights buffer truncated (header)");let e=new Uint8Array(s,4,t),o=JSON.parse(new TextDecoder().decode(e)),a=o.__dtype__??"f32",n=a==="f16"?2:4;if(r%n!==0)throw new Error(\`payload not \${n}-byte aligned (header=\${t})\`);let u=(s.byteLength-r)/n,p=l=>{if(po(l)){let{offset:c,length:m}=l;if(c+m>u)throw new Error(\`array ref out of range: offset=\${c} length=\${m}\`);let _=r+c*n;return a==="f16"?new Uint16Array(s,_,m):new Float32Array(s,_,m)}if(Array.isArray(l))return l.map(p);if(typeof l=="object"&&l!==null){let c={};for(let m of Object.keys(l))m!=="__dtype__"&&(c[m]=p(l[m]));return c}return l};return p(o)}var R=class{constructor(t,r,e,o){i(this,"inputs");i(this,"output");i(this,"gatesOp");i(this,"candOp");this.inputs=[r,e],this.gatesOp=t.ops.GatesFused(r,e,{weights:o.gates,bias:o.gatesBias}),this.candOp=t.ops.CandUpdateFused(r,e,this.gatesOp.output,{weights:o.cand,bias:o.candBias},o.gamma),this.output=this.candOp.output}run(){this.gatesOp.run(),this.candOp.run()}};function dt(s,t,r,e){let o=e.variant,a=o==="E"||o==="D",n=o==="D",u=t.h,p=t.w,l=[],c=null,m=null,_=0,g=0,v;if(a)if(n){if(!r.down2)throw new Error("variant D requires w.down2");_=Math.round(u/1.25),g=Math.round(p/1.25);let y=s.ops.Conv2d(t,r.down1,{outChannels:e.cHigh,kernel:3,stride:1,padding:1,activation:"relu"});l.push(y),m=y.output;let T=s.ops.BilinearUpsample(m,{outH:_,outW:g});l.push(T),c=T.output;let W=s.ops.DownAdapter(c,r.down2,r.adapter,{stride:2});l.push(W),v=W.output}else{if(!r.down2)throw new Error("variant E requires w.down2");let y=s.ops.Conv2d(t,r.down1,{outChannels:e.cHigh,kernel:3,stride:2,padding:1,activation:"relu"});l.push(y),c=y.output,_=c.h,g=c.w;let T=s.ops.DownAdapter(c,r.down2,r.adapter,{stride:2});l.push(T),v=T.output}else{let y=o==="A"?2:3,T=s.ops.DownAdapter(t,r.down1,r.adapter,{stride:y});l.push(T),v=T.output}return{steps:l,adapted:v,d1:c,dFull:m,midH:_,midW:g}}function mt(s,t,r,e,o,a,n,u,p,l){let c=p.variant,m=c==="E"||c==="D",_=c==="D",g=[],v=s.ops.ConvExpand(r,u.expandFeat);g.push(v);let y=v.output,T=null;if(l&&p.gruAtBase){let P=new R(s,y,l.hPrev,l.weights);g.push(P),y=P.output,T=P.output}let W;if(m){if(!u.up1Combine)throw new Error("two-stage variant requires w.up1Combine");let P=s.ops.BilinearUpsample(y,{outH:a,outW:n});g.push(P);let ut=s.ops.CatConv6to2(P.output,e,u.up1Combine);g.push(ut);let pt=s.ops.BilinearUpsample(ut.output,{outH:t.h,outW:t.w});g.push(pt),W=pt.output}else{let P=s.ops.BilinearUpsample(y,{outH:t.h,outW:t.w});g.push(P),W=P.output}if(l&&!p.gruAtBase){let P=new R(s,W,l.hPrev,l.weights);g.push(P),W=P.output,T=P.output}let z=_?s.ops.UpFinalSkip(W,o,t,u.upCombine):s.ops.UpFinal(W,t,u.upCombine);return g.push(z),{steps:g,alpha:z.output,hiddenState:T}}var Q=class{constructor(t,r,e,o,a,n,u){i(this,"inputs");i(this,"output");i(this,"hiddenState");i(this,"steps");this.inputs=[r];let p=dt(t,r,o,a),l=new n(t,p.adapted,e),c=t.ops.BilinearUpsample(l.featLowRes,{outH:p.adapted.h,outW:p.adapted.w}),m=mt(t,r,c.output,p.d1,p.dFull,p.midH,p.midW,o,a,u);this.steps=[...p.steps,l,c,...m.steps],this.output=m.alpha,this.hiddenState=m.hiddenState}run(){for(let t of this.steps)t.run()}};var S=class{constructor(t,r,e,o){i(this,"inputs");i(this,"output");i(this,"dwOp");i(this,"pwOp");this.inputs=[r],this.dwOp=t.ops.DepthwiseConv2d(r,e.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.pwOp=t.ops.Conv2d(this.dwOp.output,e.pw,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.pwOp.output}run(){this.dwOp.run(),this.pwOp.run()}};var x=class{constructor(t,r,e,o){i(this,"inputs");i(this,"output");i(this,"expandOp");i(this,"dwOp");i(this,"projOp");this.inputs=[r];let a=o.midChannels!==o.inChannels,n=o.stride===1&&o.inChannels===o.outChannels;this.expandOp=a?t.ops.Conv2d(r,e.expand,{outChannels:o.midChannels,kernel:1,stride:1,padding:0,activation:"relu6"}):null;let u=this.expandOp?this.expandOp.output:r;this.dwOp=t.ops.DepthwiseConv2d(u,e.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.projOp=n?t.ops.ProjResidual(this.dwOp.output,r,e.proj,{outChannels:o.outChannels}):t.ops.Conv2d(this.dwOp.output,e.proj,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.projOp.output}run(){this.expandOp?.run(),this.dwOp.run(),this.projOp.run()}};var G=class{constructor(t,r,e,o,a){i(this,"inputs");i(this,"output");i(this,"upOp");i(this,"concatConvOp");i(this,"conv2Op");this.inputs=[r,e],this.upOp=t.ops.BilinearUpsample(r,{outH:e.h,outW:e.w}),this.concatConvOp=t.ops.ConcatConv2d(this.upOp.output,e,o.conv1,{outChannels:a.outChannels}),this.conv2Op=t.ops.Conv2d(this.concatConvOp.output,o.conv2,{outChannels:a.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.output=this.conv2Op.output}run(){this.upOp.run(),this.concatConvOp.run(),this.conv2Op.run()}};var J=class{constructor(t,r,e){i(this,"output");i(this,"featLowRes");i(this,"stem");i(this,"s0");i(this,"s1b0");i(this,"s1b1");i(this,"s2b0");i(this,"s2b1");i(this,"s3b0");i(this,"s3b1");i(this,"s3b2");i(this,"s4b0");i(this,"s4b1");i(this,"s4b2");i(this,"bottleneck");i(this,"dec0");i(this,"dec1");i(this,"finalUp");i(this,"outConv");i(this,"alpha");this.stem=t.ops.Conv2d(r,e.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new S(t,this.stem.output,e.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new x(t,this.s0.output,e.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new x(t,this.s1b0.output,e.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new x(t,this.s1b1.output,e.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new x(t,this.s2b0.output,e.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new x(t,this.s2b1.output,e.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new x(t,this.s3b0.output,e.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new x(t,this.s3b1.output,e.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new x(t,this.s3b2.output,e.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new x(t,this.s4b0.output,e.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new x(t,this.s4b1.output,e.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.bottleneck=t.ops.Conv2d(this.s4b2.output,e.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new G(t,this.bottleneck.output,this.s2b1.output,e.decoder.blocks[0],{outChannels:64}),this.dec1=new G(t,this.dec0.output,this.s1b1.output,e.decoder.blocks[1],{outChannels:32}),this.finalUp=t.ops.UpsampleConv1x1(this.dec1.output,e.decoder.finalUpsample,{outH:this.dec1.output.h*2,outW:this.dec1.output.w*2,outChannels:32,activation:"relu6"}),this.featLowRes=this.finalUp.output,this.outConv=t.ops.Conv2d(this.finalUp.output,e.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=t.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var Z=class{constructor(t,r,e){i(this,"output");i(this,"featLowRes");i(this,"stem");i(this,"s0");i(this,"s1b0");i(this,"s1b1");i(this,"s2b0");i(this,"s2b1");i(this,"s3b0");i(this,"s3b1");i(this,"s3b2");i(this,"s4b0");i(this,"s4b1");i(this,"s4b2");i(this,"s5b0");i(this,"s5b1");i(this,"s5b2");i(this,"s5b3");i(this,"s6b0");i(this,"bottleneck");i(this,"dec0");i(this,"dec1");i(this,"dec2");i(this,"finalUp");i(this,"outConv");i(this,"alpha");this.stem=t.ops.Conv2d(r,e.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new S(t,this.stem.output,e.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new x(t,this.s0.output,e.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new x(t,this.s1b0.output,e.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new x(t,this.s1b1.output,e.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new x(t,this.s2b0.output,e.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new x(t,this.s2b1.output,e.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new x(t,this.s3b0.output,e.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new x(t,this.s3b1.output,e.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new x(t,this.s3b2.output,e.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new x(t,this.s4b0.output,e.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new x(t,this.s4b1.output,e.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new x(t,this.s4b2.output,e.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new x(t,this.s5b0.output,e.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new x(t,this.s5b1.output,e.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new x(t,this.s5b2.output,e.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new x(t,this.s5b3.output,e.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=t.ops.Conv2d(this.s6b0.output,e.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new G(t,this.bottleneck.output,this.s4b2.output,e.decoder.blocks[0],{outChannels:64}),this.dec1=new G(t,this.dec0.output,this.s2b1.output,e.decoder.blocks[1],{outChannels:32}),this.dec2=new G(t,this.dec1.output,this.s1b1.output,e.decoder.blocks[2],{outChannels:16}),this.finalUp=t.ops.UpsampleConv1x1(this.dec2.output,e.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:16,activation:"relu6"}),this.featLowRes=this.finalUp.output,this.outConv=t.ops.Conv2d(this.finalUp.output,e.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=t.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var nt=[[{in:24,mid:144,out:32,k:3,s:2},{in:32,mid:192,out:32,k:3,s:1},{in:32,mid:192,out:32,k:3,s:1},{in:32,mid:192,out:32,k:3,s:1}],[{in:32,mid:192,out:56,k:5,s:2},{in:56,mid:336,out:56,k:5,s:1},{in:56,mid:336,out:56,k:5,s:1},{in:56,mid:336,out:56,k:5,s:1}],[{in:56,mid:336,out:112,k:3,s:2},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1}],[{in:112,mid:672,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1}],[{in:160,mid:960,out:272,k:5,s:2},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1}],[{in:272,mid:1632,out:448,k:3,s:1}]],ee=class{constructor(t,r,e){i(this,"output");i(this,"featLowRes");i(this,"stem");i(this,"s0");i(this,"stages");i(this,"bottleneck");i(this,"dec0");i(this,"dec1");i(this,"dec2");i(this,"finalUp");i(this,"outConv");i(this,"alpha");this.stem=t.ops.Conv2d(r,e.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new S(t,this.stem.output,e.encoder.s0,{outChannels:24,kernel:3,stride:1,padding:1});let o=[e.encoder.s1,e.encoder.s2,e.encoder.s3,e.encoder.s4,e.encoder.s5,e.encoder.s6];this.stages=[];let a=this.s0.output;for(let m=0;m<nt.length;m++){let _=[];for(let g=0;g<nt[m].length;g++){let v=nt[m][g],y=new x(t,a,o[m][g],{inChannels:v.in,midChannels:v.mid,outChannels:v.out,kernel:v.k,stride:v.s,padding:v.s===2?"same":(v.k-1)/2});_.push(y),a=y.output}this.stages.push(_)}let n=m=>this.stages[m][this.stages[m].length-1].output,u=n(0),p=n(1),l=n(3),c=n(5);this.bottleneck=t.ops.Conv2d(c,e.bottleneck,{outChannels:256,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new G(t,this.bottleneck.output,l,e.decoder.blocks[0],{outChannels:128}),this.dec1=new G(t,this.dec0.output,p,e.decoder.blocks[1],{outChannels:64}),this.dec2=new G(t,this.dec1.output,u,e.decoder.blocks[2],{outChannels:32}),this.finalUp=t.ops.UpsampleConv1x1(this.dec2.output,e.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:32,activation:"relu6"}),this.featLowRes=this.finalUp.output,this.outConv=t.ops.Conv2d(this.finalUp.output,e.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=t.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run();for(let t of this.stages)for(let r of t)r.run();this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var ft=J,ht=Z,lo=ee,E={xs:{base:ft,wrapper:{variant:"B",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:384,h:216},baseRes:{w:128,h:72}},small:{base:ft,wrapper:{variant:"A",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:384,h:216},baseRes:{w:192,h:108}},medium:{base:ht,wrapper:{variant:"A",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:512,h:288},baseRes:{w:256,h:144}},large:{base:ht,wrapper:{variant:"D",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:640,h:360},baseRes:{w:256,h:144}},xl:{base:lo,wrapper:{variant:"E",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:1280,h:720},baseRes:{w:320,h:180}}};var co=5,gt=1e3,te=class{constructor(t){i(this,"canvas");i(this,"backend");i(this,"backendKind");i(this,"topology");i(this,"preset",null);i(this,"enabled");i(this,"currentBackground");i(this,"modelTimingCounter",0);i(this,"renderOp");i(this,"tierModel",null);i(this,"hPrev",null);i(this,"bgImageInput",null);i(this,"bgVideoInput",null);i(this,"bgVideoPort",null);i(this,"skipCounter",0);i(this,"framesRenderedAt",[]);i(this,"modelRunSamples",[]);i(this,"displayRunSamples",[]);i(this,"skippedCount",0);this.backend=t.backend,this.backendKind=t.backendKind,this.canvas=t.canvas,this.enabled=t.enabled,this.currentBackground=t.background,this.topology=t.topology,this.renderOp=new Y(this.backend)}process(t){if(this.renderOp.setSource(t),!this.enabled||this.currentBackground.kind==="none"||!this.renderOp.hasNetwork()){this.renderOp.runPassthrough(),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt);return}if(this.shouldRunModel()){let e=performance.now();this.renderOp.runModel(),this.hPrev&&this.tierModel?.hiddenState&&this.backend.copyTensor(this.tierModel.hiddenState,this.hPrev),this.backendKind==="webgpu"&&this.modelTimingCounter%co===0&&this.backend.sync().then(()=>{this.modelRunSamples.push({ts:performance.now(),ms:performance.now()-e}),this.trimSamples(this.modelRunSamples)}).catch(()=>{}),this.modelTimingCounter++}else this.skippedCount++;let r=performance.now();this.renderOp.runDisplay(),this.displayRunSamples.push({ts:performance.now(),ms:performance.now()-r}),this.trimSamples(this.displayRunSamples),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt)}shouldRunModel(){return this.skipCounter===0?(this.skipCounter=this.preset?.skipFrames??0,!0):(this.skipCounter--,!1)}setBackground(t){this.currentBackground=t,this.renderOp.setBackground(this.translateBackground(t))}setEnabled(t){this.enabled=t}setPreset(t,r){let e=E[t.model];if(!e)throw new Error(\`renderer: no TIER_CONFIG entry for model '\${t.model}'\`);let o=ct(r),a=this.backend.ops.Input(e.canvasRes.h,e.canvasRes.w),n,u=null;if(e.hasGru){let l=e.wrapper.gruAtBase?e.baseRes:e.canvasRes;u=this.backend.tensor(l.h,l.w,4,new Float32Array(l.h*l.w*4)),n={weights:o.gru,hPrev:u}}let p=new Q(this.backend,a.output,o.base,o.wrapper,e.wrapper,e.base,n);this.renderOp.attachNetwork(p,a,{upscaler:"bilinear",background:this.translateBackground(this.currentBackground)}),this.tierModel=p,this.hPrev=u,this.preset=t,this.skipCounter=0}destroy(){this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),this.backend.destroy()}getStats(){let t=performance.now();return this.trimRecent(this.framesRenderedAt,t),this.trimSamplesAt(this.modelRunSamples,t),this.trimSamplesAt(this.displayRunSamples,t),{fps:this.framesRenderedAt.length,modelFps:this.modelRunSamples.length,modelMs:_t(this.modelRunSamples.map(r=>r.ms)),displayMs:_t(this.displayRunSamples.map(r=>r.ms)),skipped:this.skippedCount,preset:this.preset?.model??"boot",skipFrames:this.preset?.skipFrames??0,enabled:this.enabled,inputPath:this.topology.input,outputPath:this.topology.output}}translateBackground(t){switch(t.kind!=="video"&&this.bgVideoPort&&(this.bgVideoPort.close(),this.bgVideoPort=null),t.kind){case"none":return{mode:"solid",color:[0,0,0]};case"color":return{mode:"solid",color:t.rgb};case"blur":return{mode:"blur",sigma:t.sigma};case"image":return this.bgImageInput||(this.bgImageInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgImageInput.setSource(t.bitmap),this.bgImageInput.run(),{mode:"image",image:this.bgImageInput.output};case"video":{this.bgVideoInput||(this.bgVideoInput=this.backend.ops.Input(this.canvas.height,this.canvas.width)),this.bgVideoPort&&this.bgVideoPort.close(),this.bgVideoPort=t.port;let r=this.bgVideoInput;return t.port.onmessage=e=>{let o=e.data.frame;try{r.setSource(o),r.run()}finally{o.close()}},t.port.start?.(),{mode:"image",image:this.bgVideoInput.output}}}}trim(t){t.length>240&&t.splice(0,t.length-240)}trimSamples(t){t.length>240&&t.splice(0,t.length-240)}trimRecent(t,r){let e=r-gt,o=0;for(;o<t.length&&t[o]<e;)o++;o>0&&t.splice(0,o)}trimSamplesAt(t,r){let e=r-gt,o=0;for(;o<t.length&&t[o].ts<e;)o++;o>0&&t.splice(0,o)}};function _t(s){if(s.length===0)return 0;let t=s.slice().sort((e,o)=>e-o),r=t.length>>1;return t.length%2?t[r]:(t[r-1]+t[r])/2}var I=new Float32Array(1),M=new Uint32Array(I.buffer);function mo(s){I[0]=s;let t=M[0],r=t>>>16&32768,e=t&2147483647,o=(e>>>23)-127+15;if((t&2139095040)===2139095040)return(t&8388607)!==0?r|32256:r|31744;if(o>=31)return r|31744;if(o<=0){if(o<-10)return r;let l=e&8388607|8388608,c=14-o,m=l>>>c,_=l>>>c-1&1,g=(l&(1<<c-1)-1)!==0?1:0;return _&&(g||m&1)&&(m+=1),r|m}let a=e>>>13&1023,n=e>>>12&1,u=(e&4095)!==0?1:0,p=o<<10|a;return n&&(u||a&1)&&(p+=1,(p>>>10&31)===31)?r|31744:r|p}function fo(s){let t=(s&32768)<<16,r=(s&31744)>>>10,e=s&1023;if(r===0){if(e===0)return M[0]=t,I[0];let o=e,a=1;for(;(o&1024)===0;)o<<=1,a-=1;return o&=1023,M[0]=t|a+127-15<<23|o<<13,I[0]}return r===31?(M[0]=t|2139095040|e<<13,I[0]):(M[0]=t|r+127-15<<23|e<<13,I[0])}function re(s){let t=new Uint16Array(s.length);for(let r=0;r<s.length;r++)t[r]=mo(s[r]);return t}function D(s){let t=new Float32Array(s.length);for(let r=0;r<s.length;r++)t[r]=fo(s[r]);return t}var f=class{constructor(t){i(this,"backend",t);i(this,"shader","");i(this,"pipeline");i(this,"bindGroup");i(this,"uniformDefs",[]);i(this,"uniformBuffers",{})}createUniform(t,r){this.uniformDefs.push({name:t,type:r})}setUniform(t,r){let e=this.backend.device.createBuffer({size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});r instanceof Uint32Array?new Uint32Array(e.getMappedRange()).set(r):new Float32Array(e.getMappedRange()).set(r),e.unmap(),this.uniformBuffers[t]=e}defaultBindGroup(){let t=[],r=0;for(let e of this.inputs)t.push({binding:r++,resource:{buffer:e.buffer}});for(let e of this.weights)t.push({binding:r++,resource:{buffer:e.buffer}});for(let e of this.uniformDefs)t.push({binding:r++,resource:{buffer:this.uniformBuffers[e.name]}});return t.push({binding:r,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:t})}defaultSetup(){let t=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:t,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup()}run(){let t=this.backend.device.createCommandEncoder(),r=t.beginComputePass();r.setPipeline(this.pipeline),r.setBindGroup(0,this.bindGroup),r.dispatchWorkgroups(...this.dispatch),r.end(),this.backend.device.queue.submit([t.finish()])}};var bt=\`// Conv2d, output-channel-blocked (K=4) \\u2014 drop-in replacement for conv2d.wgsl.
|
|
1
|
+
var w=[{model:"xs",dtype:"f16",resolution:{w:384,h:216},skipFrames:2},{model:"small",dtype:"f16",resolution:{w:384,h:216},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:512,h:288},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:640,h:360},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:1280,h:720},skipFrames:0}];var ce=false;function me(a){ce=a;}function x(a){let t=`[longpipe/${a}]`,e=((...r)=>{ce&&console.log(t,...r);});return e.warn=(...r)=>{ce&&console.warn(t,...r);},e}var P=x("adaptive"),Mt=2e3,zt=1e4,Dt=30,Rt=20,Ht=5e3,Lt=.3,Vt=15e3,G=class{constructor(t){this.opts=t;this.currentPresetIdx=w.findIndex(e=>e.model===t.initialModel),this.lastSwapAt=performance.now();}opts;timer=null;currentPresetIdx;lastSwapAt=0;overshootStart=0;headroomStart=0;start(){P(`started; backend=${this.opts.backendKind} initial=${this.opts.initialModel} idx=${this.currentPresetIdx}`),this.timer=setInterval(()=>{this.tick().catch(t=>P("tick failed:",t));},Mt);}stop(){this.timer&&clearInterval(this.timer),this.timer=null;}async tick(){if(typeof document<"u"&&document.hidden)return;let t=performance.now();if(t-this.lastSwapAt<zt)return;let e=await this.opts.getStats();if(e.fps<Rt?(this.overshootStart===0&&(this.overshootStart=t),t-this.overshootStart>=Ht&&this.tryDowngrade(e.fps)):this.overshootStart=0,this.opts.backendKind==="webgpu"&&e.modelMs>0){let r=1e3/Dt*Lt;e.modelMs<r?(this.headroomStart===0&&(this.headroomStart=t),t-this.headroomStart>=Vt&&this.tryUpgrade(e.modelMs,r)):this.headroomStart=0;}}tryDowngrade(t){if(this.currentPresetIdx<=0)return;let e=this.currentPresetIdx-1;P(`downgrade ${w[this.currentPresetIdx].model} \u2192 ${w[e].model} (fps=${t})`),this.swap(e);}tryUpgrade(t,e){if(this.currentPresetIdx>=w.length-1)return;let r=this.currentPresetIdx+1;P(`upgrade ${w[this.currentPresetIdx].model} \u2192 ${w[r].model} (modelMs=${t.toFixed(1)} < ${e.toFixed(1)})`),this.swap(r);}async swap(t){let e=w[t];this.lastSwapAt=performance.now(),this.overshootStart=0,this.headroomStart=0;try{let r=this.opts.buildWeightsUrl(this.opts.weightsBaseUrl,e.model),n=await fetch(r);if(!n.ok)throw new Error(`weights fetch failed: ${n.status} ${r}`);let i=await n.arrayBuffer();await this.opts.swapPreset(e.model,i),this.currentPresetIdx=t,P(`swap to ${e.model} done`);}catch(r){P("swap failed:",r),this.opts.onError?.({message:`adaptive preset swap failed: ${r.message??String(r)}`,source:"adaptive",recoverable:true,cause:r});}}};async function be(a){let t,e=false;if(a instanceof HTMLVideoElement){if(t=a.currentSrc||a.src,!t)throw new Error("background video: HTMLVideoElement has no src")}else if(a instanceof Blob)t=URL.createObjectURL(a),e=true;else if(typeof a=="string")t=a;else throw new Error("background video: unsupported input shape");let r=document.createElement("video");r.crossOrigin="anonymous",r.muted=true,r.loop=true,r.playsInline=true,r.src=t,await new Promise((c,h)=>{r.addEventListener("loadeddata",()=>c(),{once:true}),r.addEventListener("error",()=>h(new Error(`background video: failed to load ${t}`)),{once:true});});try{await r.play();}catch(c){throw new Error(`background video: play() rejected \u2014 ${c.message}`)}let n=new MessageChannel,i=n.port1,o=n.port2,u=false,s=r.requestVideoFrameCallback?.bind(r);if(s){let c=(h,f)=>{if(!u){try{let v=new VideoFrame(r,{timestamp:f.mediaTime*1e6});i.postMessage({frame:v},[v]);}catch{}s(c);}};s(c);}else {let c=()=>{if(!u){try{let h=new VideoFrame(r,{timestamp:performance.now()*1e3});i.postMessage({frame:h},[h]);}catch{}requestAnimationFrame(c);}};requestAnimationFrame(c);}return {port:o,transferList:[o],cleanup:()=>{u=true,i.close(),r.pause(),r.removeAttribute("src"),r.load(),e&&URL.revokeObjectURL(t);}}}var Nt=4,de=8,ve=16;async function E(a){if(typeof a=="string")return a==="none"?{background:{kind:"none"}}:a==="blur"?{background:{kind:"blur",sigma:de}}:{background:{kind:"image",bitmap:await we(a)}};if(a instanceof ImageBitmap)return {background:{kind:"image",bitmap:a}};if(typeof HTMLImageElement<"u"&&a instanceof HTMLImageElement)return {background:{kind:"image",bitmap:await createImageBitmap(a)}};if(typeof HTMLVideoElement<"u"&&a instanceof HTMLVideoElement)return await xe(a);let t=a;if(t.color!==void 0)return {background:{kind:"color",rgb:$t(t.color)}};if(t.blur!==void 0)return {background:{kind:"blur",sigma:jt(t.blur)}};if(t.image!==void 0)return {background:{kind:"image",bitmap:await qt(t.image)}};if(t.video!==void 0)return await xe(t.video);throw new Error(`background: unrecognized input shape \u2014 ${k(a)}`)}async function xe(a){let t;if(typeof a=="string")t=a;else if(typeof HTMLVideoElement<"u"&&a instanceof HTMLVideoElement)t=a;else if(a&&typeof a=="object"&&"data"in a&&"type"in a)t=a.data instanceof Blob?a.data:new Blob([a.data],{type:a.type});else throw new Error(`background.video: unrecognized shape \u2014 ${k(a)}`);let e=await be(t);return {background:{kind:"video",port:e.port},transferList:e.transferList,cleanup:e.cleanup}}function $t(a){if(typeof a=="string"){let t=a.trim().replace(/^#/,"");if(/^[0-9a-fA-F]{6}$/.test(t))return [parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255];if(/^[0-9a-fA-F]{3}$/.test(t))return [parseInt(t[0]+t[0],16)/255,parseInt(t[1]+t[1],16)/255,parseInt(t[2]+t[2],16)/255];throw new Error(`background.color: hex must be #rgb or #rrggbb, got ${k(a)}`)}if(!Array.isArray(a)||a.length!==3||!a.every(t=>typeof t=="number"&&Number.isFinite(t)&&t>=0&&t<=1))throw new Error(`background.color: expected hex string or [r, g, b] floats in [0, 1], got ${k(a)}`);return [a[0],a[1],a[2]]}function jt(a){if(a===true)return de;if("sigma"in a){if(typeof a.sigma!="number"||!Number.isFinite(a.sigma)||a.sigma<0)throw new Error(`background.blur.sigma must be a non-negative number, got ${a.sigma}`);return a.sigma}if("strength"in a){let t=a.strength;if(typeof t=="number"){let e=Math.max(0,Math.min(1,t));return ve*e}if(t==="low")return Nt;if(t==="medium")return de;if(t==="high")return ve;throw new Error(`background.blur.strength must be 'low' | 'medium' | 'high' | number, got ${k(t)}`)}throw new Error(`background.blur: must be true, { strength }, or { sigma } \u2014 got ${k(a)}`)}async function qt(a){if(a instanceof ImageBitmap)return a;if(typeof HTMLImageElement<"u"&&a instanceof HTMLImageElement)return createImageBitmap(a);if(typeof a=="string")return we(a);if(a&&typeof a=="object"&&"data"in a&&"type"in a){let t=a.data instanceof Blob?a.data:new Blob([a.data],{type:a.type});return createImageBitmap(t)}throw new Error(`background.image: unrecognized shape \u2014 ${k(a)}`)}async function we(a){let t=await fetch(a);if(!t.ok)throw new Error(`background: failed to load image from ${a} (HTTP ${t.status})`);let e=await t.blob();return createImageBitmap(e)}function k(a){return a===null?"null":typeof a!="object"?typeof a+"("+String(a)+")":`${a.constructor?.name??"Object"} ${JSON.stringify(a).slice(0,80)}`}function ye(){return {input:"MediaStreamTrackProcessor"in self?"mstp":"rvfc-postmessage",output:"MediaStreamTrackGenerator"in self?"mstg":Xt()?"transfer-capture":"bitmap-shuttle"}}var F=null;function Xt(){return F!==null||(F=!/Firefox/.test(navigator.userAgent)),F}function ke(a,t,e){let r=[a];return e==="passthrough"&&r.push(...t.getAudioTracks()),new MediaStream(r)}var A=x("worker_controller"),O=class{worker;listeners=new Map;persistentEvents=new Set;constructor(t){this.worker=t,this.worker.addEventListener("message",this.handleMessage.bind(this)),A("constructed; message listener attached");}handleMessage(t){let{request_id:e,res:r}=t.data,n=this.listeners.get(e);A("msg received: request_id=",e,"handler?",!!n,"persistent?",this.persistentEvents.has(e)),n&&(n(r),this.persistentEvents.has(e)||this.listeners.delete(e));}addPersistentListener(t,e){this.persistentEvents.add(t),this.listeners.set(t,e),A("addPersistentListener:",t);}removePersistentListener(t){this.persistentEvents.delete(t),this.listeners.delete(t);}sendMessage(t,e,r=[]){let n=crypto.randomUUID();return A("sendMessage:",t,"request_id=",n,"transferables=",r.length),new Promise(i=>{this.listeners.set(n,u=>i(u));let o={cmd:t,data:e,request_id:n};this.worker.postMessage(o,r);})}terminate(){this.worker.terminate(),this.listeners.clear(),this.persistentEvents.clear();}};var Ce=x("input-postmessage/main");function Pe(a){let t=document.createElement("video");t.srcObject=a,t.muted=true,t.autoplay=true,t.playsInline=true,t.play().catch(l=>{Ce.warn("video.play() rejected:",l);});let e=t.requestVideoFrameCallback?.bind(t);if(!e)throw new Error("setupPostMessageInput: requestVideoFrameCallback not supported on this browser");let r=new MessageChannel,n=r.port1,i=r.port2,o=false,u=(l,c)=>{if(!o){try{let h=new VideoFrame(t,{timestamp:c.mediaTime*1e6});n.postMessage({frame:h},[h]);}catch(h){Ce.warn("VideoFrame() failed; skipping frame:",h);}e(u);}};return e(u),{port:i,transferList:[i],cleanup:()=>{o=true,n.close(),t.srcObject=null,t.pause();}}}function Te(a){let t=a.getVideoTracks();if(t.length===0)throw new Error("setupMstpInput: input MediaStream has no video tracks");let e=t[0],r=self.MediaStreamTrackProcessor;if(!r)throw new Error("setupMstpInput: MediaStreamTrackProcessor not supported on this browser");let i=new r({track:e}).readable;return {readable:i,transferList:[i],cleanup:()=>{i.cancel().catch(()=>{});}}}function Ue(a,t){switch(a){case "mstp":{let e=Te(t);return {initFields:{inputReadable:e.readable},transferList:e.transferList,cleanup:e.cleanup}}case "rvfc-postmessage":{let e=Pe(t);return {initFields:{inputPort:e.port},transferList:e.transferList,cleanup:e.cleanup}}}}var Kt=x("bitmap-shuttle/main"),Yt=30;function Ie(a,t=Yt){let e=document.createElement("canvas");e.width=a.w,e.height=a.h;let r=e.getContext("bitmaprenderer");if(!r)throw new Error("setupBitmapShuttleOutput: bitmaprenderer context not available");let i=e.captureStream(t).getVideoTracks();if(i.length===0)throw new Error("setupBitmapShuttleOutput: captureStream produced no video tracks");let o=i[0],u=new MessageChannel,s=u.port1,l=u.port2,c=false,h=null,f=()=>{},v=3,I=0;return s.onmessage=B=>{if(c){if(I++,I<v){B.data.bmp.close();return}f();}try{r.transferFromImageBitmap(B.data.bmp);}catch(b){Kt.warn("transferFromImageBitmap failed:",b);}},s.start(),{videoTrack:o,port:l,transferList:[l],startPassthrough:B=>{if(c)return;c=true;let b=document.createElement("video");b.srcObject=B,b.muted=true,b.playsInline=true,b.play().catch(()=>{}),h=b;let W="requestVideoFrameCallback"in b?C=>{b.requestVideoFrameCallback(C);}:C=>{requestAnimationFrame(C);},S=()=>{if(c){if(b.videoWidth===0){W(S);return}createImageBitmap(b,{resizeWidth:e.width,resizeHeight:e.height,resizeQuality:"medium"}).then(C=>{if(!c){C.close();return}try{r.transferFromImageBitmap(C);}catch{}W(S);}).catch(()=>{W(S);});}};W(S),f=()=>{c=false,h&&(h.srcObject=null,h.pause(),h=null);};},cleanup:()=>{f(),s.onmessage=null,s.close(),o.stop();}}}function Be(){let a=self.MediaStreamTrackGenerator;if(!a)throw new Error("setupMstgOutput: MediaStreamTrackGenerator not supported on this browser");let t=new a({kind:"video"}),e=t.writable;return {videoTrack:t,writable:e,transferList:[e],cleanup:()=>{e.abort().catch(()=>{}),t.stop();}}}function We(a,t=30){let e=document.createElement("canvas");e.width=a.w,e.height=a.h;let n=e.captureStream(t).getVideoTracks();if(n.length===0)throw new Error("setupTransferCaptureOutput: captureStream produced no video tracks");let i=n[0],o=e.transferControlToOffscreen();return {videoTrack:i,canvas:o,transferList:[o],cleanup:()=>{i.stop();}}}function Se(a,t){switch(a){case "mstg":{let e=Be();return {videoTrack:e.videoTrack,initFields:{outputWritable:e.writable},transferList:e.transferList,cleanup:e.cleanup}}case "transfer-capture":{let e=We(t);return {videoTrack:e.videoTrack,initFields:{outputCanvas:e.canvas},transferList:e.transferList,cleanup:e.cleanup}}case "bitmap-shuttle":{let e=Ie(t);return {videoTrack:e.videoTrack,initFields:{outputPort:e.port},transferList:e.transferList,startPassthrough:e.startPassthrough,cleanup:e.cleanup}}}}var he=`var ao=Object.defineProperty;var no=(s,t,r)=>t in s?ao(s,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[t]=r;var i=(s,t,r)=>no(s,typeof t!="symbol"?t+"":t,r);var it=!1;function lt(s){it=s}function U(s){let t=\`[longpipe/\${s}]\`,r=((...e)=>{it&&console.log(t,...e)});return r.warn=(...e)=>{it&&console.warn(t,...e)},r}var at=[{model:"xs",dtype:"f16",resolution:{w:384,h:216},skipFrames:2},{model:"small",dtype:"f16",resolution:{w:384,h:216},skipFrames:1},{model:"medium",dtype:"f16",resolution:{w:512,h:288},skipFrames:1},{model:"large",dtype:"f32",resolution:{w:640,h:360},skipFrames:0},{model:"xl",dtype:"f32",resolution:{w:1280,h:720},skipFrames:0}],so={fast:0,balanced:2,quality:4};function V(s){return s==="auto"?null:at[so[s]]}var N=class{constructor(t,r,e,o){i(this,"op");this.op=t.ops.BilinearUpsample(r,{outH:e,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var $=class{constructor(t,r,e,o){i(this,"op");this.op=t.ops.BicubicUpsample(r,{outH:e,outW:o})}get output(){return this.op.output}run(){this.op.run()}};var X=class{constructor(t,r,e,o,a="main"){i(this,"presenter");this.presenter=t.presenters.CompositeSolid(r,e,o,a)}run(){this.presenter.run()}};var j=class{constructor(t,r,e,o,a="main"){i(this,"presenter");this.presenter=t.presenters.CompositeImage(r,e,o,a)}run(){this.presenter.run()}};var q=class{constructor(t,r,e){i(this,"downs",[]);i(this,"ups",[]);let o=uo(e),a=r;for(let n=0;n<o;n++){let u=t.ops.BilinearUpsample(a,{outH:Math.max(1,Math.floor(a.h/2)),outW:Math.max(1,Math.floor(a.w/2))});this.downs.push(u),a=u.output}for(let n=o-1;n>=1;n--){let u=this.downs[n-1].output,p=t.ops.BilinearUpsample(a,{outH:u.h,outW:u.w});this.ups.push(p),a=p.output}}get output(){return this.ups.length>0?this.ups[this.ups.length-1].output:this.downs[0].output}run(){for(let t of this.downs)t.run();for(let t of this.ups)t.run()}};function uo(s){let t=Math.max(1,3*s);return Math.max(2,Math.min(6,Math.round(Math.log2(t))))}var po=.05,K=class{constructor(t,r,e,o,a="main"){i(this,"blur");i(this,"presenter");o<=po?(this.blur=null,this.presenter=t.presenters.CompositeImage(r,e,r,a)):(this.blur=new q(t,r,o),this.presenter=t.presenters.CompositeImageBilinear(r,e,this.blur.output,a))}run(){this.blur?.run(),this.presenter.run()}};var Y=class{constructor(t){i(this,"backend",t);i(this,"displayInput");i(this,"image");i(this,"network",null);i(this,"networkInput",null);i(this,"upscaler",null);i(this,"upscalerMode","bilinear");i(this,"bgConfig",{mode:"solid",color:[0,0,0]});i(this,"compositors",new Map);let r=t.canvas;this.displayInput=t.ops.Input(r.height,r.width),this.image=this.displayInput.output}attachNetwork(t,r,e){this.network=t,this.networkInput=r,this.upscalerMode=e.upscaler,this.bgConfig=e.background,this.upscaler=this.makeUpscaler(),this.compositors.clear()}hasNetwork(){return this.network!==null}setSource(t){this.networkInput?.setSource(t),this.displayInput.setSource(t)}setUpscaler(t){t!==this.upscalerMode&&(this.upscalerMode=t,this.network&&(this.upscaler=this.makeUpscaler(),this.compositors.clear()))}setBackground(t){this.bgConfig=t}run(){this.runModel(),this.runDisplay()}runDisplay(){this.refreshDisplayInput(),this.compositeMain(!1)}runPassthrough(){this.refreshDisplayInput(),this.compositeMain(!0)}compositeMain(t){this.compositeTo("main",t?{mode:"passthrough"}:this.bgConfig)}refreshDisplayInput(){this.displayInput.run()}compositeTo(t,r){let e=this.compositors.get(t);if(e&&lo(e.spec,r)){e.handle.run();return}let o=this.buildCompositor(t,r);this.compositors.set(t,{spec:r,handle:o}),o.run()}runModel(){if(!this.network||!this.networkInput||!this.upscaler)throw new Error("RenderOp.runModel called before attachNetwork");this.networkInput.run(),this.network.run(),this.upscaler.run()}makeUpscaler(){if(!this.network)throw new Error("makeUpscaler called with no network");let{backend:t,network:r,image:e}=this;return this.upscalerMode==="bicubic"?new $(t,r.output,e.h,e.w):new N(t,r.output,e.h,e.w)}buildCompositor(t,r){let{backend:e,image:o}=this;if(r.mode==="passthrough")return e.presenters.CompositePassthrough(o,t);if(!this.upscaler)throw new Error("RenderOp.compositeTo (effect spec) called before attachNetwork");let a=this.upscaler.output;switch(r.mode){case"solid":return new X(e,o,a,r.color,t);case"image":return new j(e,o,a,r.image,t);case"blur":return new K(e,o,a,r.sigma,t)}}};function lo(s,t){if(s.mode!==t.mode)return!1;switch(t.mode){case"passthrough":return!0;case"solid":{let r=s.color;return r[0]===t.color[0]&&r[1]===t.color[1]&&r[2]===t.color[2]}case"blur":return s.sigma===t.sigma;case"image":return s.image===t.image}}var co=s=>typeof s=="object"&&s!==null&&typeof s.offset=="number"&&typeof s.length=="number";function ct(s){if(s.byteLength<4)throw new Error("weights buffer too small");let t=new DataView(s,0,4).getUint32(0,!0),r=4+t;if(s.byteLength<r)throw new Error("weights buffer truncated (header)");let e=new Uint8Array(s,4,t),o=JSON.parse(new TextDecoder().decode(e)),a=o.__dtype__??"f32",n=a==="f16"?2:4;if(r%n!==0)throw new Error(\`payload not \${n}-byte aligned (header=\${t})\`);let u=(s.byteLength-r)/n,p=l=>{if(co(l)){let{offset:c,length:m}=l;if(c+m>u)throw new Error(\`array ref out of range: offset=\${c} length=\${m}\`);let _=r+c*n;return a==="f16"?new Uint16Array(s,_,m):new Float32Array(s,_,m)}if(Array.isArray(l))return l.map(p);if(typeof l=="object"&&l!==null){let c={};for(let m of Object.keys(l))m!=="__dtype__"&&(c[m]=p(l[m]));return c}return l};return p(o)}var R=class{constructor(t,r,e,o){i(this,"inputs");i(this,"output");i(this,"gatesOp");i(this,"candOp");this.inputs=[r,e],this.gatesOp=t.ops.GatesFused(r,e,{weights:o.gates,bias:o.gatesBias}),this.candOp=t.ops.CandUpdateFused(r,e,this.gatesOp.output,{weights:o.cand,bias:o.candBias},o.gamma),this.output=this.candOp.output}run(){this.gatesOp.run(),this.candOp.run()}};function dt(s,t,r,e){let o=e.variant,a=o==="E"||o==="D",n=o==="D",u=t.h,p=t.w,l=[],c=null,m=null,_=0,g=0,x;if(a)if(n){if(!r.down2)throw new Error("variant D requires w.down2");_=Math.round(u/1.25),g=Math.round(p/1.25);let y=s.ops.Conv2d(t,r.down1,{outChannels:e.cHigh,kernel:3,stride:1,padding:1,activation:"relu"});l.push(y),m=y.output;let T=s.ops.BilinearUpsample(m,{outH:_,outW:g});l.push(T),c=T.output;let P=s.ops.DownAdapter(c,r.down2,r.adapter,{stride:2});l.push(P),x=P.output}else{if(!r.down2)throw new Error("variant E requires w.down2");let y=s.ops.Conv2d(t,r.down1,{outChannels:e.cHigh,kernel:3,stride:2,padding:1,activation:"relu"});l.push(y),c=y.output,_=c.h,g=c.w;let T=s.ops.DownAdapter(c,r.down2,r.adapter,{stride:2});l.push(T),x=T.output}else{let y=o==="A"?2:3,T=s.ops.DownAdapter(t,r.down1,r.adapter,{stride:y});l.push(T),x=T.output}return{steps:l,adapted:x,d1:c,dFull:m,midH:_,midW:g}}function mt(s,t,r,e,o,a,n,u,p,l){let c=p.variant,m=c==="E"||c==="D",_=c==="D",g=[],x=s.ops.ConvExpand(r,u.expandFeat);g.push(x);let y=x.output,T=null;if(l&&p.gruAtBase){let G=new R(s,y,l.hPrev,l.weights);g.push(G),y=G.output,T=G.output}let P;if(m){if(!u.up1Combine)throw new Error("two-stage variant requires w.up1Combine");let G=s.ops.BilinearUpsample(y,{outH:a,outW:n});g.push(G);let ut=s.ops.CatConv6to2(G.output,e,u.up1Combine);g.push(ut);let pt=s.ops.BilinearUpsample(ut.output,{outH:t.h,outW:t.w});g.push(pt),P=pt.output}else{let G=s.ops.BilinearUpsample(y,{outH:t.h,outW:t.w});g.push(G),P=G.output}if(l&&!p.gruAtBase){let G=new R(s,P,l.hPrev,l.weights);g.push(G),P=G.output,T=G.output}let z=_?s.ops.UpFinalSkip(P,o,t,u.upCombine):s.ops.UpFinal(P,t,u.upCombine);return g.push(z),{steps:g,alpha:z.output,hiddenState:T}}var Q=class{constructor(t,r,e,o,a,n,u){i(this,"inputs");i(this,"output");i(this,"hiddenState");i(this,"steps");this.inputs=[r];let p=dt(t,r,o,a),l=new n(t,p.adapted,e),c=t.ops.BilinearUpsample(l.featLowRes,{outH:p.adapted.h,outW:p.adapted.w}),m=mt(t,r,c.output,p.d1,p.dFull,p.midH,p.midW,o,a,u);this.steps=[...p.steps,l,c,...m.steps],this.output=m.alpha,this.hiddenState=m.hiddenState}run(){for(let t of this.steps)t.run()}};var S=class{constructor(t,r,e,o){i(this,"inputs");i(this,"output");i(this,"dwOp");i(this,"pwOp");this.inputs=[r],this.dwOp=t.ops.DepthwiseConv2d(r,e.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.pwOp=t.ops.Conv2d(this.dwOp.output,e.pw,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.pwOp.output}run(){this.dwOp.run(),this.pwOp.run()}};var v=class{constructor(t,r,e,o){i(this,"inputs");i(this,"output");i(this,"expandOp");i(this,"dwOp");i(this,"projOp");this.inputs=[r];let a=o.midChannels!==o.inChannels,n=o.stride===1&&o.inChannels===o.outChannels;this.expandOp=a?t.ops.Conv2d(r,e.expand,{outChannels:o.midChannels,kernel:1,stride:1,padding:0,activation:"relu6"}):null;let u=this.expandOp?this.expandOp.output:r;this.dwOp=t.ops.DepthwiseConv2d(u,e.dw,{kernel:o.kernel,stride:o.stride,padding:o.padding,activation:"relu6"}),this.projOp=n?t.ops.ProjResidual(this.dwOp.output,r,e.proj,{outChannels:o.outChannels}):t.ops.Conv2d(this.dwOp.output,e.proj,{outChannels:o.outChannels,kernel:1,stride:1,padding:0,activation:"none"}),this.output=this.projOp.output}run(){this.expandOp?.run(),this.dwOp.run(),this.projOp.run()}};var B=class{constructor(t,r,e,o,a){i(this,"inputs");i(this,"output");i(this,"upOp");i(this,"concatConvOp");i(this,"conv2Op");this.inputs=[r,e],this.upOp=t.ops.BilinearUpsample(r,{outH:e.h,outW:e.w}),this.concatConvOp=t.ops.ConcatConv2d(this.upOp.output,e,o.conv1,{outChannels:a.outChannels}),this.conv2Op=t.ops.Conv2d(this.concatConvOp.output,o.conv2,{outChannels:a.outChannels,kernel:3,stride:1,padding:1,activation:"relu6"}),this.output=this.conv2Op.output}run(){this.upOp.run(),this.concatConvOp.run(),this.conv2Op.run()}};var J=class{constructor(t,r,e){i(this,"output");i(this,"featLowRes");i(this,"stem");i(this,"s0");i(this,"s1b0");i(this,"s1b1");i(this,"s2b0");i(this,"s2b1");i(this,"s3b0");i(this,"s3b1");i(this,"s3b2");i(this,"s4b0");i(this,"s4b1");i(this,"s4b2");i(this,"bottleneck");i(this,"dec0");i(this,"dec1");i(this,"finalUp");i(this,"outConv");i(this,"alpha");this.stem=t.ops.Conv2d(r,e.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new S(t,this.stem.output,e.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new v(t,this.s0.output,e.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new v(t,this.s1b0.output,e.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new v(t,this.s1b1.output,e.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new v(t,this.s2b0.output,e.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new v(t,this.s2b1.output,e.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new v(t,this.s3b0.output,e.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new v(t,this.s3b1.output,e.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new v(t,this.s3b2.output,e.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new v(t,this.s4b0.output,e.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new v(t,this.s4b1.output,e.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.bottleneck=t.ops.Conv2d(this.s4b2.output,e.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new B(t,this.bottleneck.output,this.s2b1.output,e.decoder.blocks[0],{outChannels:64}),this.dec1=new B(t,this.dec0.output,this.s1b1.output,e.decoder.blocks[1],{outChannels:32}),this.finalUp=t.ops.UpsampleConv1x1(this.dec1.output,e.decoder.finalUpsample,{outH:this.dec1.output.h*2,outW:this.dec1.output.w*2,outChannels:32,activation:"relu6"}),this.featLowRes=this.finalUp.output,this.outConv=t.ops.Conv2d(this.finalUp.output,e.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=t.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var Z=class{constructor(t,r,e){i(this,"output");i(this,"featLowRes");i(this,"stem");i(this,"s0");i(this,"s1b0");i(this,"s1b1");i(this,"s2b0");i(this,"s2b1");i(this,"s3b0");i(this,"s3b1");i(this,"s3b2");i(this,"s4b0");i(this,"s4b1");i(this,"s4b2");i(this,"s5b0");i(this,"s5b1");i(this,"s5b2");i(this,"s5b3");i(this,"s6b0");i(this,"bottleneck");i(this,"dec0");i(this,"dec1");i(this,"dec2");i(this,"finalUp");i(this,"outConv");i(this,"alpha");this.stem=t.ops.Conv2d(r,e.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new S(t,this.stem.output,e.encoder.s0,{outChannels:16,kernel:3,stride:1,padding:1}),this.s1b0=new v(t,this.s0.output,e.encoder.s1[0],{inChannels:16,midChannels:96,outChannels:24,kernel:3,stride:2,padding:"same"}),this.s1b1=new v(t,this.s1b0.output,e.encoder.s1[1],{inChannels:24,midChannels:144,outChannels:24,kernel:3,stride:1,padding:1}),this.s2b0=new v(t,this.s1b1.output,e.encoder.s2[0],{inChannels:24,midChannels:144,outChannels:40,kernel:5,stride:2,padding:"same"}),this.s2b1=new v(t,this.s2b0.output,e.encoder.s2[1],{inChannels:40,midChannels:240,outChannels:40,kernel:5,stride:1,padding:2}),this.s3b0=new v(t,this.s2b1.output,e.encoder.s3[0],{inChannels:40,midChannels:240,outChannels:80,kernel:3,stride:2,padding:"same"}),this.s3b1=new v(t,this.s3b0.output,e.encoder.s3[1],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s3b2=new v(t,this.s3b1.output,e.encoder.s3[2],{inChannels:80,midChannels:480,outChannels:80,kernel:3,stride:1,padding:1}),this.s4b0=new v(t,this.s3b2.output,e.encoder.s4[0],{inChannels:80,midChannels:480,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b1=new v(t,this.s4b0.output,e.encoder.s4[1],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s4b2=new v(t,this.s4b1.output,e.encoder.s4[2],{inChannels:112,midChannels:672,outChannels:112,kernel:5,stride:1,padding:2}),this.s5b0=new v(t,this.s4b2.output,e.encoder.s5[0],{inChannels:112,midChannels:672,outChannels:192,kernel:5,stride:2,padding:"same"}),this.s5b1=new v(t,this.s5b0.output,e.encoder.s5[1],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b2=new v(t,this.s5b1.output,e.encoder.s5[2],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s5b3=new v(t,this.s5b2.output,e.encoder.s5[3],{inChannels:192,midChannels:1152,outChannels:192,kernel:5,stride:1,padding:2}),this.s6b0=new v(t,this.s5b3.output,e.encoder.s6[0],{inChannels:192,midChannels:1152,outChannels:320,kernel:3,stride:1,padding:1}),this.bottleneck=t.ops.Conv2d(this.s6b0.output,e.bottleneck,{outChannels:128,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new B(t,this.bottleneck.output,this.s4b2.output,e.decoder.blocks[0],{outChannels:64}),this.dec1=new B(t,this.dec0.output,this.s2b1.output,e.decoder.blocks[1],{outChannels:32}),this.dec2=new B(t,this.dec1.output,this.s1b1.output,e.decoder.blocks[2],{outChannels:16}),this.finalUp=t.ops.UpsampleConv1x1(this.dec2.output,e.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:16,activation:"relu6"}),this.featLowRes=this.finalUp.output,this.outConv=t.ops.Conv2d(this.finalUp.output,e.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=t.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run(),this.s1b0.run(),this.s1b1.run(),this.s2b0.run(),this.s2b1.run(),this.s3b0.run(),this.s3b1.run(),this.s3b2.run(),this.s4b0.run(),this.s4b1.run(),this.s4b2.run(),this.s5b0.run(),this.s5b1.run(),this.s5b2.run(),this.s5b3.run(),this.s6b0.run(),this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var nt=[[{in:24,mid:144,out:32,k:3,s:2},{in:32,mid:192,out:32,k:3,s:1},{in:32,mid:192,out:32,k:3,s:1},{in:32,mid:192,out:32,k:3,s:1}],[{in:32,mid:192,out:56,k:5,s:2},{in:56,mid:336,out:56,k:5,s:1},{in:56,mid:336,out:56,k:5,s:1},{in:56,mid:336,out:56,k:5,s:1}],[{in:56,mid:336,out:112,k:3,s:2},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1},{in:112,mid:672,out:112,k:3,s:1}],[{in:112,mid:672,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1},{in:160,mid:960,out:160,k:5,s:1}],[{in:160,mid:960,out:272,k:5,s:2},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1},{in:272,mid:1632,out:272,k:5,s:1}],[{in:272,mid:1632,out:448,k:3,s:1}]],ee=class{constructor(t,r,e){i(this,"output");i(this,"featLowRes");i(this,"stem");i(this,"s0");i(this,"stages");i(this,"bottleneck");i(this,"dec0");i(this,"dec1");i(this,"dec2");i(this,"finalUp");i(this,"outConv");i(this,"alpha");this.stem=t.ops.Conv2d(r,e.encoder.stem,{outChannels:32,kernel:3,stride:2,padding:"same",activation:"relu6"}),this.s0=new S(t,this.stem.output,e.encoder.s0,{outChannels:24,kernel:3,stride:1,padding:1});let o=[e.encoder.s1,e.encoder.s2,e.encoder.s3,e.encoder.s4,e.encoder.s5,e.encoder.s6];this.stages=[];let a=this.s0.output;for(let m=0;m<nt.length;m++){let _=[];for(let g=0;g<nt[m].length;g++){let x=nt[m][g],y=new v(t,a,o[m][g],{inChannels:x.in,midChannels:x.mid,outChannels:x.out,kernel:x.k,stride:x.s,padding:x.s===2?"same":(x.k-1)/2});_.push(y),a=y.output}this.stages.push(_)}let n=m=>this.stages[m][this.stages[m].length-1].output,u=n(0),p=n(1),l=n(3),c=n(5);this.bottleneck=t.ops.Conv2d(c,e.bottleneck,{outChannels:256,kernel:1,stride:1,padding:0,activation:"relu6"}),this.dec0=new B(t,this.bottleneck.output,l,e.decoder.blocks[0],{outChannels:128}),this.dec1=new B(t,this.dec0.output,p,e.decoder.blocks[1],{outChannels:64}),this.dec2=new B(t,this.dec1.output,u,e.decoder.blocks[2],{outChannels:32}),this.finalUp=t.ops.UpsampleConv1x1(this.dec2.output,e.decoder.finalUpsample,{outH:this.dec2.output.h*2,outW:this.dec2.output.w*2,outChannels:32,activation:"relu6"}),this.featLowRes=this.finalUp.output,this.outConv=t.ops.Conv2d(this.finalUp.output,e.decoder.outputConv,{outChannels:4,kernel:1,stride:1,padding:0,activation:"none"}),this.alpha=t.ops.UpsampleSigmoid(this.outConv.output,{outH:this.outConv.output.h*2,outW:this.outConv.output.w*2}),this.output=this.alpha.output}run(){this.stem.run(),this.s0.run();for(let t of this.stages)for(let r of t)r.run();this.bottleneck.run(),this.dec0.run(),this.dec1.run(),this.dec2.run(),this.finalUp.run(),this.outConv.run(),this.alpha.run()}};var ft=J,ht=Z,mo=ee,E={xs:{base:ft,wrapper:{variant:"B",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:384,h:216},baseRes:{w:128,h:72}},small:{base:ft,wrapper:{variant:"A",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:384,h:216},baseRes:{w:192,h:108}},medium:{base:ht,wrapper:{variant:"A",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:512,h:288},baseRes:{w:256,h:144}},large:{base:ht,wrapper:{variant:"D",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:640,h:360},baseRes:{w:256,h:144}},xl:{base:mo,wrapper:{variant:"E",cHigh:4,cLow:4,cUp:2,gruAtBase:!0},hasGru:!0,canvasRes:{w:1280,h:720},baseRes:{w:320,h:180}}};var fo=15,ho=5,gt=1e3,te=class{constructor(t){i(this,"canvas");i(this,"backend");i(this,"backendKind");i(this,"topology");i(this,"preset",null);i(this,"enabled");i(this,"currentBackground");i(this,"modelTimingCounter",0);i(this,"renderOp");i(this,"tierModel",null);i(this,"hPrev",null);i(this,"bgImageInputs",new Map);i(this,"bgVideoInputs",new Map);i(this,"bgVideoPorts",new Map);i(this,"previewCanvas",null);i(this,"previewCtx",null);i(this,"previewBg",null);i(this,"previewEffectSpec",null);i(this,"previewIntervalMs",1e3/fo);i(this,"lastPreviewAt",0);i(this,"skipCounter",0);i(this,"framesRenderedAt",[]);i(this,"modelRunSamples",[]);i(this,"displayRunSamples",[]);i(this,"skippedCount",0);this.backend=t.backend,this.backendKind=t.backendKind,this.canvas=t.canvas,this.enabled=t.enabled,this.currentBackground=t.background,this.topology=t.topology,this.renderOp=new Y(this.backend)}process(t){this.renderOp.setSource(t);let r=performance.now(),e=this.renderOp.hasNetwork(),o=this.enabled&&e&&this.currentBackground.kind!=="none",a=this.isPreviewTick(r),n=a&&e&&this.previewBg!==null&&this.previewBg.kind!=="none",u=!1;o&&(this.shouldRunModel()?(this.runModelOnce(),u=!0):this.skippedCount++),!u&&n&&(this.runModelOnce(),u=!0);let p=performance.now();a&&this.previewCanvas?(this.backendKind==="webgl"?this.compositePreviewWebGL(o,n):(this.compositeMain(o),this.renderOp.compositeTo("preview",this.previewSpec(n))),this.lastPreviewAt=r):this.compositeMain(o),this.displayRunSamples.push({ts:performance.now(),ms:performance.now()-p}),this.trimSamples(this.displayRunSamples),this.framesRenderedAt.push(performance.now()),this.trim(this.framesRenderedAt)}compositeMain(t){t?this.renderOp.runDisplay():this.renderOp.runPassthrough()}compositePreviewWebGL(t,r){this.renderOp.refreshDisplayInput(),this.renderOp.compositeTo("preview",this.previewSpec(r));let e=this.canvas.transferToImageBitmap();this.previewCtx.transferFromImageBitmap(e),this.renderOp.compositeMain(!t)}previewSpec(t){return t&&this.previewEffectSpec?this.previewEffectSpec:{mode:"passthrough"}}runModelOnce(){let t=performance.now();this.renderOp.runModel(),this.hPrev&&this.tierModel?.hiddenState&&this.backend.copyTensor(this.tierModel.hiddenState,this.hPrev),this.backendKind==="webgpu"&&this.modelTimingCounter%ho===0&&this.backend.sync().then(()=>{this.modelRunSamples.push({ts:performance.now(),ms:performance.now()-t}),this.trimSamples(this.modelRunSamples)}).catch(()=>{}),this.modelTimingCounter++}isPreviewTick(t){return!this.previewCanvas||this.previewBg===null||!this.enabled?!1:t-this.lastPreviewAt>=this.previewIntervalMs}shouldRunModel(){return this.skipCounter===0?(this.skipCounter=this.preset?.skipFrames??0,!0):(this.skipCounter--,!1)}setBackground(t){this.currentBackground=t,this.renderOp.setBackground(this.translateBackgroundFor("main",t))}setEnabled(t){this.enabled=t}attachPreview(t){if(t.width=this.canvas.width,t.height=this.canvas.height,this.previewCanvas=t,this.backendKind==="webgpu")this.backend.attachCanvas("preview",t);else{let r=t.getContext("bitmaprenderer");if(!r)throw new Error("renderer: failed to get bitmaprenderer context for preview canvas");this.previewCtx=r}}setPreview(t,r){this.previewBg=t,this.previewEffectSpec=t.kind==="none"?null:this.translateBackgroundFor("preview",t),r?.fps&&r.fps>0&&(this.previewIntervalMs=1e3/r.fps),this.lastPreviewAt=0}clearPreview(){this.previewBg=null,this.previewEffectSpec=null;let t=this.bgVideoPorts.get("preview");t&&(t.close(),this.bgVideoPorts.delete("preview"))}setPreset(t,r){let e=E[t.model];if(!e)throw new Error(\`renderer: no TIER_CONFIG entry for model '\${t.model}'\`);let o=ct(r),a=this.backend.ops.Input(e.canvasRes.h,e.canvasRes.w),n,u=null;if(e.hasGru){let l=e.wrapper.gruAtBase?e.baseRes:e.canvasRes;u=this.backend.tensor(l.h,l.w,4,new Float32Array(l.h*l.w*4)),n={weights:o.gru,hPrev:u}}let p=new Q(this.backend,a.output,o.base,o.wrapper,e.wrapper,e.base,n);this.renderOp.attachNetwork(p,a,{upscaler:"bilinear",background:this.translateBackgroundFor("main",this.currentBackground)}),this.tierModel=p,this.hPrev=u,this.preset=t,this.skipCounter=0}destroy(){for(let t of this.bgVideoPorts.values())t.close();this.bgVideoPorts.clear(),this.backend.destroy()}getStats(){let t=performance.now();return this.trimRecent(this.framesRenderedAt,t),this.trimSamplesAt(this.modelRunSamples,t),this.trimSamplesAt(this.displayRunSamples,t),{fps:this.framesRenderedAt.length,modelFps:this.modelRunSamples.length,modelMs:_t(this.modelRunSamples.map(r=>r.ms)),displayMs:_t(this.displayRunSamples.map(r=>r.ms)),skipped:this.skippedCount,preset:this.preset?.model??"boot",skipFrames:this.preset?.skipFrames??0,enabled:this.enabled,inputPath:this.topology.input,outputPath:this.topology.output}}translateBackgroundFor(t,r){let e=this.bgVideoPorts.get(t);switch(r.kind!=="video"&&e&&(e.close(),this.bgVideoPorts.delete(t)),r.kind){case"none":return{mode:"solid",color:[0,0,0]};case"color":return{mode:"solid",color:r.rgb};case"blur":return{mode:"blur",sigma:r.sigma};case"image":{let o=this.bgInputFor(this.bgImageInputs,t);return o.setSource(r.bitmap),o.run(),{mode:"image",image:o.output}}case"video":{let o=this.bgInputFor(this.bgVideoInputs,t);return e&&e.close(),this.bgVideoPorts.set(t,r.port),r.port.onmessage=a=>{let n=a.data.frame;try{o.setSource(n),o.run()}finally{n.close()}},r.port.start?.(),{mode:"image",image:o.output}}}}bgInputFor(t,r){let e=t.get(r);return e||(e=this.backend.ops.Input(this.canvas.height,this.canvas.width),t.set(r,e)),e}trim(t){t.length>240&&t.splice(0,t.length-240)}trimSamples(t){t.length>240&&t.splice(0,t.length-240)}trimRecent(t,r){let e=r-gt,o=0;for(;o<t.length&&t[o]<e;)o++;o>0&&t.splice(0,o)}trimSamplesAt(t,r){let e=r-gt,o=0;for(;o<t.length&&t[o].ts<e;)o++;o>0&&t.splice(0,o)}};function _t(s){if(s.length===0)return 0;let t=s.slice().sort((e,o)=>e-o),r=t.length>>1;return t.length%2?t[r]:(t[r-1]+t[r])/2}var O=new Float32Array(1),M=new Uint32Array(O.buffer);function go(s){O[0]=s;let t=M[0],r=t>>>16&32768,e=t&2147483647,o=(e>>>23)-127+15;if((t&2139095040)===2139095040)return(t&8388607)!==0?r|32256:r|31744;if(o>=31)return r|31744;if(o<=0){if(o<-10)return r;let l=e&8388607|8388608,c=14-o,m=l>>>c,_=l>>>c-1&1,g=(l&(1<<c-1)-1)!==0?1:0;return _&&(g||m&1)&&(m+=1),r|m}let a=e>>>13&1023,n=e>>>12&1,u=(e&4095)!==0?1:0,p=o<<10|a;return n&&(u||a&1)&&(p+=1,(p>>>10&31)===31)?r|31744:r|p}function _o(s){let t=(s&32768)<<16,r=(s&31744)>>>10,e=s&1023;if(r===0){if(e===0)return M[0]=t,O[0];let o=e,a=1;for(;(o&1024)===0;)o<<=1,a-=1;return o&=1023,M[0]=t|a+127-15<<23|o<<13,O[0]}return r===31?(M[0]=t|2139095040|e<<13,O[0]):(M[0]=t|r+127-15<<23|e<<13,O[0])}function re(s){let t=new Uint16Array(s.length);for(let r=0;r<s.length;r++)t[r]=go(s[r]);return t}function I(s){let t=new Float32Array(s.length);for(let r=0;r<s.length;r++)t[r]=_o(s[r]);return t}var f=class{constructor(t){i(this,"backend",t);i(this,"shader","");i(this,"pipeline");i(this,"bindGroup");i(this,"uniformDefs",[]);i(this,"uniformBuffers",{})}createUniform(t,r){this.uniformDefs.push({name:t,type:r})}setUniform(t,r){let e=this.backend.device.createBuffer({size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});r instanceof Uint32Array?new Uint32Array(e.getMappedRange()).set(r):new Float32Array(e.getMappedRange()).set(r),e.unmap(),this.uniformBuffers[t]=e}defaultBindGroup(){let t=[],r=0;for(let e of this.inputs)t.push({binding:r++,resource:{buffer:e.buffer}});for(let e of this.weights)t.push({binding:r++,resource:{buffer:e.buffer}});for(let e of this.uniformDefs)t.push({binding:r++,resource:{buffer:this.uniformBuffers[e.name]}});return t.push({binding:r,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:t})}defaultSetup(){let t=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:t,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup()}run(){let t=this.backend.device.createCommandEncoder(),r=t.beginComputePass();r.setPipeline(this.pipeline),r.setBindGroup(0,this.bindGroup),r.dispatchWorkgroups(...this.dispatch),r.end(),this.backend.device.queue.submit([t.finish()])}};var bt=\`// Conv2d, output-channel-blocked (K=4) \\u2014 drop-in replacement for conv2d.wgsl.
|
|
2
2
|
//
|
|
3
3
|
// Identical math, layout, and output to conv2d.wgsl, but each thread computes 4
|
|
4
4
|
// output channel-groups (16 channels) for one pixel, loading each input vec4
|
|
@@ -98,7 +98,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
98
98
|
if (has2) { output_buf[baseO + o2] = act(acc2, params.activation); }
|
|
99
99
|
if (has3) { output_buf[baseO + o3] = act(acc3, params.activation); }
|
|
100
100
|
}
|
|
101
|
-
\`;var
|
|
101
|
+
\`;var vt=\`enable f16;
|
|
102
102
|
|
|
103
103
|
// Conv2d, output-channel-blocked (K=4) \\u2014 full f16. Drop-in replacement for
|
|
104
104
|
// conv2d_f16.wgsl. Each thread computes 4 output channel-groups for one pixel,
|
|
@@ -190,7 +190,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
190
190
|
if (has2) { output_buf[baseO + o2] = act(acc2, params.activation); }
|
|
191
191
|
if (has3) { output_buf[baseO + o3] = act(acc3, params.activation); }
|
|
192
192
|
}
|
|
193
|
-
\`;function w(s,t,r,e){return typeof e=="number"?Math.floor((s+2*e-t)/r)+1:e==="same"?Math.ceil(s/r):Math.floor((s-t)/r)+1}function
|
|
193
|
+
\`;function w(s,t,r,e){return typeof e=="number"?Math.floor((s+2*e-t)/r)+1:e==="same"?Math.ceil(s/r):Math.floor((s-t)/r)+1}function xo(s,t,r,e){return Math.floor(Math.max((t-1)*e+r-s,0)/2)}function k(s,t,r,e,o){return typeof s=="number"?s:s==="same"?xo(t,r,e,o):0}function d(s){return s instanceof Float32Array||s instanceof Uint16Array?s:new Float32Array(s)}function b(s){let t=Math.max(4,Math.ceil(s.length/4)*4),r=new Float32Array(t);for(let e=0;e<s.length;e++)r[e]=s[e];return r}var oe=class extends f{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?vt:bt;let n=w(e.h,a.kernel,a.stride,a.padding),u=w(e.w,a.kernel,a.stride,a.padding),p=e.c/4,l=a.outChannels/4,c=k(a.padding,e.h,n,a.kernel,a.stride),m=k(a.padding,e.w,u,a.kernel,a.stride);this.output=r.tensor(n,u,a.outChannels),this.inputs=[e],this.weights=[r.upload(d(o.weights)),r.upload(d(o.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,n,u,p,l,a.kernel,a.kernel,a.stride,c,m,a.activation==="relu6"?1:a.activation==="relu"?2:0])),this.defaultSetup(),this.dispatch=[Math.ceil(u/8),Math.ceil(n/8),Math.ceil(l/4)]}};var xt=\`// Depthwise Conv2d \\u2014 groups = in_channels (each channel convolved independently).
|
|
194
194
|
//
|
|
195
195
|
// Weight layout: [K*K][channel_groups] array of vec4
|
|
196
196
|
// weight index = (ky*kernel_w + kx) * channel_groups + c
|
|
@@ -330,7 +330,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
330
330
|
|
|
331
331
|
output_buf[y * params.out_w * C + x * C + c] = result;
|
|
332
332
|
}
|
|
333
|
-
\`;var ie=class extends f{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?yt:
|
|
333
|
+
\`;var ie=class extends f{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?yt:xt;let n=w(e.h,a.kernel,a.stride,a.padding),u=w(e.w,a.kernel,a.stride,a.padding),p=e.c/4,l=k(a.padding,e.h,n,a.kernel,a.stride),c=k(a.padding,e.w,u,a.kernel,a.stride);this.output=r.tensor(n,u,e.c),this.inputs=[e],this.weights=[r.upload(d(o.weights)),r.upload(d(o.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,n,u,p,a.kernel,a.kernel,a.stride,l,c,a.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(u/8),Math.ceil(n/8),p]}};var wt=\`// Element-wise add of two tensors \\u2014 used for residual connections in MBConv blocks.
|
|
334
334
|
// Operates on the flat float buffer directly; layout is irrelevant for a pure element-wise op.
|
|
335
335
|
|
|
336
336
|
struct Params {
|
|
@@ -797,7 +797,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
797
797
|
output_buf[out_idx] = input_b[y * W * Bg + x * Bg + c_b];
|
|
798
798
|
}
|
|
799
799
|
}
|
|
800
|
-
\`;var
|
|
800
|
+
\`;var Ot=\`enable f16;
|
|
801
801
|
|
|
802
802
|
// Channel concatenation \\u2014 full f16 variant.
|
|
803
803
|
|
|
@@ -838,7 +838,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
838
838
|
output_buf[out_idx] = input_b[y * W * Bg + x * Bg + c_b];
|
|
839
839
|
}
|
|
840
840
|
}
|
|
841
|
-
\`;var ce=class extends f{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights",[]);i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?
|
|
841
|
+
\`;var ce=class extends f{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights",[]);i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?Ot:Et;let a=e.c/4,n=o.c/4,u=a+n;this.output=r.tensor(e.h,e.w,e.c+o.c),this.inputs=[e,o],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,a,n,u,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),u]}};var It=\`// Conv2d + skip add fused.
|
|
842
842
|
// Identical to conv2d.wgsl except skip is an activation input (binding 1),
|
|
843
843
|
// added element-wise to the conv result at write time.
|
|
844
844
|
// Eliminates the separate add dispatch and its intermediate buffer round-trip.
|
|
@@ -912,7 +912,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
912
912
|
let out_idx = y * params.out_w * O + x * O + o;
|
|
913
913
|
output_buf[out_idx] = result + skip_buf[out_idx];
|
|
914
914
|
}
|
|
915
|
-
\`;var
|
|
915
|
+
\`;var Dt=\`enable f16;
|
|
916
916
|
|
|
917
917
|
// Conv2d + skip add fused \\u2014 full f16 variant.
|
|
918
918
|
|
|
@@ -986,7 +986,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
986
986
|
let out_idx = y * params.out_w * O + x * O + o;
|
|
987
987
|
output_buf[out_idx] = result + skip_buf[out_idx];
|
|
988
988
|
}
|
|
989
|
-
\`;var de=class extends f{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?
|
|
989
|
+
\`;var de=class extends f{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?Dt:It;let u=w(e.h,n.kernel,n.stride,n.padding),p=w(e.w,n.kernel,n.stride,n.padding),l=e.c/4,c=n.outChannels/4,m=k(n.padding,e.h,u,n.kernel,n.stride),_=k(n.padding,e.w,p,n.kernel,n.stride);this.output=r.tensor(u,p,n.outChannels),this.inputs=[e,o],this.weights=[r.upload(d(a.weights)),r.upload(d(a.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,u,p,l,c,n.kernel,n.kernel,n.stride,m,_,n.activation==="relu6"?1:0])),this.defaultSetup(),this.dispatch=[Math.ceil(p/8),Math.ceil(u/8),c]}};var At=\`// proj_residual: bespoke 1\\xD71 conv (no activation) + residual add, fused.
|
|
990
990
|
// Specializes conv2d_add to kernel=1 / stride=1 / pad=0 / no activation: drops
|
|
991
991
|
// the kernel loop, the padding checks, and the activation branch. Used by the
|
|
992
992
|
// MBConv project+residual tail. Both inputs share the same spatial resolution.
|
|
@@ -1620,7 +1620,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
1620
1620
|
let adapt_out = adapt_w[0] * down_out + adapt_b[0];
|
|
1621
1621
|
output_buf[y * p.out_w + x] = vec4<f16>(adapt_out.xyz, 0.0h);
|
|
1622
1622
|
}
|
|
1623
|
-
\`;var
|
|
1623
|
+
\`;var ve=class extends f{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?Qt:Yt;let u=w(e.h,3,n.stride,1),p=w(e.w,3,n.stride,1),l=k(1,e.h,u,3,n.stride),c=k(1,e.w,p,3,n.stride);this.output=r.tensor(u,p,4),this.inputs=[e],this.weights=[r.upload(d(o.weights)),r.upload(b(o.bias)),r.upload(d(a.weights)),r.upload(b(a.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,u,p,n.stride,l,c,0])),this.defaultSetup(),this.dispatch=[Math.ceil(p/8),Math.ceil(u/8),1]}};var Jt=\`// up_final: fused concat(u, rgb) \\u2192 conv 3\\xD73 5\\u21921 \\u2192 sigmoid (A/B alpha head).
|
|
1624
1624
|
// u = c_up=2 carrier (.xy); rgb = x_hr (.xyz). 5 inputs \\u2192 1 alpha (output .x).
|
|
1625
1625
|
// Weight: 18 vec4 \\u2014 [0..8] = (w0, w1, 0, 0) for u per kpos; [9..17] =
|
|
1626
1626
|
// (w2, w3, w4, 0) for rgb per kpos. Bias .x.
|
|
@@ -1688,7 +1688,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
1688
1688
|
|
|
1689
1689
|
output_buf[y * params.w + x] = vec4<f16>(1.0h / (1.0h + exp(-acc)), 0.0h, 0.0h, 0.0h);
|
|
1690
1690
|
}
|
|
1691
|
-
\`;var
|
|
1691
|
+
\`;var xe=class extends f{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader");this.shader=r.dtype==="f16"?Zt:Jt,this.output=r.tensor(e.h,e.w,4),this.inputs=[e,o],this.weights=[r.upload(d(a.weights)),r.upload(b(a.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1]}};var er=\`// up_final_skip: C/D alpha head. Fused concat(u, d_full, rgb) \\u2192 conv 3\\xD73 9\\u21921
|
|
1692
1692
|
// \\u2192 sigmoid. u = c_up=2 (.xy); d_full = c_high=4 full-res skip (full vec4);
|
|
1693
1693
|
// rgb = x_hr (.xyz). Channel order concat = 2 + 4 + 3 = 9. Output .x = alpha.
|
|
1694
1694
|
// Weight: 27 vec4 (3 per kpos): [kpos*3+0]=(w0,w1,0,0) u; [kpos*3+1]=(w2..w5)
|
|
@@ -2596,7 +2596,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2596
2596
|
let rgba = textureSampleBaseClampToEdge(src_tex, src_sampler, uv);
|
|
2597
2597
|
output_buf[y * params.out_w + x] = rgba;
|
|
2598
2598
|
}
|
|
2599
|
-
\`;var
|
|
2599
|
+
\`;var vr=\`enable f16;
|
|
2600
2600
|
|
|
2601
2601
|
// Input op \\u2014 texture_external + f16 storage. Sample in f32, store as f16.
|
|
2602
2602
|
|
|
@@ -2625,12 +2625,12 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
2625
2625
|
let rgba = textureSampleBaseClampToEdge(src_tex, src_sampler, uv);
|
|
2626
2626
|
output_buf[y * params.out_w + x] = vec4<f16>(rgba);
|
|
2627
2627
|
}
|
|
2628
|
-
\`;var
|
|
2628
|
+
\`;var yi=s=>typeof VideoFrame<"u"&&s instanceof VideoFrame,Be=class{constructor(t,r,e){i(this,"output");i(this,"device");i(this,"dtype");i(this,"sampler");i(this,"uniformBuffer");i(this,"dispatch");i(this,"pipeline2d",null);i(this,"pipelineExternal",null);i(this,"stagingTex",null);i(this,"stagingW",0);i(this,"stagingH",0);i(this,"source",null);this.device=t.device,this.dtype=t.dtype,this.output=t.tensor(r,e,4),this.sampler=this.device.createSampler({magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let o=new ArrayBuffer(16);new Uint32Array(o,0,2).set([e,r]),this.device.queue.writeBuffer(this.uniformBuffer,0,o),this.dispatch=[Math.ceil(e/8),Math.ceil(r/8),1],this.pipeline2d=this.buildPipeline(this.dtype==="f16"?_r:gr)}setSource(t){this.source=t}run(){if(!this.source)throw new Error("InputWebGPU.run() called before setSource()");yi(this.source)?this.runExternal(this.source):this.run2d(this.source)}run2d(t){this.ensureStagingTexture(t.width,t.height),this.device.queue.copyExternalImageToTexture({source:t,flipY:!1},{texture:this.stagingTex},[t.width,t.height]);let r=this.device.createBindGroup({layout:this.pipeline2d.getBindGroupLayout(0),entries:[{binding:0,resource:this.stagingTex.createView()},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipeline2d,r)}runExternal(t){this.pipelineExternal||(this.pipelineExternal=this.buildPipeline(this.dtype==="f16"?vr:br));let r=this.device.importExternalTexture({source:t}),e=this.device.createBindGroup({layout:this.pipelineExternal.getBindGroupLayout(0),entries:[{binding:0,resource:r},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipelineExternal,e)}ensureStagingTexture(t,r){this.stagingTex&&this.stagingW===t&&this.stagingH===r||(this.stagingTex?.destroy(),this.stagingTex=this.device.createTexture({size:[t,r,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.stagingW=t,this.stagingH=r)}buildPipeline(t){let r=this.device.createShaderModule({code:t});return this.device.createComputePipeline({layout:"auto",compute:{module:r,entryPoint:"main"}})}dispatchOnce(t,r){let e=this.device.createCommandEncoder(),o=e.beginComputePass();o.setPipeline(t),o.setBindGroup(0,r),o.dispatchWorkgroups(...this.dispatch),o.end(),this.device.queue.submit([e.finish()])}};var wi=navigator.gpu?GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST:0,D=class s{constructor(t,r,e){i(this,"device",t);i(this,"canvas",r);i(this,"dtype",e);i(this,"ops");i(this,"presenters");i(this,"canvasContext");i(this,"canvasFormat");i(this,"bytesPerElement");i(this,"contexts",new Map);this.bytesPerElement=e==="f16"?2:4;let o=r.getContext("webgpu");if(!o)throw new Error("Failed to get WebGPU context from canvas");this.canvasFormat=navigator.gpu.getPreferredCanvasFormat(),this.configureContext(o),this.canvasContext=o,this.contexts.set("main",o),this.ops={Conv2d:(a,n,u)=>new oe(this,a,n,u),DepthwiseConv2d:(a,n,u)=>new ie(this,a,n,u),Add:(a,n)=>new ae(this,a,n),Sigmoid:a=>new ne(this,a),Tanh:a=>new se(this,a),ElementwiseMul:(a,n)=>new ue(this,a,n),BilinearUpsample:(a,n)=>new pe(this,a,n),BicubicUpsample:(a,n)=>new le(this,a,n),ChannelConcat:(a,n)=>new ce(this,a,n),Conv2dAdd:(a,n,u,p)=>new de(this,a,n,u,p),ProjResidual:(a,n,u,p)=>new me(this,a,n,u,p),ConcatConv2d:(a,n,u,p)=>new fe(this,a,n,u,p),GatesFused:(a,n,u)=>new he(this,a,n,u),CandUpdateFused:(a,n,u,p,l)=>new ge(this,a,n,u,p,l),ConvExpand:(a,n)=>new _e(this,a,n),CatConv6to2:(a,n,u)=>new be(this,a,n,u),DownAdapter:(a,n,u,p)=>new ve(this,a,n,u,p),UpFinal:(a,n,u)=>new xe(this,a,n,u),UpFinalSkip:(a,n,u,p)=>new ye(this,a,n,u,p),UpsampleConcat:(a,n,u)=>new we(this,a,n,u),UpsampleConv1x1:(a,n,u)=>new ke(this,a,n,u),UpsampleSigmoid:(a,n)=>new Te(this,a,n),Input:(a,n)=>new Be(this,a,n)},this.presenters={CompositeSolid:(a,n,u,p="main")=>{let l=new Ce(this,a,n,u);return{run:()=>{l.setOutput(this.getCurrentDisplayTexture(p)),l.run()}}},CompositeImage:(a,n,u,p="main")=>{let l=new We(this,a,n,u);return{run:()=>{l.setOutput(this.getCurrentDisplayTexture(p)),l.run()}}},CompositeImageBilinear:(a,n,u,p="main")=>{let l=new Pe(this,a,n,u);return{run:()=>{l.setOutput(this.getCurrentDisplayTexture(p)),l.run()}}},CompositePassthrough:(a,n="main")=>{let u=new Ge(this,a);return{run:()=>{u.setOutput(this.getCurrentDisplayTexture(n)),u.run()}}}}}configureContext(t){t.configure({device:this.device,format:this.canvasFormat,alphaMode:"premultiplied"})}attachCanvas(t,r){if(t==="main")throw new Error("attachCanvas: 'main' is reserved for the create() canvas");let e=r.getContext("webgpu");if(!e)throw new Error(\`attachCanvas: failed to get WebGPU context for target '\${t}'\`);this.configureContext(e),this.contexts.set(t,e)}static async isAvailable(){return navigator.gpu?await navigator.gpu.requestAdapter()!==null:!1}static async hasF16Support(){if(!navigator.gpu)return!1;let t=await navigator.gpu.requestAdapter();return t?t.features.has("shader-f16"):!1}static async create(t){let r=t.dtype??"f32",e=t.device;if(e){if(r==="f16"&&!e.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but supplied device lacks \`shader-f16\`")}else{let o=await navigator.gpu.requestAdapter();if(!o)throw new Error("WebGPU adapter not available");if(r==="f16"&&!o.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but adapter lacks \`shader-f16\` feature");e=await o.requestDevice({requiredFeatures:r==="f16"?["shader-f16"]:[]})}return new s(e,t.canvas,r)}getCurrentDisplayTexture(t="main"){let r=this.contexts.get(t);if(!r)throw new Error(\`getCurrentDisplayTexture: no canvas attached for target '\${t}'\`);return r.getCurrentTexture()}tensor(t,r,e,o){let n=t*r*e*this.bytesPerElement,u=this.device.createBuffer({size:n,usage:wi,mappedAtCreation:o!==void 0});if(o!==void 0){let p=u.getMappedRange();this.writeView(p,o),u.unmap()}return{h:t,w:r,c:e,buffer:u}}upload(t){let e=t.length*this.bytesPerElement,o=this.device.createBuffer({size:e,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});return this.writeView(o.getMappedRange(),t),o.unmap(),{buffer:o}}writeView(t,r){let e=this.dtype==="f16",o=r instanceof Uint16Array;if(e===o){e?new Uint16Array(t).set(r):new Float32Array(t).set(r);return}e?new Uint16Array(t).set(re(r)):new Float32Array(t).set(I(r))}async readback(t){let r=this.device.createBuffer({size:t.buffer.size,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),e=this.device.createCommandEncoder();e.copyBufferToBuffer(t.buffer,0,r,0,t.buffer.size),this.device.queue.submit([e.finish()]),await r.mapAsync(GPUMapMode.READ);let o=r.getMappedRange(),a=this.dtype==="f16"?I(new Uint16Array(o.slice(0))):new Float32Array(o.slice(0));return r.unmap(),r.destroy(),a}copyTensor(t,r){if(t.buffer.size!==r.buffer.size)throw new Error(\`copyTensor: size mismatch (src \${t.buffer.size} vs dst \${r.buffer.size})\`);let e=this.device.createCommandEncoder();e.copyBufferToBuffer(t.buffer,0,r.buffer,0,t.buffer.size),this.device.queue.submit([e.finish()])}async sync(){await this.device.queue.onSubmittedWorkDone()}destroy(){this.device.destroy()}};var ki=\`#version 300 es
|
|
2629
2629
|
const vec2 VERTS[6] = vec2[6](
|
|
2630
2630
|
vec2(-1.0,-1.0), vec2(1.0,-1.0), vec2(-1.0,1.0),
|
|
2631
2631
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
2632
2632
|
);
|
|
2633
|
-
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,h=class{constructor(t){i(this,"backend",t);i(this,"shader","");i(this,"program");i(this,"samplers",[]);i(this,"uniformInts",{})}makeTexture(t,r,e){let o=this.backend.gl,a=this.backend.textureFormat,n=this.backend.toTextureView(t),u=o.createTexture();return o.bindTexture(o.TEXTURE_2D,u),o.texImage2D(o.TEXTURE_2D,0,a.internalFormat,r,e,0,a.format,a.type,n),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.NEAREST),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.NEAREST),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),u}defaultSetup(){let t=this.backend.gl,r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,
|
|
2633
|
+
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,h=class{constructor(t){i(this,"backend",t);i(this,"shader","");i(this,"program");i(this,"samplers",[]);i(this,"uniformInts",{})}makeTexture(t,r,e){let o=this.backend.gl,a=this.backend.textureFormat,n=this.backend.toTextureView(t),u=o.createTexture();return o.bindTexture(o.TEXTURE_2D,u),o.texImage2D(o.TEXTURE_2D,0,a.internalFormat,r,e,0,a.format,a.type,n),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.NEAREST),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.NEAREST),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),u}defaultSetup(){let t=this.backend.gl,r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,ki),t.compileShader(r);let e=t.createShader(t.FRAGMENT_SHADER);if(t.shaderSource(e,this.shader),t.compileShader(e),!t.getShaderParameter(e,t.COMPILE_STATUS))throw new Error(\`GLSL compile error: \${t.getShaderInfoLog(e)}\`);if(this.program=t.createProgram(),t.attachShader(this.program,r),t.attachShader(this.program,e),t.linkProgram(this.program),!t.getProgramParameter(this.program,t.LINK_STATUS))throw new Error(\`GLSL link error: \${t.getProgramInfoLog(this.program)}\`)}run(){let t=this.backend.gl;t.useProgram(this.program),this.samplers.forEach(({name:r,texture:e},o)=>{t.activeTexture(t.TEXTURE0+o),t.bindTexture(t.TEXTURE_2D,e),t.uniform1i(t.getUniformLocation(this.program,r),o)});for(let[r,e]of Object.entries(this.uniformInts))t.uniform1i(t.getUniformLocation(this.program,r),e);t.bindFramebuffer(t.FRAMEBUFFER,this.backend.fbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.output.texture,0),t.viewport(0,0,this.dispatch[0],this.dispatch[1]),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var xr=\`#version 300 es
|
|
2634
2634
|
// Conv2d \\u2014 handles all variants: 1\\xD71 (pointwise), 3\\xD73, 5\\xD75, strided, BN-fused.
|
|
2635
2635
|
//
|
|
2636
2636
|
// Tensor layout: NHWC vec4 \\u2014 texture dimensions (W * C/4, H).
|
|
@@ -2706,7 +2706,7 @@ void main() {
|
|
|
2706
2706
|
|
|
2707
2707
|
fragColor = result;
|
|
2708
2708
|
}
|
|
2709
|
-
\`;var Ue=class extends h{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",
|
|
2709
|
+
\`;var Ue=class extends h{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",xr);let n=w(e.h,a.kernel,a.stride,a.padding),u=w(e.w,a.kernel,a.stride,a.padding),p=e.c/4,l=a.outChannels/4,c=k(a.padding,e.h,n,a.kernel,a.stride),m=k(a.padding,e.w,u,a.kernel,a.stride),_=d(o.weights),g=d(o.bias),x=this.makeTexture(_,p*4,a.kernel*a.kernel*l),y=this.makeTexture(g,l,1),T=u*l,P=this.makeTexture(null,T,n);this.output={h:n,w:u,c:a.outChannels,texture:P,texW:T,texH:n},this.inputs=[e],this.weights=[],this.samplers=[{name:"u_input",texture:e.texture},{name:"u_weights",texture:x},{name:"u_bias",texture:y}],this.uniformInts={u_in_w:e.w,u_in_h:e.h,u_in_c_groups:p,u_out_c_groups:l,u_kernel_h:a.kernel,u_kernel_w:a.kernel,u_stride:a.stride,u_pad_top:c,u_pad_left:m,u_activation:a.activation==="relu6"?1:a.activation==="relu"?2:0},this.defaultSetup(),this.dispatch=[T,n]}};var yr=\`#version 300 es
|
|
2710
2710
|
// Depthwise Conv2d \\u2014 groups = in_channels (each channel convolved independently).
|
|
2711
2711
|
//
|
|
2712
2712
|
// Weight layout: (C_groups, K\\xB2) RGBA32F texture \\u2014 contrast with conv2d which uses mat4.
|
|
@@ -2763,7 +2763,7 @@ void main() {
|
|
|
2763
2763
|
|
|
2764
2764
|
fragColor = result;
|
|
2765
2765
|
}
|
|
2766
|
-
\`;var Se=class extends h{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",yr);let n=w(e.h,a.kernel,a.stride,a.padding),u=w(e.w,a.kernel,a.stride,a.padding),p=e.c/4,l=k(a.padding,e.h,n,a.kernel,a.stride),c=k(a.padding,e.w,u,a.kernel,a.stride),m=d(o.weights),_=d(o.bias),g=this.makeTexture(m,p,a.kernel*a.kernel),
|
|
2766
|
+
\`;var Se=class extends h{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",yr);let n=w(e.h,a.kernel,a.stride,a.padding),u=w(e.w,a.kernel,a.stride,a.padding),p=e.c/4,l=k(a.padding,e.h,n,a.kernel,a.stride),c=k(a.padding,e.w,u,a.kernel,a.stride),m=d(o.weights),_=d(o.bias),g=this.makeTexture(m,p,a.kernel*a.kernel),x=this.makeTexture(_,p,1),y=u*p,T=this.makeTexture(null,y,n);this.output={h:n,w:u,c:e.c,texture:T,texW:y,texH:n},this.inputs=[e],this.weights=[],this.samplers=[{name:"u_input",texture:e.texture},{name:"u_weights",texture:g},{name:"u_bias",texture:x}],this.uniformInts={u_in_w:e.w,u_in_h:e.h,u_c_groups:p,u_kernel_h:a.kernel,u_kernel_w:a.kernel,u_stride:a.stride,u_pad_top:l,u_pad_left:c,u_apply_relu6:a.activation==="relu6"?1:0},this.defaultSetup(),this.dispatch=[y,n]}};var wr=\`#version 300 es
|
|
2767
2767
|
// Element-wise add \\u2014 both inputs and output share the same texture dimensions.
|
|
2768
2768
|
// Works for any 2D layout; used here with a flat (nVec4, 1) texture.
|
|
2769
2769
|
|
|
@@ -2819,7 +2819,7 @@ void main() {
|
|
|
2819
2819
|
ivec2 fc = ivec2(gl_FragCoord.xy);
|
|
2820
2820
|
fragColor = texelFetch(u_input_a, fc, 0) * texelFetch(u_input_b, fc, 0);
|
|
2821
2821
|
}
|
|
2822
|
-
\`;var
|
|
2822
|
+
\`;var Oe=class extends h{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights",[]);i(this,"output");i(this,"dispatch");i(this,"shader",Cr);let a=e,n=this.makeTexture(null,a.texW,a.texH);this.output={h:e.h,w:e.w,c:e.c,texture:n,texW:a.texW,texH:a.texH},this.inputs=[e,o],this.samplers=[{name:"u_input_a",texture:e.texture},{name:"u_input_b",texture:o.texture}],this.defaultSetup(),this.dispatch=[a.texW,a.texH]}};var Wr=\`#version 300 es
|
|
2823
2823
|
// Bilinear upsample (arbitrary scale) \\u2014 align_corners=False.
|
|
2824
2824
|
//
|
|
2825
2825
|
// Hardware texture filtering can't be used: adjacent texels in x belong to
|
|
@@ -2870,7 +2870,7 @@ void main() {
|
|
|
2870
2870
|
|
|
2871
2871
|
fragColor = mix(mix(v00, v10, fx), mix(v01, v11, fx), fy);
|
|
2872
2872
|
}
|
|
2873
|
-
\`;var
|
|
2873
|
+
\`;var Ie=class extends h{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights",[]);i(this,"output");i(this,"dispatch");i(this,"shader",Wr);let a=e.c/4,n=o.outW*a,u=this.makeTexture(null,n,o.outH);this.output={h:o.outH,w:o.outW,c:e.c,texture:u,texW:n,texH:o.outH},this.inputs=[e],this.samplers=[{name:"u_input",texture:e.texture}],this.uniformInts={u_in_w:e.w,u_in_h:e.h,u_out_w:o.outW,u_out_h:o.outH,u_c_groups:a},this.defaultSetup(),this.dispatch=[n,o.outH]}};var Pr=\`#version 300 es
|
|
2874
2874
|
// Bicubic upsample (arbitrary scale) \\u2014 Keys cubic, a=-0.75 (PyTorch default
|
|
2875
2875
|
// for mode='bicubic', align_corners=False).
|
|
2876
2876
|
//
|
|
@@ -2930,7 +2930,7 @@ void main() {
|
|
|
2930
2930
|
}
|
|
2931
2931
|
fragColor = acc;
|
|
2932
2932
|
}
|
|
2933
|
-
\`;var
|
|
2933
|
+
\`;var De=class extends h{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights",[]);i(this,"output");i(this,"dispatch");i(this,"shader",Pr);let a=e.c/4,n=o.outW*a,u=this.makeTexture(null,n,o.outH);this.output={h:o.outH,w:o.outW,c:e.c,texture:u,texW:n,texH:o.outH},this.inputs=[e],this.samplers=[{name:"u_input",texture:e.texture}],this.uniformInts={u_in_w:e.w,u_in_h:e.h,u_out_w:o.outW,u_out_h:o.outH,u_c_groups:a},this.defaultSetup(),this.dispatch=[n,o.outH]}};var Gr=\`#version 300 es
|
|
2934
2934
|
// Channel concat \\u2014 concatenates two NHWC textures along the channel dimension.
|
|
2935
2935
|
// Both inputs must share the same spatial dimensions (W, H). Channel counts are
|
|
2936
2936
|
// multiples of 4 so each "group" is one vec4 texel.
|
|
@@ -3212,7 +3212,7 @@ void main() {
|
|
|
3212
3212
|
|
|
3213
3213
|
fragColor = result + texelFetch(u_skip, ivec2(fx, fy), 0);
|
|
3214
3214
|
}
|
|
3215
|
-
\`;var ze=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Lr);let u=w(e.h,n.kernel,n.stride,n.padding),p=w(e.w,n.kernel,n.stride,n.padding),l=e.c/4,c=n.outChannels/4,m=k(n.padding,e.h,u,n.kernel,n.stride),_=k(n.padding,e.w,p,n.kernel,n.stride),g=d(a.weights),
|
|
3215
|
+
\`;var ze=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Lr);let u=w(e.h,n.kernel,n.stride,n.padding),p=w(e.w,n.kernel,n.stride,n.padding),l=e.c/4,c=n.outChannels/4,m=k(n.padding,e.h,u,n.kernel,n.stride),_=k(n.padding,e.w,p,n.kernel,n.stride),g=d(a.weights),x=d(a.bias),y=this.makeTexture(g,l*4,n.kernel*n.kernel*c),T=this.makeTexture(x,c,1),P=p*c,z=this.makeTexture(null,P,u);this.output={h:u,w:p,c:n.outChannels,texture:z,texW:P,texH:u},this.inputs=[e,o],this.weights=[],this.samplers=[{name:"u_input",texture:e.texture},{name:"u_skip",texture:o.texture},{name:"u_weights",texture:y},{name:"u_bias",texture:T}],this.uniformInts={u_in_w:e.w,u_in_h:e.h,u_in_c_groups:l,u_out_c_groups:c,u_kernel_h:n.kernel,u_kernel_w:n.kernel,u_stride:n.stride,u_pad_top:m,u_pad_left:_,u_activation:n.activation==="relu6"?1:0},this.defaultSetup(),this.dispatch=[P,u]}};var Fr=\`#version 300 es
|
|
3216
3216
|
// proj_residual: bespoke 1\\xD71 conv (no activation) + residual add, fused.
|
|
3217
3217
|
// Specializes conv2d_add to kernel=1 / stride=1 / pad=0 / no activation. Both
|
|
3218
3218
|
// inputs share the same spatial resolution. See conv2d.glsl for the weight
|
|
@@ -3254,7 +3254,7 @@ void main() {
|
|
|
3254
3254
|
|
|
3255
3255
|
fragColor = result + texelFetch(u_skip, ivec2(fx, fy), 0);
|
|
3256
3256
|
}
|
|
3257
|
-
\`;var Ve=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Fr);let u=e.c/4,p=n.outChannels/4,l=d(a.weights),c=d(a.bias),m=this.makeTexture(l,u*4,p),_=this.makeTexture(c,p,1),g=e.w*p,
|
|
3257
|
+
\`;var Ve=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Fr);let u=e.c/4,p=n.outChannels/4,l=d(a.weights),c=d(a.bias),m=this.makeTexture(l,u*4,p),_=this.makeTexture(c,p,1),g=e.w*p,x=this.makeTexture(null,g,e.h);this.output={h:e.h,w:e.w,c:n.outChannels,texture:x,texW:g,texH:e.h},this.inputs=[e,o],this.weights=[],this.samplers=[{name:"u_input",texture:e.texture},{name:"u_skip",texture:o.texture},{name:"u_weights",texture:m},{name:"u_bias",texture:_}],this.uniformInts={u_in_c_groups:u,u_out_c_groups:p},this.defaultSetup(),this.dispatch=[g,e.h]}};var Er=\`#version 300 es
|
|
3258
3258
|
// concat_conv2d: fuses [concat(a, b) \\u2192 conv 3\\xD73 (pad 1) \\u2192 relu6] into one pass.
|
|
3259
3259
|
// Both inputs already at output resolution. Weight cols [0, a_groups) read a,
|
|
3260
3260
|
// [a_groups, I) read b. Weight texture layout matches conv2d.glsl
|
|
@@ -3315,7 +3315,7 @@ void main() {
|
|
|
3315
3315
|
|
|
3316
3316
|
fragColor = clamp(result, 0.0, 6.0);
|
|
3317
3317
|
}
|
|
3318
|
-
\`;var Ne=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Er);let u=e.c/4,p=o.c/4,l=u+p,c=n.outChannels/4,m=d(a.weights),_=d(a.bias),g=this.makeTexture(m,l*4,9*c),
|
|
3318
|
+
\`;var Ne=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Er);let u=e.c/4,p=o.c/4,l=u+p,c=n.outChannels/4,m=d(a.weights),_=d(a.bias),g=this.makeTexture(m,l*4,9*c),x=this.makeTexture(_,c,1),y=e.w*c,T=this.makeTexture(null,y,e.h);this.output={h:e.h,w:e.w,c:n.outChannels,texture:T,texW:y,texH:e.h},this.inputs=[e,o],this.weights=[],this.samplers=[{name:"u_a",texture:e.texture},{name:"u_b",texture:o.texture},{name:"u_weights",texture:g},{name:"u_bias",texture:x}],this.uniformInts={u_w:e.w,u_h:e.h,u_a_groups:u,u_b_groups:p,u_out_c_groups:c},this.defaultSetup(),this.dispatch=[y,e.h]}};var Or=\`#version 300 es
|
|
3319
3319
|
// gates_fused: ConvGRU z + r gates, fused. Production config (c_up=2,
|
|
3320
3320
|
// recurrent=1). u_in (.x=a, .y=b), h_prev (.x). weights 9 vec4 =
|
|
3321
3321
|
// (z_w_b, z_w_h, r_w_b, r_w_h) in a (9,1) texture. bias .xy. output (z, r, 0, 0).
|
|
@@ -3358,7 +3358,7 @@ void main() {
|
|
|
3358
3358
|
float r = 1.0 / (1.0 + exp(-r_pre));
|
|
3359
3359
|
fragColor = vec4(z, r, 0.0, 0.0);
|
|
3360
3360
|
}
|
|
3361
|
-
\`;var $e=class extends h{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",
|
|
3361
|
+
\`;var $e=class extends h{constructor(r,e,o,a){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Or);let n=this.makeTexture(d(a.weights),9,1),u=this.makeTexture(b(a.bias),1,1),p=e.w,l=this.makeTexture(null,p,e.h);this.output={h:e.h,w:e.w,c:4,texture:l,texW:p,texH:e.h},this.inputs=[e,o],this.weights=[],this.samplers=[{name:"u_u_in",texture:e.texture},{name:"u_h_prev",texture:o.texture},{name:"u_weights",texture:n},{name:"u_bias",texture:u}],this.uniformInts={u_w:e.w,u_h:e.h},this.defaultSetup(),this.dispatch=[p,e.h]}};var Ir=\`#version 300 es
|
|
3362
3362
|
// cand_update_fused: ConvGRU candidate + state update + output, fused.
|
|
3363
3363
|
// Production config (c_up=2, recurrent=1). u_in (.x=a, .y=b), h_prev (.x),
|
|
3364
3364
|
// gates_out (.x=z, .y=r). weights 9 vec4 (.xy = b_w, rh_w) in a (9,1) texture.
|
|
@@ -3406,7 +3406,7 @@ void main() {
|
|
|
3406
3406
|
float b_out = u_cur.y + gamma * h_new;
|
|
3407
3407
|
fragColor = vec4(u_cur.x, b_out, h_new, 0.0);
|
|
3408
3408
|
}
|
|
3409
|
-
\`;var Xe=class extends h{constructor(r,e,o,a,n,u){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",
|
|
3409
|
+
\`;var Xe=class extends h{constructor(r,e,o,a,n,u){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Ir);let p=this.makeTexture(d(n.weights),9,1),l=this.makeTexture(b(n.bias),1,1),c=this.makeTexture(b(u),1,1),m=e.w,_=this.makeTexture(null,m,e.h);this.output={h:e.h,w:e.w,c:4,texture:_,texW:m,texH:e.h},this.inputs=[e,o,a],this.weights=[],this.samplers=[{name:"u_u_in",texture:e.texture},{name:"u_h_prev",texture:o.texture},{name:"u_gates_out",texture:a.texture},{name:"u_weights",texture:p},{name:"u_bias",texture:l},{name:"u_gamma",texture:c}],this.uniformInts={u_w:e.w,u_h:e.h},this.defaultSetup(),this.dispatch=[m,e.h]}};var Dr=\`#version 300 es
|
|
3410
3410
|
// conv_expand: bespoke N\\u21922 conv 3\\xD73 (pad 1) + relu (wrapper expand_feat).
|
|
3411
3411
|
// Input N ch (in_groups vec4); output 2ch in .xy (.zw = 0). Weights: 9 *
|
|
3412
3412
|
// in_groups mat4x2 (8 floats each, col-major c0r0,c0r1,...,c3r0,c3r1) in a
|
|
@@ -3449,7 +3449,7 @@ void main() {
|
|
|
3449
3449
|
|
|
3450
3450
|
fragColor = vec4(max(result, vec2(0.0)), 0.0, 0.0); // expand_feat is F.relu
|
|
3451
3451
|
}
|
|
3452
|
-
\`;var je=class extends h{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",
|
|
3452
|
+
\`;var je=class extends h{constructor(r,e,o){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Dr);let a=e.c/4,n=this.makeTexture(d(o.weights),18*a,1),u=this.makeTexture(b(o.bias),1,1),p=e.w,l=this.makeTexture(null,p,e.h);this.output={h:e.h,w:e.w,c:4,texture:l,texW:p,texH:e.h},this.inputs=[e],this.weights=[],this.samplers=[{name:"u_input",texture:e.texture},{name:"u_weights",texture:n},{name:"u_bias",texture:u}],this.uniformInts={u_w:e.w,u_h:e.h,u_in_groups:a},this.defaultSetup(),this.dispatch=[p,e.h]}};var Ar=\`#version 300 es
|
|
3453
3453
|
// cat_conv_6to2: fused concat(u[2], d[4]) \\u2192 6\\u21922 conv 3\\xD73 (pad 1) + relu
|
|
3454
3454
|
// (E up1_combine). Channel order v3a=(u.x,u.y,d.x), v3b=d.yzw. weights = 9*2
|
|
3455
3455
|
// mat3x2 (6 floats each, col-major) in a 1-row (27-texel) texture.
|
|
@@ -3548,7 +3548,7 @@ void main() {
|
|
|
3548
3548
|
a.z = awf(2) * d.x + awf(6) * d.y + awf(10) * d.z + awf(14) * d.w + ab.z;
|
|
3549
3549
|
fragColor = vec4(a.xyz, 0.0);
|
|
3550
3550
|
}
|
|
3551
|
-
\`;var Ke=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Rr);let u=w(e.h,3,n.stride,1),p=w(e.w,3,n.stride,1),l=k(1,e.h,u,3,n.stride),c=this.makeTexture(d(o.weights),36,1),m=this.makeTexture(b(o.bias),1,1),_=this.makeTexture(d(a.weights),4,1),g=this.makeTexture(b(a.bias),1,1),
|
|
3551
|
+
\`;var Ke=class extends h{constructor(r,e,o,a,n){super(r);i(this,"inputs");i(this,"weights");i(this,"output");i(this,"dispatch");i(this,"shader",Rr);let u=w(e.h,3,n.stride,1),p=w(e.w,3,n.stride,1),l=k(1,e.h,u,3,n.stride),c=this.makeTexture(d(o.weights),36,1),m=this.makeTexture(b(o.bias),1,1),_=this.makeTexture(d(a.weights),4,1),g=this.makeTexture(b(a.bias),1,1),x=p,y=this.makeTexture(null,x,u);this.output={h:u,w:p,c:4,texture:y,texW:x,texH:u},this.inputs=[e],this.weights=[],this.samplers=[{name:"u_input",texture:e.texture},{name:"u_down_w",texture:c},{name:"u_down_b",texture:m},{name:"u_adapt_w",texture:_},{name:"u_adapt_b",texture:g}],this.uniformInts={u_in_w:e.w,u_in_h:e.h,u_stride:n.stride,u_pad:l},this.defaultSetup(),this.dispatch=[x,u]}};var Mr=\`#version 300 es
|
|
3552
3552
|
// up_final: cat(u[2], rgb[3]) \\u2192 conv 3\\xD73 5\\u21921 \\u2192 sigmoid (A/B alpha head).
|
|
3553
3553
|
// weights 18 vec4 (1-row): [kpos]=(w0,w1,0,0) for u, [9+kpos]=(w2,w3,w4,0) rgb.
|
|
3554
3554
|
|
|
@@ -3660,12 +3660,12 @@ void main() {
|
|
|
3660
3660
|
vec3 rgb = fg * a + u_bgColor * (1.0 - a);
|
|
3661
3661
|
fragColor = vec4(rgb, 1.0);
|
|
3662
3662
|
}
|
|
3663
|
-
\`;var
|
|
3663
|
+
\`;var ji=\`#version 300 es
|
|
3664
3664
|
const vec2 VERTS[6] = vec2[6](
|
|
3665
3665
|
vec2(-1.0,-1.0), vec2(1.0,-1.0), vec2(-1.0,1.0),
|
|
3666
3666
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
3667
3667
|
);
|
|
3668
|
-
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,Je=class{constructor(t,r,e,o){i(this,"backend",t);i(this,"program");i(this,"imageTex");i(this,"alphaTex");i(this,"bgColor");if(r.h!==e.h||r.w!==e.w)throw new Error(\`CompositeSolid: image (\${r.h}\\xD7\${r.w}) and alpha (\${e.h}\\xD7\${e.w}) must match. Run the upscaler first.\`);let a=r,n=e;this.imageTex=a.texture,this.alphaTex=n.texture,this.bgColor=o;let u=t.gl,p=u.createShader(u.VERTEX_SHADER);u.shaderSource(p,
|
|
3668
|
+
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,Je=class{constructor(t,r,e,o){i(this,"backend",t);i(this,"program");i(this,"imageTex");i(this,"alphaTex");i(this,"bgColor");if(r.h!==e.h||r.w!==e.w)throw new Error(\`CompositeSolid: image (\${r.h}\\xD7\${r.w}) and alpha (\${e.h}\\xD7\${e.w}) must match. Run the upscaler first.\`);let a=r,n=e;this.imageTex=a.texture,this.alphaTex=n.texture,this.bgColor=o;let u=t.gl,p=u.createShader(u.VERTEX_SHADER);u.shaderSource(p,ji),u.compileShader(p);let l=u.createShader(u.FRAGMENT_SHADER);if(u.shaderSource(l,zr),u.compileShader(l),!u.getShaderParameter(l,u.COMPILE_STATUS))throw new Error(\`composite_solid GLSL compile error: \${u.getShaderInfoLog(l)}\`);if(this.program=u.createProgram(),u.attachShader(this.program,p),u.attachShader(this.program,l),u.linkProgram(this.program),!u.getProgramParameter(this.program,u.LINK_STATUS))throw new Error(\`composite_solid GLSL link error: \${u.getProgramInfoLog(this.program)}\`)}run(){let t=this.backend.gl;t.useProgram(this.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.imageTex),t.uniform1i(t.getUniformLocation(this.program,"u_image"),0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.alphaTex),t.uniform1i(t.getUniformLocation(this.program,"u_alpha"),1),t.uniform3f(t.getUniformLocation(this.program,"u_bgColor"),this.bgColor[0],this.bgColor[1],this.bgColor[2]),this.backend.bindDisplayFramebuffer(),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var Vr=\`#version 300 es
|
|
3669
3669
|
// Same as composite_solid but bg is a texture (NHWC vec4 tensor) instead of
|
|
3670
3670
|
// a uniform color. Caller invariants: image, alpha, bg all share h \\xD7 w, and
|
|
3671
3671
|
// canvas dimensions match.
|
|
@@ -3691,12 +3691,12 @@ void main() {
|
|
|
3691
3691
|
vec3 rgb = fg * a + bg * (1.0 - a);
|
|
3692
3692
|
fragColor = vec4(rgb, 1.0);
|
|
3693
3693
|
}
|
|
3694
|
-
\`;var
|
|
3694
|
+
\`;var Ki=\`#version 300 es
|
|
3695
3695
|
const vec2 VERTS[6] = vec2[6](
|
|
3696
3696
|
vec2(-1.0,-1.0), vec2(1.0,-1.0), vec2(-1.0,1.0),
|
|
3697
3697
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
3698
3698
|
);
|
|
3699
|
-
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,Ze=class{constructor(t,r,e,o){i(this,"backend",t);i(this,"program");i(this,"imageTex");i(this,"alphaTex");i(this,"bgTex");if(r.h!==e.h||r.w!==e.w||r.h!==o.h||r.w!==o.w)throw new Error(\`CompositeImage: image (\${r.h}\\xD7\${r.w}), alpha (\${e.h}\\xD7\${e.w}), and bg (\${o.h}\\xD7\${o.w}) must all match. Run upscaler / resizer first.\`);this.imageTex=r.texture,this.alphaTex=e.texture,this.bgTex=o.texture;let a=t.gl,n=a.createShader(a.VERTEX_SHADER);a.shaderSource(n,
|
|
3699
|
+
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,Ze=class{constructor(t,r,e,o){i(this,"backend",t);i(this,"program");i(this,"imageTex");i(this,"alphaTex");i(this,"bgTex");if(r.h!==e.h||r.w!==e.w||r.h!==o.h||r.w!==o.w)throw new Error(\`CompositeImage: image (\${r.h}\\xD7\${r.w}), alpha (\${e.h}\\xD7\${e.w}), and bg (\${o.h}\\xD7\${o.w}) must all match. Run upscaler / resizer first.\`);this.imageTex=r.texture,this.alphaTex=e.texture,this.bgTex=o.texture;let a=t.gl,n=a.createShader(a.VERTEX_SHADER);a.shaderSource(n,Ki),a.compileShader(n);let u=a.createShader(a.FRAGMENT_SHADER);if(a.shaderSource(u,Vr),a.compileShader(u),!a.getShaderParameter(u,a.COMPILE_STATUS))throw new Error(\`composite_image GLSL compile error: \${a.getShaderInfoLog(u)}\`);if(this.program=a.createProgram(),a.attachShader(this.program,n),a.attachShader(this.program,u),a.linkProgram(this.program),!a.getProgramParameter(this.program,a.LINK_STATUS))throw new Error(\`composite_image GLSL link error: \${a.getProgramInfoLog(this.program)}\`)}run(){let t=this.backend.gl;t.useProgram(this.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.imageTex),t.uniform1i(t.getUniformLocation(this.program,"u_image"),0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.alphaTex),t.uniform1i(t.getUniformLocation(this.program,"u_alpha"),1),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,this.bgTex),t.uniform1i(t.getUniformLocation(this.program,"u_bg"),2),this.backend.bindDisplayFramebuffer(),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var Nr=\`#version 300 es
|
|
3700
3700
|
// Like composite_image but bg is bilinearly sampled \\u2014 bg is at a smaller
|
|
3701
3701
|
// resolution than (image, alpha) at canvas h \\xD7 w. Used by CompositorBlur to
|
|
3702
3702
|
// skip the final full-res upsample in the blur pyramid.
|
|
@@ -3745,12 +3745,12 @@ void main() {
|
|
|
3745
3745
|
vec3 rgb = fg * a + bg * (1.0 - a);
|
|
3746
3746
|
fragColor = vec4(rgb, 1.0);
|
|
3747
3747
|
}
|
|
3748
|
-
\`;var
|
|
3748
|
+
\`;var Qi=\`#version 300 es
|
|
3749
3749
|
const vec2 VERTS[6] = vec2[6](
|
|
3750
3750
|
vec2(-1.0,-1.0), vec2(1.0,-1.0), vec2(-1.0,1.0),
|
|
3751
3751
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
3752
3752
|
);
|
|
3753
|
-
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,et=class{constructor(t,r,e,o){i(this,"backend",t);i(this,"program");i(this,"imageTex");i(this,"alphaTex");i(this,"bgTex");i(this,"outW");i(this,"outH");i(this,"bgW");i(this,"bgH");if(r.h!==e.h||r.w!==e.w)throw new Error(\`CompositeImageBilinear: image (\${r.h}\\xD7\${r.w}) and alpha (\${e.h}\\xD7\${e.w}) must match.\`);this.imageTex=r.texture,this.alphaTex=e.texture,this.bgTex=o.texture,this.outW=r.w,this.outH=r.h,this.bgW=o.w,this.bgH=o.h;let a=t.gl,n=a.createShader(a.VERTEX_SHADER);a.shaderSource(n,
|
|
3753
|
+
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,et=class{constructor(t,r,e,o){i(this,"backend",t);i(this,"program");i(this,"imageTex");i(this,"alphaTex");i(this,"bgTex");i(this,"outW");i(this,"outH");i(this,"bgW");i(this,"bgH");if(r.h!==e.h||r.w!==e.w)throw new Error(\`CompositeImageBilinear: image (\${r.h}\\xD7\${r.w}) and alpha (\${e.h}\\xD7\${e.w}) must match.\`);this.imageTex=r.texture,this.alphaTex=e.texture,this.bgTex=o.texture,this.outW=r.w,this.outH=r.h,this.bgW=o.w,this.bgH=o.h;let a=t.gl,n=a.createShader(a.VERTEX_SHADER);a.shaderSource(n,Qi),a.compileShader(n);let u=a.createShader(a.FRAGMENT_SHADER);if(a.shaderSource(u,Nr),a.compileShader(u),!a.getShaderParameter(u,a.COMPILE_STATUS))throw new Error(\`composite_image_bilinear GLSL compile error: \${a.getShaderInfoLog(u)}\`);if(this.program=a.createProgram(),a.attachShader(this.program,n),a.attachShader(this.program,u),a.linkProgram(this.program),!a.getProgramParameter(this.program,a.LINK_STATUS))throw new Error(\`composite_image_bilinear GLSL link error: \${a.getProgramInfoLog(this.program)}\`)}run(){let t=this.backend.gl;t.useProgram(this.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.imageTex),t.uniform1i(t.getUniformLocation(this.program,"u_image"),0),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this.alphaTex),t.uniform1i(t.getUniformLocation(this.program,"u_alpha"),1),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,this.bgTex),t.uniform1i(t.getUniformLocation(this.program,"u_bg"),2),t.uniform1i(t.getUniformLocation(this.program,"u_out_w"),this.outW),t.uniform1i(t.getUniformLocation(this.program,"u_out_h"),this.outH),t.uniform1i(t.getUniformLocation(this.program,"u_bg_w"),this.bgW),t.uniform1i(t.getUniformLocation(this.program,"u_bg_h"),this.bgH),this.backend.bindDisplayFramebuffer(),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var $r=\`#version 300 es
|
|
3754
3754
|
// Passthrough "compositor": writes the image directly to the canvas
|
|
3755
3755
|
// (default framebuffer). No alpha math, no background. Used by RenderOp
|
|
3756
3756
|
// when the renderer is in disabled state.
|
|
@@ -3773,12 +3773,12 @@ void main() {
|
|
|
3773
3773
|
vec3 rgb = texelFetch(u_image, px, 0).rgb;
|
|
3774
3774
|
fragColor = vec4(rgb, 1.0);
|
|
3775
3775
|
}
|
|
3776
|
-
\`;var
|
|
3776
|
+
\`;var Zi=\`#version 300 es
|
|
3777
3777
|
const vec2 VERTS[6] = vec2[6](
|
|
3778
3778
|
vec2(-1.0,-1.0), vec2(1.0,-1.0), vec2(-1.0,1.0),
|
|
3779
3779
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
3780
3780
|
);
|
|
3781
|
-
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,tt=class{constructor(t,r){i(this,"backend",t);i(this,"program");i(this,"imageTex");this.imageTex=r.texture;let e=t.gl,o=e.createShader(e.VERTEX_SHADER);e.shaderSource(o,
|
|
3781
|
+
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,tt=class{constructor(t,r){i(this,"backend",t);i(this,"program");i(this,"imageTex");this.imageTex=r.texture;let e=t.gl,o=e.createShader(e.VERTEX_SHADER);e.shaderSource(o,Zi),e.compileShader(o);let a=e.createShader(e.FRAGMENT_SHADER);if(e.shaderSource(a,$r),e.compileShader(a),!e.getShaderParameter(a,e.COMPILE_STATUS))throw new Error(\`composite_passthrough GLSL compile error: \${e.getShaderInfoLog(a)}\`);if(this.program=e.createProgram(),e.attachShader(this.program,o),e.attachShader(this.program,a),e.linkProgram(this.program),!e.getProgramParameter(this.program,e.LINK_STATUS))throw new Error(\`composite_passthrough GLSL link error: \${e.getProgramInfoLog(this.program)}\`)}run(){let t=this.backend.gl;t.useProgram(this.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.imageTex),t.uniform1i(t.getUniformLocation(this.program,"u_image"),0),this.backend.bindDisplayFramebuffer(),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var Xr=\`#version 300 es
|
|
3782
3782
|
precision highp float;
|
|
3783
3783
|
|
|
3784
3784
|
// Input op \\u2014 bilinear-sample a source texture (RGBA8 unorm uploaded from an
|
|
@@ -3796,13 +3796,13 @@ void main() {
|
|
|
3796
3796
|
vec2 uv = (gl_FragCoord.xy + vec2(0.5)) / vec2(float(u_out_w), float(u_out_h));
|
|
3797
3797
|
fragColor = texture(u_src, uv);
|
|
3798
3798
|
}
|
|
3799
|
-
\`;var
|
|
3799
|
+
\`;var ta=\`#version 300 es
|
|
3800
3800
|
const vec2 VERTS[6] = vec2[6](
|
|
3801
3801
|
vec2(-1.0,-1.0), vec2(1.0,-1.0), vec2(-1.0,1.0),
|
|
3802
3802
|
vec2(-1.0,1.0), vec2(1.0,-1.0), vec2(1.0,1.0)
|
|
3803
3803
|
);
|
|
3804
|
-
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,rt=class{constructor(t,r,e){i(this,"backend",t);i(this,"output");i(this,"gl");i(this,"program");i(this,"srcTex");i(this,"uOutW");i(this,"uOutH");i(this,"uSrc");i(this,"source",null);let o=t.gl;this.gl=o,this.output=t.tensor(r,e,4),this.srcTex=o.createTexture(),o.bindTexture(o.TEXTURE_2D,this.srcTex),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE);let a=o.createShader(o.VERTEX_SHADER);o.shaderSource(a,Ji),o.compileShader(a);let n=o.createShader(o.FRAGMENT_SHADER);if(o.shaderSource(n,Xr),o.compileShader(n),!o.getShaderParameter(n,o.COMPILE_STATUS))throw new Error(\`Input GLSL compile error: \${o.getShaderInfoLog(n)}\`);if(this.program=o.createProgram(),o.attachShader(this.program,a),o.attachShader(this.program,n),o.linkProgram(this.program),!o.getProgramParameter(this.program,o.LINK_STATUS))throw new Error(\`Input GLSL link error: \${o.getProgramInfoLog(this.program)}\`);this.uSrc=o.getUniformLocation(this.program,"u_src"),this.uOutW=o.getUniformLocation(this.program,"u_out_w"),this.uOutH=o.getUniformLocation(this.program,"u_out_h")}setSource(t){this.source=t}run(){if(!this.source)throw new Error("InputWebGL.run() called before setSource()");let t=this.gl;t.bindTexture(t.TEXTURE_2D,this.srcTex),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.source),t.useProgram(this.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.srcTex),t.uniform1i(this.uSrc,0),t.uniform1i(this.uOutW,this.output.w),t.uniform1i(this.uOutH,this.output.h),t.bindFramebuffer(t.FRAMEBUFFER,this.backend.fbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.output.texture,0),t.viewport(0,0,this.output.texW,this.output.texH),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var L=class s{constructor(t,r,e){i(this,"gl",t);i(this,"canvas",r);i(this,"dtype",e);i(this,"ops");i(this,"presenters");i(this,"fbo");i(this,"textureFormat");this.fbo=t.createFramebuffer(),this.textureFormat=e==="f16"?{internalFormat:t.RGBA16F,format:t.RGBA,type:t.HALF_FLOAT,bytesPerElement:2}:{internalFormat:t.RGBA32F,format:t.RGBA,type:t.FLOAT,bytesPerElement:4},this.ops={Conv2d:(o,a,n)=>new Ue(this,o,a,n),DepthwiseConv2d:(o,a,n)=>new Se(this,o,a,n),Add:(o,a)=>new Le(this,o,a),Sigmoid:o=>new Fe(this,o),Tanh:o=>new Ee(this,o),ElementwiseMul:(o,a)=>new Ie(this,o,a),BilinearUpsample:(o,a)=>new De(this,o,a),BicubicUpsample:(o,a)=>new Oe(this,o,a),ChannelConcat:(o,a)=>new Ae(this,o,a),Conv2dAdd:(o,a,n,u)=>new ze(this,o,a,n,u),ProjResidual:(o,a,n,u)=>new Ve(this,o,a,n,u),ConcatConv2d:(o,a,n,u)=>new Ne(this,o,a,n,u),GatesFused:(o,a,n)=>new $e(this,o,a,n),CandUpdateFused:(o,a,n,u,p)=>new Xe(this,o,a,n,u,p),ConvExpand:(o,a)=>new je(this,o,a),CatConv6to2:(o,a,n)=>new qe(this,o,a,n),DownAdapter:(o,a,n,u)=>new Ke(this,o,a,n,u),UpFinal:(o,a,n)=>new Ye(this,o,a,n),UpFinalSkip:(o,a,n,u)=>new Qe(this,o,a,n,u),UpsampleConcat:(o,a,n)=>new Me(this,o,a,n),UpsampleConv1x1:(o,a,n)=>new He(this,o,a,n),UpsampleSigmoid:(o,a)=>new Re(this,o,a),Input:(o,a)=>new rt(this,o,a)},this.presenters={CompositeSolid:(o,a,n)=>new Je(this,o,a,n),CompositeImage:(o,a,n)=>new Ze(this,o,a,n),CompositeImageBilinear:(o,a,n)=>new et(this,o,a,n),CompositePassthrough:o=>new tt(this,o)}}static isAvailable(){let t=null;try{return t=new OffscreenCanvas(1,1).getContext("webgl2"),!(!t||!t.getExtension("EXT_color_buffer_float"))}catch{return!1}finally{t?.getExtension("WEBGL_lose_context")?.loseContext()}}static create(t){let r=t.canvas.getContext("webgl2");if(!r)throw new Error("WebGL2 not available");if(!r.getExtension("EXT_color_buffer_float"))throw new Error("EXT_color_buffer_float not available");return new s(r,t.canvas,t.dtype??"f32")}bindDisplayFramebuffer(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height)}toTextureView(t){if(t===null)return null;let r=this.dtype==="f16",e=t instanceof Uint16Array;return r===e?t:r?re(t):D(t)}tensor(t,r,e,o){let a=r*(e/4),n=t,u=this.gl,p=u.createTexture(),l=this.textureFormat,c=this.toTextureView(o??null);return u.bindTexture(u.TEXTURE_2D,p),u.texImage2D(u.TEXTURE_2D,0,l.internalFormat,a,n,0,l.format,l.type,c),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MIN_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MAG_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_S,u.CLAMP_TO_EDGE),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_T,u.CLAMP_TO_EDGE),{h:t,w:r,c:e,texture:p,texW:a,texH:n}}upload(t){return{data:t}}async readback(t){let r=this.gl,e=this.textureFormat;if(r.bindFramebuffer(r.FRAMEBUFFER,this.fbo),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,t.texture,0),this.dtype==="f16"){let a=new Uint16Array(t.texW*t.texH*4);return r.readPixels(0,0,t.texW,t.texH,e.format,r.HALF_FLOAT,a),r.bindFramebuffer(r.FRAMEBUFFER,null),D(a)}let o=new Float32Array(t.texW*t.texH*4);return r.readPixels(0,0,t.texW,t.texH,e.format,r.FLOAT,o),r.bindFramebuffer(r.FRAMEBUFFER,null),o}copyTensor(t,r){if(t.texW!==r.texW||t.texH!==r.texH)throw new Error(\`copyTensor: size mismatch (src \${t.texW}\\xD7\${t.texH} vs dst \${r.texW}\\xD7\${r.texH})\`);let e=this.gl;e.bindFramebuffer(e.FRAMEBUFFER,this.fbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.texture,0),e.bindTexture(e.TEXTURE_2D,r.texture),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t.texW,t.texH),e.bindFramebuffer(e.FRAMEBUFFER,null)}async sync(){let t=this.gl,r=t.fenceSync(t.SYNC_GPU_COMMANDS_COMPLETE,0);if(!r){t.finish();return}for(t.flush();;){let e=t.clientWaitSync(r,0,0);if(e===t.ALREADY_SIGNALED||e===t.CONDITION_SATISFIED){t.deleteSync(r);return}if(e===t.WAIT_FAILED)throw t.deleteSync(r),new Error("WebGLBackend.sync: clientWaitSync returned WAIT_FAILED");await new Promise(o=>setTimeout(o,1))}}destroy(){this.gl.deleteFramebuffer(this.fbo),this.gl.getExtension("WEBGL_lose_context")?.loseContext()}};var st=U("setup_backend");async function jr(s,t,r={}){let e=s.backend==="webgpu"||s.backend==="auto",o=!!s.outputCanvas,a=()=>s.outputCanvas??new OffscreenCanvas(t.w,t.h),n=null;if(e&&await O.isAvailable()){let p=s.dtype==="f16"&&!await O.hasF16Support()?"f32":s.dtype,l=a();try{let c=await O.create({canvas:l,dtype:p});return c.device.lost.then(m=>{m.reason!=="destroyed"&&r.onContextLost?.({message:\`WebGPU device lost: \${m.reason}\${m.message?" \\u2014 "+m.message:""}\`,source:"backend-lost",recoverable:!1,cause:m})}).catch(()=>{}),{backend:c,resolvedBackend:"webgpu",resolvedDtype:p,canvas:l}}catch(c){st.warn("WebGPU isAvailable but create() threw; trying WebGL fallback:",c),n=c,o&&st.warn("transfer-capture topology: WebGL fallback may also fail on the same canvas")}}if(L.isAvailable()){let p=a();try{let l=L.create({canvas:p,dtype:s.dtype});return p.addEventListener("webglcontextlost",c=>{r.onContextLost?.({message:"WebGL context lost",source:"backend-lost",recoverable:!1,cause:c})}),{backend:l,resolvedBackend:"webgl",resolvedDtype:s.dtype,canvas:p}}catch(l){st.warn("WebGL create() threw:",l),n=l}}let u=n?\` (last error: \${n.message??n})\`:"";throw new Error(\`setup_backend: no usable GPU backend\${u}\`)}var qr=.5,Zi=3,Kr=10,ea=30,F=U("autotune");async function Yr(s,t=ea){let r=s instanceof L?qr*.5:qr,e=1e3/t*r;F(\`start; budget per source frame: \${e.toFixed(1)}ms (source \${t}fps \\xD7 \${r} safety)\`),F("backend dtype:",s.dtype);let o=null;for(let a of at){if(!E[a.model]){F("skip",a.model,"(no TIER_CONFIG entry)");continue}try{let n=E[a.model].baseRes;F(\`bench \${a.model} base @ \${n.w}\\xD7\${n.h} skipFrames=\${a.skipFrames} \\u2026\`);let u=await oa(s,a),p=u<=e;if(F(\` \${a.model}: \${u.toFixed(1)}ms / source frame \${p?"\\u2713 within budget":"\\u2717 over budget"}\`),(p||o===null)&&(o=a),!p)break}catch(n){F(" bench failed for",a.model,":",n);break}}if(!o)throw new Error("autotune: no implementable preset available");return F("picked",o.model),o}function ta(s){let t=Object.create(s);return t.ops={...s.ops,Conv2d:(r,e,o)=>{let a={weights:new Float32Array(o.kernel*o.kernel*r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.Conv2d(r,a,o)},DepthwiseConv2d:(r,e,o)=>{let a={weights:new Float32Array(o.kernel*o.kernel*r.c),bias:new Float32Array(r.c)};return s.ops.DepthwiseConv2d(r,a,o)},Conv2dAdd:(r,e,o,a)=>{let n={weights:new Float32Array(a.kernel*a.kernel*r.c*a.outChannels),bias:new Float32Array(a.outChannels)};return s.ops.Conv2dAdd(r,e,n,a)},UpsampleConv1x1:(r,e,o)=>{let a={weights:new Float32Array(r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.UpsampleConv1x1(r,a,o)},ProjResidual:(r,e,o,a)=>{let n={weights:new Float32Array(r.c*a.outChannels),bias:new Float32Array(a.outChannels)};return s.ops.ProjResidual(r,e,n,a)},ConcatConv2d:(r,e,o,a)=>{let n={weights:new Float32Array(9*(r.c+e.c)*a.outChannels),bias:new Float32Array(a.outChannels)};return s.ops.ConcatConv2d(r,e,n,a)}},t}function ra(){let s=new Proxy({},{get:()=>s});return s}async function oa(s,t){let r=E[t.model];if(!r)throw new Error(\`microbench: no TIER_CONFIG entry for '\${t.model}'\`);let e=r.base,o=ta(s),a=o.tensor(r.baseRes.h,r.baseRes.w,4),n=new e(o,a,ra());for(let c=0;c<Zi;c++)n.run(),await s.sync();let u=t.skipFrames+1,p=performance.now();for(let c=0;c<Kr;c++)c%u===0&&n.run();return await s.sync(),(performance.now()-p)/Kr}async function Qr(s,t,r){let e;if(s==="auto")e=await Yr(r);else if(typeof s=="string"){let o=V(s);if(!o)throw new Error(\`resolve_preset: unknown preset name '\${s}'\`);e=o}else e=s;return e.dtype!==t?{...e,dtype:t}:e}function Jr(s){let t=null,r=null;return s.onmessage=e=>{let{frame:o}=e.data;if(r){let a=r;r=null,a(o)}else t&&t.close(),t=o},s.start?.(),new ReadableStream({pull(e){if(t){e.enqueue(t),t=null;return}return new Promise(o=>{r=a=>{e.enqueue(a),o()}})},cancel(){t&&(t.close(),t=null),s.close()}},{highWaterMark:0})}function Zr(s){switch(s.topology.input){case"mstp":if(!s.inputReadable)throw new Error("create_input: topology.input='mstp' but InitData.inputReadable missing");return s.inputReadable;case"rvfc-postmessage":if(!s.inputPort)throw new Error("create_input: topology.input='rvfc-postmessage' but InitData.inputPort missing");return Jr(s.inputPort)}}function eo(s){return new TransformStream({transform(t,r){s.process(t);let e=new VideoFrame(s.canvas,{timestamp:t.timestamp});t.close(),r.enqueue(e)}})}function to(s){return new WritableStream({write(t){s.process(t),t.close()}})}function ro(s,t){return new WritableStream({write(r){s.process(r),r.close();let e=s.canvas.transferToImageBitmap();t.postMessage({bmp:e},[e])},close(){t.close()}})}var ia=U("create_output");function oo(s,t,r){switch(s.topology.output){case"mstg":{if(!s.outputWritable)throw new Error("create_output: topology.output='mstg' but InitData.outputWritable missing");let e=eo(t);return e.readable.pipeTo(s.outputWritable,{signal:r}).catch(o=>{r.aborted||ia.warn("mstg downstream pipe failed:",o)}),e.writable}case"transfer-capture":return to(t);case"bitmap-shuttle":{if(!s.outputPort)throw new Error("create_output: topology.output='bitmap-shuttle' but InitData.outputPort missing");return ro(t,s.outputPort)}}}function io(s){if(!s.onFirstFrame)return s.input.pipeTo(s.output,{signal:s.signal});let t=!1,r=s.onFirstFrame,e=new TransformStream({transform(o,a){a.enqueue(o),t||(t=!0,queueMicrotask(r))}});return s.input.pipeThrough(e,{signal:s.signal}).pipeTo(s.output,{signal:s.signal})}var C=U("worker");C("script loaded");var B=null,A=null,ot=null;self.onmessage=async function(s){let{cmd:t,data:r,request_id:e}=s.data;C("cmd received:",t,"request_id:",e);try{let o=await aa(t,r);C("cmd ok:",t),ma(e,o)}catch(o){C("cmd FAILED:",t,o),H("error",{message:\`\${t} failed: \${o.message??String(o)}\`,source:"worker",recoverable:!1,cause:o})}};async function aa(s,t){switch(s){case"init":return na(t);case"startRender":return sa(t.weights);case"setBackground":return ua(t);case"setEnabled":return pa(t.enabled);case"setPreset":return la(t);case"getStats":return B?.getStats()??null;case"destroy":return ca();default:throw new Error(\`unknown cmd: \${s}\`)}}async function na(s){if(lt(!!s.debug),C("handleInit: start; topology=",s.topology,"preset=",s.preset,"backend=",s.backend,"dtype=",s.dtype),B)throw new Error("handleInit: already initialized");C("handleInit: setupBackend\\u2026");let t=await jr(s,s.canvasSize,{onContextLost:a=>{C("GPU context lost:",a.message),H("error",a)}});C("handleInit: backend ready:",t.resolvedBackend,t.resolvedDtype,"canvas:",t.canvas.width,"x",t.canvas.height),C("handleInit: constructing Renderer (boot mode)\\u2026"),B=new te({backend:t.backend,backendKind:t.resolvedBackend,canvas:t.canvas,background:s.background,enabled:s.enabled,topology:s.topology}),A=new AbortController,C("handleInit: createInputStream\\u2026");let r=Zr(s);C("handleInit: createOutputSink\\u2026");let e=oo(s,B,A.signal);C("handleInit: starting pipe (passthrough)\\u2026"),io({input:r,output:e,signal:A.signal}).then(()=>{C("pipe completed (input ended)")}).catch(a=>{if(A?.signal.aborted){C("pipe aborted (expected on destroy)");return}C("pipe FAILED:",a),H("error",{message:\`pipe failed: \${a.message}\`,source:"worker",recoverable:!1,cause:a})}),C("handleInit: resolvePreset\\u2026");let o=await Qr(s.preset,t.resolvedDtype,t.backend);return C("handleInit: preset resolved:",o),ot=o,C("handleInit: done; returning InitResponse, awaiting startRender"),{resolvedPreset:o,resolvedBackend:t.resolvedBackend,resolvedDtype:t.resolvedDtype}}async function sa(s){if(C("handleStartRender: start; weights bytes:",s.byteLength),!B||!ot)throw new Error("handleStartRender: handleInit not completed");C("handleStartRender: attaching network via setPreset\\u2026"),B.setPreset(ot,s),C("handleStartRender: ready (effect mode active)"),H("ready",void 0)}async function ua(s){B?.setBackground(s)}async function pa(s){B?.setEnabled(s)}async function la(s){if(!B)throw new Error("handleSetPreset: not initialized");if(!s.weights)throw new Error("handleSetPreset: weights required for runtime preset swap");if(s.preset==="auto")throw new Error("handleSetPreset: 'auto' not supported on runtime swap (use at init for autotune)");let t=typeof s.preset=="string"?V(s.preset)??da(s.preset):s.preset;return B.setPreset(t,s.weights),{resolvedPreset:t}}async function ca(){A?.abort(),A=null,B?.destroy(),B=null,ot=null}function da(s){throw new Error(\`handleSetPreset: unknown preset '\${s}'\`)}function ma(s,t){let r={request_id:s,res:t};self.postMessage(r)}function H(s,t){let r={request_id:s,res:t};self.postMessage(r)}function Eh(s){H("stats",s)}export{Eh as emitStats};
|
|
3805
|
-
`;var y=x("pipeline");function
|
|
3804
|
+
void main() { gl_Position = vec4(VERTS[gl_VertexID], 0.0, 1.0); }\`,rt=class{constructor(t,r,e){i(this,"backend",t);i(this,"output");i(this,"gl");i(this,"program");i(this,"srcTex");i(this,"uOutW");i(this,"uOutH");i(this,"uSrc");i(this,"source",null);let o=t.gl;this.gl=o,this.output=t.tensor(r,e,4),this.srcTex=o.createTexture(),o.bindTexture(o.TEXTURE_2D,this.srcTex),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.LINEAR),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE);let a=o.createShader(o.VERTEX_SHADER);o.shaderSource(a,ta),o.compileShader(a);let n=o.createShader(o.FRAGMENT_SHADER);if(o.shaderSource(n,Xr),o.compileShader(n),!o.getShaderParameter(n,o.COMPILE_STATUS))throw new Error(\`Input GLSL compile error: \${o.getShaderInfoLog(n)}\`);if(this.program=o.createProgram(),o.attachShader(this.program,a),o.attachShader(this.program,n),o.linkProgram(this.program),!o.getProgramParameter(this.program,o.LINK_STATUS))throw new Error(\`Input GLSL link error: \${o.getProgramInfoLog(this.program)}\`);this.uSrc=o.getUniformLocation(this.program,"u_src"),this.uOutW=o.getUniformLocation(this.program,"u_out_w"),this.uOutH=o.getUniformLocation(this.program,"u_out_h")}setSource(t){this.source=t}run(){if(!this.source)throw new Error("InputWebGL.run() called before setSource()");let t=this.gl;t.bindTexture(t.TEXTURE_2D,this.srcTex),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.source),t.useProgram(this.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.srcTex),t.uniform1i(this.uSrc,0),t.uniform1i(this.uOutW,this.output.w),t.uniform1i(this.uOutH,this.output.h),t.bindFramebuffer(t.FRAMEBUFFER,this.backend.fbo),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.output.texture,0),t.viewport(0,0,this.output.texW,this.output.texH),t.bindVertexArray(null),t.drawArrays(t.TRIANGLES,0,6)}};var L=class s{constructor(t,r,e){i(this,"gl",t);i(this,"canvas",r);i(this,"dtype",e);i(this,"ops");i(this,"presenters");i(this,"fbo");i(this,"textureFormat");this.fbo=t.createFramebuffer(),this.textureFormat=e==="f16"?{internalFormat:t.RGBA16F,format:t.RGBA,type:t.HALF_FLOAT,bytesPerElement:2}:{internalFormat:t.RGBA32F,format:t.RGBA,type:t.FLOAT,bytesPerElement:4},this.ops={Conv2d:(o,a,n)=>new Ue(this,o,a,n),DepthwiseConv2d:(o,a,n)=>new Se(this,o,a,n),Add:(o,a)=>new Le(this,o,a),Sigmoid:o=>new Fe(this,o),Tanh:o=>new Ee(this,o),ElementwiseMul:(o,a)=>new Oe(this,o,a),BilinearUpsample:(o,a)=>new Ie(this,o,a),BicubicUpsample:(o,a)=>new De(this,o,a),ChannelConcat:(o,a)=>new Ae(this,o,a),Conv2dAdd:(o,a,n,u)=>new ze(this,o,a,n,u),ProjResidual:(o,a,n,u)=>new Ve(this,o,a,n,u),ConcatConv2d:(o,a,n,u)=>new Ne(this,o,a,n,u),GatesFused:(o,a,n)=>new $e(this,o,a,n),CandUpdateFused:(o,a,n,u,p)=>new Xe(this,o,a,n,u,p),ConvExpand:(o,a)=>new je(this,o,a),CatConv6to2:(o,a,n)=>new qe(this,o,a,n),DownAdapter:(o,a,n,u)=>new Ke(this,o,a,n,u),UpFinal:(o,a,n)=>new Ye(this,o,a,n),UpFinalSkip:(o,a,n,u)=>new Qe(this,o,a,n,u),UpsampleConcat:(o,a,n)=>new Me(this,o,a,n),UpsampleConv1x1:(o,a,n)=>new He(this,o,a,n),UpsampleSigmoid:(o,a)=>new Re(this,o,a),Input:(o,a)=>new rt(this,o,a)},this.presenters={CompositeSolid:(o,a,n)=>new Je(this,o,a,n),CompositeImage:(o,a,n)=>new Ze(this,o,a,n),CompositeImageBilinear:(o,a,n)=>new et(this,o,a,n),CompositePassthrough:o=>new tt(this,o)}}static isAvailable(){let t=null;try{return t=new OffscreenCanvas(1,1).getContext("webgl2"),!(!t||!t.getExtension("EXT_color_buffer_float"))}catch{return!1}finally{t?.getExtension("WEBGL_lose_context")?.loseContext()}}static create(t){let r=t.canvas.getContext("webgl2");if(!r)throw new Error("WebGL2 not available");if(!r.getExtension("EXT_color_buffer_float"))throw new Error("EXT_color_buffer_float not available");return new s(r,t.canvas,t.dtype??"f32")}attachCanvas(t){throw new Error(\`WebGLBackend.attachCanvas('\${t}'): WebGL cannot render to a second canvas; use the renderer's snapshot-and-present path for preview output\`)}bindDisplayFramebuffer(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height)}toTextureView(t){if(t===null)return null;let r=this.dtype==="f16",e=t instanceof Uint16Array;return r===e?t:r?re(t):I(t)}tensor(t,r,e,o){let a=r*(e/4),n=t,u=this.gl,p=u.createTexture(),l=this.textureFormat,c=this.toTextureView(o??null);return u.bindTexture(u.TEXTURE_2D,p),u.texImage2D(u.TEXTURE_2D,0,l.internalFormat,a,n,0,l.format,l.type,c),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MIN_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_MAG_FILTER,u.NEAREST),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_S,u.CLAMP_TO_EDGE),u.texParameteri(u.TEXTURE_2D,u.TEXTURE_WRAP_T,u.CLAMP_TO_EDGE),{h:t,w:r,c:e,texture:p,texW:a,texH:n}}upload(t){return{data:t}}async readback(t){let r=this.gl,e=this.textureFormat;if(r.bindFramebuffer(r.FRAMEBUFFER,this.fbo),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,t.texture,0),this.dtype==="f16"){let a=new Uint16Array(t.texW*t.texH*4);return r.readPixels(0,0,t.texW,t.texH,e.format,r.HALF_FLOAT,a),r.bindFramebuffer(r.FRAMEBUFFER,null),I(a)}let o=new Float32Array(t.texW*t.texH*4);return r.readPixels(0,0,t.texW,t.texH,e.format,r.FLOAT,o),r.bindFramebuffer(r.FRAMEBUFFER,null),o}copyTensor(t,r){if(t.texW!==r.texW||t.texH!==r.texH)throw new Error(\`copyTensor: size mismatch (src \${t.texW}\\xD7\${t.texH} vs dst \${r.texW}\\xD7\${r.texH})\`);let e=this.gl;e.bindFramebuffer(e.FRAMEBUFFER,this.fbo),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.texture,0),e.bindTexture(e.TEXTURE_2D,r.texture),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t.texW,t.texH),e.bindFramebuffer(e.FRAMEBUFFER,null)}async sync(){let t=this.gl,r=t.fenceSync(t.SYNC_GPU_COMMANDS_COMPLETE,0);if(!r){t.finish();return}for(t.flush();;){let e=t.clientWaitSync(r,0,0);if(e===t.ALREADY_SIGNALED||e===t.CONDITION_SATISFIED){t.deleteSync(r);return}if(e===t.WAIT_FAILED)throw t.deleteSync(r),new Error("WebGLBackend.sync: clientWaitSync returned WAIT_FAILED");await new Promise(o=>setTimeout(o,1))}}destroy(){this.gl.deleteFramebuffer(this.fbo),this.gl.getExtension("WEBGL_lose_context")?.loseContext()}};var st=U("setup_backend");async function jr(s,t,r={}){let e=s.backend==="webgpu"||s.backend==="auto",o=!!s.outputCanvas,a=()=>s.outputCanvas??new OffscreenCanvas(t.w,t.h),n=null;if(e&&await D.isAvailable()){let p=s.dtype==="f16"&&!await D.hasF16Support()?"f32":s.dtype,l=a();try{let c=await D.create({canvas:l,dtype:p});return c.device.lost.then(m=>{m.reason!=="destroyed"&&r.onContextLost?.({message:\`WebGPU device lost: \${m.reason}\${m.message?" \\u2014 "+m.message:""}\`,source:"backend-lost",recoverable:!1,cause:m})}).catch(()=>{}),{backend:c,resolvedBackend:"webgpu",resolvedDtype:p,canvas:l}}catch(c){st.warn("WebGPU isAvailable but create() threw; trying WebGL fallback:",c),n=c,o&&st.warn("transfer-capture topology: WebGL fallback may also fail on the same canvas")}}if(L.isAvailable()){let p=a();try{let l=L.create({canvas:p,dtype:s.dtype});return p.addEventListener("webglcontextlost",c=>{r.onContextLost?.({message:"WebGL context lost",source:"backend-lost",recoverable:!1,cause:c})}),{backend:l,resolvedBackend:"webgl",resolvedDtype:s.dtype,canvas:p}}catch(l){st.warn("WebGL create() threw:",l),n=l}}let u=n?\` (last error: \${n.message??n})\`:"";throw new Error(\`setup_backend: no usable GPU backend\${u}\`)}var qr=.5,ra=3,Kr=10,oa=30,F=U("autotune");async function Yr(s,t=oa){let r=s instanceof L?qr*.5:qr,e=1e3/t*r;F(\`start; budget per source frame: \${e.toFixed(1)}ms (source \${t}fps \\xD7 \${r} safety)\`),F("backend dtype:",s.dtype);let o=null;for(let a of at){if(!E[a.model]){F("skip",a.model,"(no TIER_CONFIG entry)");continue}try{let n=E[a.model].baseRes;F(\`bench \${a.model} base @ \${n.w}\\xD7\${n.h} skipFrames=\${a.skipFrames} \\u2026\`);let u=await na(s,a),p=u<=e;if(F(\` \${a.model}: \${u.toFixed(1)}ms / source frame \${p?"\\u2713 within budget":"\\u2717 over budget"}\`),(p||o===null)&&(o=a),!p)break}catch(n){F(" bench failed for",a.model,":",n);break}}if(!o)throw new Error("autotune: no implementable preset available");return F("picked",o.model),o}function ia(s){let t=Object.create(s);return t.ops={...s.ops,Conv2d:(r,e,o)=>{let a={weights:new Float32Array(o.kernel*o.kernel*r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.Conv2d(r,a,o)},DepthwiseConv2d:(r,e,o)=>{let a={weights:new Float32Array(o.kernel*o.kernel*r.c),bias:new Float32Array(r.c)};return s.ops.DepthwiseConv2d(r,a,o)},Conv2dAdd:(r,e,o,a)=>{let n={weights:new Float32Array(a.kernel*a.kernel*r.c*a.outChannels),bias:new Float32Array(a.outChannels)};return s.ops.Conv2dAdd(r,e,n,a)},UpsampleConv1x1:(r,e,o)=>{let a={weights:new Float32Array(r.c*o.outChannels),bias:new Float32Array(o.outChannels)};return s.ops.UpsampleConv1x1(r,a,o)},ProjResidual:(r,e,o,a)=>{let n={weights:new Float32Array(r.c*a.outChannels),bias:new Float32Array(a.outChannels)};return s.ops.ProjResidual(r,e,n,a)},ConcatConv2d:(r,e,o,a)=>{let n={weights:new Float32Array(9*(r.c+e.c)*a.outChannels),bias:new Float32Array(a.outChannels)};return s.ops.ConcatConv2d(r,e,n,a)}},t}function aa(){let s=new Proxy({},{get:()=>s});return s}async function na(s,t){let r=E[t.model];if(!r)throw new Error(\`microbench: no TIER_CONFIG entry for '\${t.model}'\`);let e=r.base,o=ia(s),a=o.tensor(r.baseRes.h,r.baseRes.w,4),n=new e(o,a,aa());for(let c=0;c<ra;c++)n.run(),await s.sync();let u=t.skipFrames+1,p=performance.now();for(let c=0;c<Kr;c++)c%u===0&&n.run();return await s.sync(),(performance.now()-p)/Kr}async function Qr(s,t,r){let e;if(s==="auto")e=await Yr(r);else if(typeof s=="string"){let o=V(s);if(!o)throw new Error(\`resolve_preset: unknown preset name '\${s}'\`);e=o}else e=s;return e.dtype!==t?{...e,dtype:t}:e}function Jr(s){let t=null,r=null;return s.onmessage=e=>{let{frame:o}=e.data;if(r){let a=r;r=null,a(o)}else t&&t.close(),t=o},s.start?.(),new ReadableStream({pull(e){if(t){e.enqueue(t),t=null;return}return new Promise(o=>{r=a=>{e.enqueue(a),o()}})},cancel(){t&&(t.close(),t=null),s.close()}},{highWaterMark:0})}function Zr(s){switch(s.topology.input){case"mstp":if(!s.inputReadable)throw new Error("create_input: topology.input='mstp' but InitData.inputReadable missing");return s.inputReadable;case"rvfc-postmessage":if(!s.inputPort)throw new Error("create_input: topology.input='rvfc-postmessage' but InitData.inputPort missing");return Jr(s.inputPort)}}function eo(s){return new TransformStream({transform(t,r){s.process(t);let e=new VideoFrame(s.canvas,{timestamp:t.timestamp});t.close(),r.enqueue(e)}})}function to(s){return new WritableStream({write(t){s.process(t),t.close()}})}function ro(s,t){return new WritableStream({write(r){s.process(r),r.close();let e=s.canvas.transferToImageBitmap();t.postMessage({bmp:e},[e])},close(){t.close()}})}var sa=U("create_output");function oo(s,t,r){switch(s.topology.output){case"mstg":{if(!s.outputWritable)throw new Error("create_output: topology.output='mstg' but InitData.outputWritable missing");let e=eo(t);return e.readable.pipeTo(s.outputWritable,{signal:r}).catch(o=>{r.aborted||sa.warn("mstg downstream pipe failed:",o)}),e.writable}case"transfer-capture":return to(t);case"bitmap-shuttle":{if(!s.outputPort)throw new Error("create_output: topology.output='bitmap-shuttle' but InitData.outputPort missing");return ro(t,s.outputPort)}}}function io(s){if(!s.onFirstFrame)return s.input.pipeTo(s.output,{signal:s.signal});let t=!1,r=s.onFirstFrame,e=new TransformStream({transform(o,a){a.enqueue(o),t||(t=!0,queueMicrotask(r))}});return s.input.pipeThrough(e,{signal:s.signal}).pipeTo(s.output,{signal:s.signal})}var C=U("worker");C("script loaded");var W=null,A=null,ot=null;self.onmessage=async function(s){let{cmd:t,data:r,request_id:e}=s.data;C("cmd received:",t,"request_id:",e);try{let o=await ua(t,r);C("cmd ok:",t),va(e,o)}catch(o){C("cmd FAILED:",t,o),H("error",{message:\`\${t} failed: \${o.message??String(o)}\`,source:"worker",recoverable:!1,cause:o})}};async function ua(s,t){switch(s){case"init":return pa(t);case"startRender":return la(t.weights);case"setBackground":return ca(t);case"setEnabled":return da(t.enabled);case"setPreset":return ga(t);case"getStats":return W?.getStats()??null;case"destroy":return _a();case"attachPreview":return ma(t);case"setPreview":return fa(t);case"clearPreview":return ha();default:throw new Error(\`unknown cmd: \${s}\`)}}async function pa(s){if(lt(!!s.debug),C("handleInit: start; topology=",s.topology,"preset=",s.preset,"backend=",s.backend,"dtype=",s.dtype),W)throw new Error("handleInit: already initialized");C("handleInit: setupBackend\\u2026");let t=await jr(s,s.canvasSize,{onContextLost:a=>{C("GPU context lost:",a.message),H("error",a)}});C("handleInit: backend ready:",t.resolvedBackend,t.resolvedDtype,"canvas:",t.canvas.width,"x",t.canvas.height),C("handleInit: constructing Renderer (boot mode)\\u2026"),W=new te({backend:t.backend,backendKind:t.resolvedBackend,canvas:t.canvas,background:s.background,enabled:s.enabled,topology:s.topology}),A=new AbortController,C("handleInit: createInputStream\\u2026");let r=Zr(s);C("handleInit: createOutputSink\\u2026");let e=oo(s,W,A.signal);C("handleInit: starting pipe (passthrough)\\u2026"),io({input:r,output:e,signal:A.signal}).then(()=>{C("pipe completed (input ended)")}).catch(a=>{if(A?.signal.aborted){C("pipe aborted (expected on destroy)");return}C("pipe FAILED:",a),H("error",{message:\`pipe failed: \${a.message}\`,source:"worker",recoverable:!1,cause:a})}),C("handleInit: resolvePreset\\u2026");let o=await Qr(s.preset,t.resolvedDtype,t.backend);return C("handleInit: preset resolved:",o),ot=o,C("handleInit: done; returning InitResponse, awaiting startRender"),{resolvedPreset:o,resolvedBackend:t.resolvedBackend,resolvedDtype:t.resolvedDtype}}async function la(s){if(C("handleStartRender: start; weights bytes:",s.byteLength),!W||!ot)throw new Error("handleStartRender: handleInit not completed");C("handleStartRender: attaching network via setPreset\\u2026"),W.setPreset(ot,s),C("handleStartRender: ready (effect mode active)"),H("ready",void 0)}async function ca(s){W?.setBackground(s)}async function da(s){W?.setEnabled(s)}async function ma(s){if(!W)throw new Error("handleAttachPreview: not initialized");W.attachPreview(s.canvas)}async function fa(s){if(!W)throw new Error("handleSetPreview: not initialized");W.setPreview(s.background,s.fps!==void 0?{fps:s.fps}:void 0)}async function ha(){W?.clearPreview()}async function ga(s){if(!W)throw new Error("handleSetPreset: not initialized");if(!s.weights)throw new Error("handleSetPreset: weights required for runtime preset swap");if(s.preset==="auto")throw new Error("handleSetPreset: 'auto' not supported on runtime swap (use at init for autotune)");let t=typeof s.preset=="string"?V(s.preset)??ba(s.preset):s.preset;return W.setPreset(t,s.weights),{resolvedPreset:t}}async function _a(){A?.abort(),A=null,W?.destroy(),W=null,ot=null}function ba(s){throw new Error(\`handleSetPreset: unknown preset '\${s}'\`)}function va(s,t){let r={request_id:s,res:t};self.postMessage(r)}function H(s,t){let r={request_id:s,res:t};self.postMessage(r)}function Mh(s){H("stats",s)}export{Mh as emitStats};
|
|
3805
|
+
`;var y=x("pipeline");function Qt(){{let a=new Blob([he],{type:"application/javascript"}),t=URL.createObjectURL(a),e=new Worker(t,{type:"module"});return URL.revokeObjectURL(t),e}}var Jt="https://cdn.longpipe.dev/models/v/0.0.2/",Zt={background:"blur",preset:"auto",weightsBaseUrl:Jt,audio:"passthrough",enabled:true,adaptive:true,debug:false},Ge={w:1280,h:720};function er(a,t){if(t)return t;let r=a.getVideoTracks()[0]?.getSettings()??{};return {w:r.width||Ge.w,h:r.height||Ge.h}}function Ee(a,t){return `${a.replace(/\/$/,"")}/model_${t}.bin`}var fe=class{stream;ready;controller;worker;inputCleanup;outputCleanup;adaptive=null;bgCleanup=null;previewBgCleanup=null;constructor(t,e){let r={...Zt,...e};me(r.debug);let n=ye(),i=Ue(n.input,t),o=er(t,r.outputResolution),u=Se(n.output,o);this.inputCleanup=i.cleanup,this.outputCleanup=u.cleanup,this.stream=ke(u.videoTrack,t,r.audio),u.startPassthrough?.(t),this.worker=Qt(),this.controller=new O(this.worker),this.ready=new Promise((c,h)=>{this.controller.addPersistentListener("ready",()=>{y("ready handler invoked; resolving .ready"),r.onReady?.(),c();}),this.controller.addPersistentListener("error",f=>{console.error(`[longpipe/pipeline] error (${f.source}):`,f.message),f.recoverable||h(new Error(f.message)),r.onError?.(f);});});let s={topology:n,preset:r.preset,enabled:r.enabled,backend:"auto",dtype:"f16",canvasSize:o,debug:r.debug,...i.initFields,...u.initFields},l=[...i.transferList,...u.transferList];this.bootstrap(s,r.background,l,r.weightsBaseUrl,r.adaptive,r.onError);}async bootstrap(t,e,r,n,i,o){try{y("normalizing background\u2026");let u=await E(e);this.bgCleanup=u.cleanup??null;let s={...t,background:u.background},l=[...r,...u.transferList??[]];y("sending init\u2026");let c=await this.controller.sendMessage("init",s,l);y("init resolved:",c);let h=Ee(n,c.resolvedPreset.model);y("fetching weights:",h);let f=await fetch(h);if(!f.ok)throw new Error(`weights fetch failed: ${f.status} ${h}`);let v=await f.arrayBuffer();y("weights bytes:",v.byteLength),y("sending startRender\u2026"),await this.controller.sendMessage("startRender",{weights:v},[v]),y("startRender resolved; awaiting first frame"),s.preset==="auto"&&i&&(this.adaptive=new G({backendKind:c.resolvedBackend,initialModel:c.resolvedPreset.model,weightsBaseUrl:n,buildWeightsUrl:Ee,getStats:()=>this.getStats(),swapPreset:async(I,le)=>{await this.controller.sendMessage("setPreset",{preset:I,weights:le},[le]);},onError:o}),this.adaptive.start());}catch(u){console.error("[longpipe/pipeline] bootstrap failed:",u),this.controller.handleMessage.call(this.controller,{data:{request_id:"error",res:{message:u.message??String(u),source:"worker",recoverable:false,cause:u}}});}}then(t,e){return this.ready.then(()=>t?t(this):this,e)}async setBackground(t){let e=await E(t),r=this.bgCleanup;this.bgCleanup=e.cleanup??null,await this.controller.sendMessage("setBackground",e.background,e.transferList),r?.();}setPreset(t,e){this.controller.sendMessage("setPreset",{preset:t,weights:e});}attachPreview(t){let e=t.transferControlToOffscreen();this.controller.sendMessage("attachPreview",{canvas:e},[e]);}async setPreview(t){let e=await E(t.background),r=this.previewBgCleanup;this.previewBgCleanup=e.cleanup??null,await this.controller.sendMessage("setPreview",{background:e.background,fps:t.fps},e.transferList),r?.();}clearPreview(){this.controller.sendMessage("clearPreview",{}),this.previewBgCleanup?.(),this.previewBgCleanup=null;}setEnabled(t){this.controller.sendMessage("setEnabled",{enabled:t});}async getStats(){return this.controller.sendMessage("getStats",{})}destroy(){this.adaptive?.stop(),this.adaptive=null,this.bgCleanup?.(),this.bgCleanup=null,this.previewBgCleanup?.(),this.previewBgCleanup=null,this.controller.sendMessage("destroy",{}),this.controller.terminate(),this.inputCleanup(),this.outputCleanup();}};var T=new Float32Array(1),U=new Uint32Array(T.buffer);function tr(a){T[0]=a;let t=U[0],e=t>>>16&32768,r=t&2147483647,n=(r>>>23)-127+15;if((t&2139095040)===2139095040)return (t&8388607)!==0?e|32256:e|31744;if(n>=31)return e|31744;if(n<=0){if(n<-10)return e;let l=r&8388607|8388608,c=14-n,h=l>>>c,f=l>>>c-1&1,v=(l&(1<<c-1)-1)!==0?1:0;return f&&(v||h&1)&&(h+=1),e|h}let i=r>>>13&1023,o=r>>>12&1,u=(r&4095)!==0?1:0,s=n<<10|i;return o&&(u||i&1)&&(s+=1,(s>>>10&31)===31)?e|31744:e|s}function rr(a){let t=(a&32768)<<16,e=(a&31744)>>>10,r=a&1023;if(e===0){if(r===0)return U[0]=t,T[0];let n=r,i=1;for(;(n&1024)===0;)n<<=1,i-=1;return n&=1023,U[0]=t|i+127-15<<23|n<<13,T[0]}return e===31?(U[0]=t|2139095040|r<<13,T[0]):(U[0]=t|e+127-15<<23|r<<13,T[0])}function Fe(a){let t=new Uint16Array(a.length);for(let e=0;e<a.length;e++)t[e]=tr(a[e]);return t}function ge(a){let t=new Float32Array(a.length);for(let e=0;e<a.length;e++)t[e]=rr(a[e]);return t}var p=class{constructor(t){this.backend=t;}backend;shader="";pipeline;bindGroup;uniformDefs=[];uniformBuffers={};createUniform(t,e){this.uniformDefs.push({name:t,type:e});}setUniform(t,e){let r=this.backend.device.createBuffer({size:e.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:true});e instanceof Uint32Array?new Uint32Array(r.getMappedRange()).set(e):new Float32Array(r.getMappedRange()).set(e),r.unmap(),this.uniformBuffers[t]=r;}defaultBindGroup(){let t=[],e=0;for(let r of this.inputs)t.push({binding:e++,resource:{buffer:r.buffer}});for(let r of this.weights)t.push({binding:e++,resource:{buffer:r.buffer}});for(let r of this.uniformDefs)t.push({binding:e++,resource:{buffer:this.uniformBuffers[r.name]}});return t.push({binding:e,resource:{buffer:this.output.buffer}}),this.backend.device.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:t})}defaultSetup(){let t=this.backend.device.createShaderModule({code:this.shader});this.pipeline=this.backend.device.createComputePipeline({layout:"auto",compute:{module:t,entryPoint:"main"}}),this.bindGroup=this.defaultBindGroup();}run(){let t=this.backend.device.createCommandEncoder(),e=t.beginComputePass();e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.dispatchWorkgroups(...this.dispatch),e.end(),this.backend.device.queue.submit([t.finish()]);}};var Ae=`// Conv2d, output-channel-blocked (K=4) \u2014 drop-in replacement for conv2d.wgsl.
|
|
3806
3806
|
//
|
|
3807
3807
|
// Identical math, layout, and output to conv2d.wgsl, but each thread computes 4
|
|
3808
3808
|
// output channel-groups (16 channels) for one pixel, loading each input vec4
|
|
@@ -3902,7 +3902,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3902
3902
|
if (has2) { output_buf[baseO + o2] = act(acc2, params.activation); }
|
|
3903
3903
|
if (has3) { output_buf[baseO + o3] = act(acc3, params.activation); }
|
|
3904
3904
|
}
|
|
3905
|
-
`;var
|
|
3905
|
+
`;var Oe=`enable f16;
|
|
3906
3906
|
|
|
3907
3907
|
// Conv2d, output-channel-blocked (K=4) \u2014 full f16. Drop-in replacement for
|
|
3908
3908
|
// conv2d_f16.wgsl. Each thread computes 4 output channel-groups for one pixel,
|
|
@@ -3994,7 +3994,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
3994
3994
|
if (has2) { output_buf[baseO + o2] = act(acc2, params.activation); }
|
|
3995
3995
|
if (has3) { output_buf[baseO + o3] = act(acc3, params.activation); }
|
|
3996
3996
|
}
|
|
3997
|
-
`;function _(a,t,e,r){return typeof r=="number"?Math.floor((a+2*r-t)/e)+1:r==="same"?Math.ceil(a/e):Math.floor((a-t)/e)+1}function ir(a,t,e,r){return Math.floor(Math.max((t-1)*r+e-a,0)/2)}function m(a,t,e,r,n){return typeof a=="number"?a:a==="same"?ir(t,e,r,n):0}function
|
|
3997
|
+
`;function _(a,t,e,r){return typeof r=="number"?Math.floor((a+2*r-t)/e)+1:r==="same"?Math.ceil(a/e):Math.floor((a-t)/e)+1}function ir(a,t,e,r){return Math.floor(Math.max((t-1)*r+e-a,0)/2)}function m(a,t,e,r,n){return typeof a=="number"?a:a==="same"?ir(t,e,r,n):0}function d(a){return a instanceof Float32Array||a instanceof Uint16Array?a:new Float32Array(a)}function g(a){let t=Math.max(4,Math.ceil(a.length/4)*4),e=new Float32Array(t);for(let r=0;r<a.length;r++)e[r]=a[r];return e}var M=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?Oe:Ae;let i=_(e.h,n.kernel,n.stride,n.padding),o=_(e.w,n.kernel,n.stride,n.padding),u=e.c/4,s=n.outChannels/4,l=m(n.padding,e.h,i,n.kernel,n.stride),c=m(n.padding,e.w,o,n.kernel,n.stride);this.output=t.tensor(i,o,n.outChannels),this.inputs=[e],this.weights=[t.upload(d(r.weights)),t.upload(d(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i,o,u,s,n.kernel,n.kernel,n.stride,l,c,n.activation==="relu6"?1:n.activation==="relu"?2:0])),this.defaultSetup(),this.dispatch=[Math.ceil(o/8),Math.ceil(i/8),Math.ceil(s/4)];}};var Me=`// Depthwise Conv2d \u2014 groups = in_channels (each channel convolved independently).
|
|
3998
3998
|
//
|
|
3999
3999
|
// Weight layout: [K*K][channel_groups] array of vec4
|
|
4000
4000
|
// weight index = (ky*kernel_w + kx) * channel_groups + c
|
|
@@ -4069,7 +4069,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4069
4069
|
let out_idx = y * params.out_w * C + x * C + c;
|
|
4070
4070
|
output_buf[out_idx] = result;
|
|
4071
4071
|
}
|
|
4072
|
-
`;var
|
|
4072
|
+
`;var ze=`enable f16;
|
|
4073
4073
|
|
|
4074
4074
|
// Depthwise conv2d \u2014 full f16 variant. All buffers f16.
|
|
4075
4075
|
|
|
@@ -4134,7 +4134,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4134
4134
|
|
|
4135
4135
|
output_buf[y * params.out_w * C + x * C + c] = result;
|
|
4136
4136
|
}
|
|
4137
|
-
`;var z=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?
|
|
4137
|
+
`;var z=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?ze:Me;let i=_(e.h,n.kernel,n.stride,n.padding),o=_(e.w,n.kernel,n.stride,n.padding),u=e.c/4,s=m(n.padding,e.h,i,n.kernel,n.stride),l=m(n.padding,e.w,o,n.kernel,n.stride);this.output=t.tensor(i,o,e.c),this.inputs=[e],this.weights=[t.upload(d(r.weights)),t.upload(d(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,i,o,u,n.kernel,n.kernel,n.stride,s,l,n.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(o/8),Math.ceil(i/8),u];}};var De=`// Element-wise add of two tensors \u2014 used for residual connections in MBConv blocks.
|
|
4138
4138
|
// Operates on the flat float buffer directly; layout is irrelevant for a pure element-wise op.
|
|
4139
4139
|
|
|
4140
4140
|
struct Params {
|
|
@@ -4155,7 +4155,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4155
4155
|
if (idx >= params.size) { return; }
|
|
4156
4156
|
output[idx] = input_a[idx] + input_b[idx];
|
|
4157
4157
|
}
|
|
4158
|
-
`;var
|
|
4158
|
+
`;var Re=`enable f16;
|
|
4159
4159
|
|
|
4160
4160
|
// Element-wise add \u2014 full f16 variant.
|
|
4161
4161
|
// array<f16> is binary-compatible with array<vec4<f16>> written by the f16 conv shaders.
|
|
@@ -4178,7 +4178,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4178
4178
|
if (idx >= params.size) { return; }
|
|
4179
4179
|
output[idx] = input_a[idx] + input_b[idx];
|
|
4180
4180
|
}
|
|
4181
|
-
`;var
|
|
4181
|
+
`;var D=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Re:De;let n=e.h*e.w*e.c;this.output=t.tensor(e.h,e.w,e.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([n,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(n/256),1,1];}};var He=`// Element-wise sigmoid: output = 1 / (1 + exp(-x)).
|
|
4182
4182
|
// Operates on packed vec4 buffers (NHWC layout). exp() and arithmetic are element-wise on vec4.
|
|
4183
4183
|
|
|
4184
4184
|
struct Params {
|
|
@@ -4198,7 +4198,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4198
4198
|
if (idx >= params.n_groups) { return; }
|
|
4199
4199
|
output_buf[idx] = 1.0 / (1.0 + exp(-input_buf[idx]));
|
|
4200
4200
|
}
|
|
4201
|
-
`;var
|
|
4201
|
+
`;var Le=`enable f16;
|
|
4202
4202
|
|
|
4203
4203
|
// Sigmoid \u2014 full f16 variant.
|
|
4204
4204
|
|
|
@@ -4220,7 +4220,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4220
4220
|
let x = vec4<f32>(input_buf[idx]);
|
|
4221
4221
|
output_buf[idx] = vec4<f16>(1.0 / (1.0 + exp(-x)));
|
|
4222
4222
|
}
|
|
4223
|
-
`;var
|
|
4223
|
+
`;var R=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e){super(t),this.shader=t.dtype==="f16"?Le:He;let r=e.h*e.w*(e.c/4);this.output=t.tensor(e.h,e.w,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([r,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r/256),1,1];}};var Ve=`// Element-wise tanh \u2014 used by ConvGRU candidate activation.
|
|
4224
4224
|
// Operates on packed vec4 buffers (NHWC layout). tanh() is element-wise on vec4.
|
|
4225
4225
|
|
|
4226
4226
|
struct Params {
|
|
@@ -4240,7 +4240,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4240
4240
|
if (idx >= params.n_groups) { return; }
|
|
4241
4241
|
output_buf[idx] = tanh(input_buf[idx]);
|
|
4242
4242
|
}
|
|
4243
|
-
`;var
|
|
4243
|
+
`;var Ne=`enable f16;
|
|
4244
4244
|
|
|
4245
4245
|
// Tanh \u2014 full f16 variant.
|
|
4246
4246
|
|
|
@@ -4262,7 +4262,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4262
4262
|
let x = vec4<f32>(input_buf[idx]);
|
|
4263
4263
|
output_buf[idx] = vec4<f16>(tanh(x));
|
|
4264
4264
|
}
|
|
4265
|
-
`;var
|
|
4265
|
+
`;var H=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e){super(t),this.shader=t.dtype==="f16"?Ne:Ve;let r=e.h*e.w*(e.c/4);this.output=t.tensor(e.h,e.w,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([r,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r/256),1,1];}};var $e=`// Element-wise multiply \u2014 used in ConvGRU for r \u2299 h_prev.
|
|
4266
4266
|
// Same flat-float layout as add.wgsl.
|
|
4267
4267
|
|
|
4268
4268
|
struct Params {
|
|
@@ -4283,7 +4283,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4283
4283
|
if (idx >= params.size) { return; }
|
|
4284
4284
|
output[idx] = input_a[idx] * input_b[idx];
|
|
4285
4285
|
}
|
|
4286
|
-
`;var
|
|
4286
|
+
`;var je=`enable f16;
|
|
4287
4287
|
|
|
4288
4288
|
// Element-wise multiply \u2014 full f16 variant.
|
|
4289
4289
|
// array<f16> is binary-compatible with array<vec4<f16>> written by the f16 conv shaders.
|
|
@@ -4306,7 +4306,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4306
4306
|
if (idx >= params.size) { return; }
|
|
4307
4307
|
output[idx] = input_a[idx] * input_b[idx];
|
|
4308
4308
|
}
|
|
4309
|
-
`;var
|
|
4309
|
+
`;var L=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?je:$e;let n=e.h*e.w*e.c;this.output=t.tensor(e.h,e.w,e.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([n,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(n/256),1,1];}};var qe=`// Bilinear upsample (arbitrary ratio), align_corners=False (matches PyTorch default).
|
|
4310
4310
|
// Input/output in NHWC vec4 format: index = y*W*(C/4) + x*(C/4) + c_group.
|
|
4311
4311
|
// Each thread computes one output pixel for one channel group (vec4 = 4 channels).
|
|
4312
4312
|
|
|
@@ -4364,7 +4364,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4364
4364
|
|
|
4365
4365
|
output_buf[oy * params.out_w * C + ox * C + c] = result;
|
|
4366
4366
|
}
|
|
4367
|
-
`;var
|
|
4367
|
+
`;var Xe=`enable f16;
|
|
4368
4368
|
|
|
4369
4369
|
// Bilinear upsample 2\xD7 \u2014 full f16 variant.
|
|
4370
4370
|
// Interpolation weights (wx, wy) and intermediate blends computed in f32 for
|
|
@@ -4420,7 +4420,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4420
4420
|
|
|
4421
4421
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(result);
|
|
4422
4422
|
}
|
|
4423
|
-
`;var
|
|
4423
|
+
`;var V=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Xe:qe;let n=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,n,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),n];}};var Ke=`// Bicubic upsample (arbitrary scale) \u2014 Keys cubic, a=-0.75 (PyTorch default
|
|
4424
4424
|
// for mode='bicubic', align_corners=False). Direct 2D, 4\xD74 = 16 taps per
|
|
4425
4425
|
// output pixel. NHWC vec4 layout: index = y*W*(C/4) + x*(C/4) + c_group.
|
|
4426
4426
|
|
|
@@ -4487,7 +4487,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4487
4487
|
|
|
4488
4488
|
output_buf[oy * params.out_w * C + ox * C + c] = acc;
|
|
4489
4489
|
}
|
|
4490
|
-
`;var
|
|
4490
|
+
`;var Ye=`enable f16;
|
|
4491
4491
|
|
|
4492
4492
|
// Bicubic upsample \u2014 full f16 storage variant. Bicubic weights and the per-
|
|
4493
4493
|
// pixel accumulator are computed in f32 (cheap to keep precision around the
|
|
@@ -4556,7 +4556,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4556
4556
|
|
|
4557
4557
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(acc);
|
|
4558
4558
|
}
|
|
4559
|
-
`;var
|
|
4559
|
+
`;var N=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Ye:Ke;let n=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,n,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),n];}};var Qe=`// Channel concatenation: output = cat(A, B, dim=channel).
|
|
4560
4560
|
// Both A and B must share the same H\xD7W and be in NHWC vec4 format.
|
|
4561
4561
|
// Output layout: for each (y, x), the first a_groups vec4s come from A,
|
|
4562
4562
|
// followed by b_groups vec4s from B.
|
|
@@ -4601,7 +4601,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4601
4601
|
output_buf[out_idx] = input_b[y * W * Bg + x * Bg + c_b];
|
|
4602
4602
|
}
|
|
4603
4603
|
}
|
|
4604
|
-
`;var
|
|
4604
|
+
`;var Je=`enable f16;
|
|
4605
4605
|
|
|
4606
4606
|
// Channel concatenation \u2014 full f16 variant.
|
|
4607
4607
|
|
|
@@ -4642,7 +4642,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4642
4642
|
output_buf[out_idx] = input_b[y * W * Bg + x * Bg + c_b];
|
|
4643
4643
|
}
|
|
4644
4644
|
}
|
|
4645
|
-
`;var
|
|
4645
|
+
`;var $=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Je:Qe;let n=e.c/4,i=r.c/4,o=n+i;this.output=t.tensor(e.h,e.w,e.c+r.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,n,i,o,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),o];}};var Ze=`// Conv2d + skip add fused.
|
|
4646
4646
|
// Identical to conv2d.wgsl except skip is an activation input (binding 1),
|
|
4647
4647
|
// added element-wise to the conv result at write time.
|
|
4648
4648
|
// Eliminates the separate add dispatch and its intermediate buffer round-trip.
|
|
@@ -4716,7 +4716,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4716
4716
|
let out_idx = y * params.out_w * O + x * O + o;
|
|
4717
4717
|
output_buf[out_idx] = result + skip_buf[out_idx];
|
|
4718
4718
|
}
|
|
4719
|
-
`;var
|
|
4719
|
+
`;var et=`enable f16;
|
|
4720
4720
|
|
|
4721
4721
|
// Conv2d + skip add fused \u2014 full f16 variant.
|
|
4722
4722
|
|
|
@@ -4790,7 +4790,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4790
4790
|
let out_idx = y * params.out_w * O + x * O + o;
|
|
4791
4791
|
output_buf[out_idx] = result + skip_buf[out_idx];
|
|
4792
4792
|
}
|
|
4793
|
-
`;var
|
|
4793
|
+
`;var j=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i){super(t),this.shader=t.dtype==="f16"?et:Ze;let o=_(e.h,i.kernel,i.stride,i.padding),u=_(e.w,i.kernel,i.stride,i.padding),s=e.c/4,l=i.outChannels/4,c=m(i.padding,e.h,o,i.kernel,i.stride),h=m(i.padding,e.w,u,i.kernel,i.stride);this.output=t.tensor(o,u,i.outChannels),this.inputs=[e,r],this.weights=[t.upload(d(n.weights)),t.upload(d(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,o,u,s,l,i.kernel,i.kernel,i.stride,c,h,i.activation==="relu6"?1:0])),this.defaultSetup(),this.dispatch=[Math.ceil(u/8),Math.ceil(o/8),l];}};var tt=`// proj_residual: bespoke 1\xD71 conv (no activation) + residual add, fused.
|
|
4794
4794
|
// Specializes conv2d_add to kernel=1 / stride=1 / pad=0 / no activation: drops
|
|
4795
4795
|
// the kernel loop, the padding checks, and the activation branch. Used by the
|
|
4796
4796
|
// MBConv project+residual tail. Both inputs share the same spatial resolution.
|
|
@@ -4835,7 +4835,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4835
4835
|
|
|
4836
4836
|
output_buf[pix * O + o] = result;
|
|
4837
4837
|
}
|
|
4838
|
-
`;var
|
|
4838
|
+
`;var rt=`enable f16;
|
|
4839
4839
|
|
|
4840
4840
|
// proj_residual \u2014 full f16 variant. See proj_residual.wgsl for layout details.
|
|
4841
4841
|
// Bespoke 1\xD71 conv (no activation) + residual add, fused.
|
|
@@ -4877,7 +4877,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4877
4877
|
|
|
4878
4878
|
output_buf[pix * O + o] = result;
|
|
4879
4879
|
}
|
|
4880
|
-
`;var
|
|
4880
|
+
`;var q=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i){super(t),this.shader=t.dtype==="f16"?rt:tt;let o=e.c/4,u=i.outChannels/4;this.output=t.tensor(e.h,e.w,i.outChannels),this.inputs=[e,r],this.weights=[t.upload(d(n.weights)),t.upload(d(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,o,u])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),u];}};var nt=`// concat_conv2d: fuses [concat(a, b) \u2192 conv 3\xD73 (pad 1) \u2192 relu6] into one
|
|
4881
4881
|
// dispatch. Both inputs are already at the output resolution (the upstream
|
|
4882
4882
|
// upsample stays a separate dispatch writing a clean intermediate, so the conv
|
|
4883
4883
|
// reads are plain-indexed). Identical math to conv2d; the only difference is
|
|
@@ -4937,7 +4937,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4937
4937
|
result = clamp(result, vec4<f32>(0.0), vec4<f32>(6.0));
|
|
4938
4938
|
output_buf[(y * p.w + x) * O + o] = result;
|
|
4939
4939
|
}
|
|
4940
|
-
`;var
|
|
4940
|
+
`;var at=`enable f16;
|
|
4941
4941
|
|
|
4942
4942
|
// concat_conv2d \u2014 full f16 variant. See concat_conv2d.wgsl for layout details.
|
|
4943
4943
|
// Fuses [concat(a, b) \u2192 conv 3\xD73 (pad 1) \u2192 relu6] into one dispatch.
|
|
@@ -4992,7 +4992,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
4992
4992
|
result = clamp(result, vec4<f16>(0.0h), vec4<f16>(6.0h));
|
|
4993
4993
|
output_buf[(y * p.w + x) * O + o] = result;
|
|
4994
4994
|
}
|
|
4995
|
-
`;var
|
|
4995
|
+
`;var X=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i){super(t),this.shader=t.dtype==="f16"?at:nt;let o=e.c/4,u=r.c/4,s=i.outChannels/4;this.output=t.tensor(e.h,e.w,i.outChannels),this.inputs=[e,r],this.weights=[t.upload(d(n.weights)),t.upload(d(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,o,u,s,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),s];}};var it=`// gates_fused: ConvGRU z + r gates, fused into one dispatch.
|
|
4996
4996
|
// Production config (c_up=2, split_ratio=0.5 \u2192 passthrough=1, recurrent=1):
|
|
4997
4997
|
// u_in : c_up=2 packed in a vec4 (.x = passthrough a, .y = recurrent b)
|
|
4998
4998
|
// h_prev : hidden carrier \u2014 recurrent state in .z (see cand_update_fused: the
|
|
@@ -5037,7 +5037,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5037
5037
|
let r = 1.0 / (1.0 + exp(-r_pre));
|
|
5038
5038
|
output_buf[y * params.w + x] = vec4<f32>(z, r, 0.0, 0.0);
|
|
5039
5039
|
}
|
|
5040
|
-
`;var
|
|
5040
|
+
`;var ot=`enable f16;
|
|
5041
5041
|
|
|
5042
5042
|
// gates_fused \u2014 full f16 variant. See gates_fused.wgsl for layout details.
|
|
5043
5043
|
// ConvGRU z + r gates (production config c_up=2, recurrent=1).
|
|
@@ -5079,7 +5079,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5079
5079
|
let r = 1.0h / (1.0h + exp(-r_pre));
|
|
5080
5080
|
output_buf[y * params.w + x] = vec4<f16>(z, r, 0.0h, 0.0h);
|
|
5081
5081
|
}
|
|
5082
|
-
`;var
|
|
5082
|
+
`;var K=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?ot:it,this.output=t.tensor(e.h,e.w,4),this.inputs=[e,r],this.weights=[t.upload(d(n.weights)),t.upload(g(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1];}};var ut=`// cand_update_fused: ConvGRU candidate path + state update + output, fused.
|
|
5083
5083
|
// Production config (c_up=2, recurrent=1):
|
|
5084
5084
|
// u_in : c_up=2 (.x = a passthrough, .y = b recurrent)
|
|
5085
5085
|
// h_prev : hidden carrier \u2014 recurrent state in .z (the previous frame's
|
|
@@ -5132,7 +5132,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5132
5132
|
let b_out = u_cur.y + gamma_buf[0].x * h_new;
|
|
5133
5133
|
output_buf[cur] = vec4<f32>(u_cur.x, b_out, h_new, 0.0);
|
|
5134
5134
|
}
|
|
5135
|
-
`;var
|
|
5135
|
+
`;var st=`enable f16;
|
|
5136
5136
|
|
|
5137
5137
|
// cand_update_fused \u2014 full f16 variant. See cand_update_fused.wgsl for details.
|
|
5138
5138
|
// ConvGRU candidate + state update + output (production config c_up=2, recurrent=1).
|
|
@@ -5178,7 +5178,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5178
5178
|
let b_out = u_cur.y + gamma_buf[0].x * h_new;
|
|
5179
5179
|
output_buf[cur] = vec4<f16>(u_cur.x, b_out, h_new, 0.0h);
|
|
5180
5180
|
}
|
|
5181
|
-
`;var
|
|
5181
|
+
`;var Y=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i,o){super(t),this.shader=t.dtype==="f16"?st:ut,this.output=t.tensor(e.h,e.w,4),this.inputs=[e,r,n],this.weights=[t.upload(d(i.weights)),t.upload(g(i.bias)),t.upload(g(o))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1];}};var pt=`// conv_expand: bespoke N\u21922 conv 3\xD73 (pad 1) + relu (wrapper expand_feat).
|
|
5182
5182
|
// Expands feat_lr (in_c, mult of 4) to the c_up=2 carrier \u2014 output .xy = the 2
|
|
5183
5183
|
// native channels, .zw = 0. mat4x2 per (kpos, in_group) with a vec2 accumulator.
|
|
5184
5184
|
// Weight: 9 * in_groups mat4x2 (8 floats each, col-major). Bias .xy.
|
|
@@ -5215,7 +5215,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5215
5215
|
result = max(result, vec2<f32>(0.0)); // expand_feat is F.relu
|
|
5216
5216
|
output_buf[y * params.w + x] = vec4<f32>(result, 0.0, 0.0);
|
|
5217
5217
|
}
|
|
5218
|
-
`;var
|
|
5218
|
+
`;var lt=`enable f16;
|
|
5219
5219
|
|
|
5220
5220
|
// conv_expand \u2014 full f16 variant. See conv_expand.wgsl for layout details.
|
|
5221
5221
|
// Bespoke N\u21922 conv 3\xD73 (pad 1) + relu (wrapper expand_feat).
|
|
@@ -5252,7 +5252,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5252
5252
|
result = max(result, vec2<f16>(0.0h));
|
|
5253
5253
|
output_buf[y * params.w + x] = vec4<f16>(result, 0.0h, 0.0h);
|
|
5254
5254
|
}
|
|
5255
|
-
`;var
|
|
5255
|
+
`;var Q=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?lt:pt;let n=e.c/4;this.output=t.tensor(e.h,e.w,4),this.inputs=[e],this.weights=[t.upload(d(r.weights)),t.upload(g(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,n,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1];}};var ct=`// cat_conv_6to2: fused concat(u, d) + 6\u21922 conv 3\xD73 (pad 1) + relu (E up1_combine).
|
|
5256
5256
|
// u = c_up=2 carrier (.xy); d = c_high=4 (full vec4). Both same resolution.
|
|
5257
5257
|
// Channel order concat([u, d]) = (u.x, u.y, d.x, d.y, d.z, d.w), split into
|
|
5258
5258
|
// v3a = (u.x, u.y, d.x) v3b = d.yzw
|
|
@@ -5292,7 +5292,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5292
5292
|
result = max(result, vec2<f32>(0.0)); // up1_combine is F.relu
|
|
5293
5293
|
output_buf[y * params.w + x] = vec4<f32>(result, 0.0, 0.0);
|
|
5294
5294
|
}
|
|
5295
|
-
`;var
|
|
5295
|
+
`;var dt=`enable f16;
|
|
5296
5296
|
|
|
5297
5297
|
// cat_conv_6to2 \u2014 full f16 variant. See cat_conv_6to2.wgsl for layout details.
|
|
5298
5298
|
// Fused concat(u, d) + 6\u21922 conv 3\xD73 (pad 1) + relu (E up1_combine).
|
|
@@ -5331,7 +5331,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5331
5331
|
result = max(result, vec2<f16>(0.0h));
|
|
5332
5332
|
output_buf[y * params.w + x] = vec4<f16>(result, 0.0h, 0.0h);
|
|
5333
5333
|
}
|
|
5334
|
-
`;var J=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?
|
|
5334
|
+
`;var J=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?dt:ct,this.output=t.tensor(e.h,e.w,4),this.inputs=[e,r],this.weights=[t.upload(d(n.weights)),t.upload(g(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1];}};var ht=`// down_adapter: fused stride-N 3\xD73 conv (4\u21924) + relu + 1\xD71 adapter (4\u21923, no
|
|
5335
5335
|
// act) into one dispatch. E variant: down2 (c_high=4 \u2192 c_low=4, stride 2) +
|
|
5336
5336
|
// adapter. A/B variant: down1 (RGB .xyz \u2192 4, stride 2/3) + adapter (the down
|
|
5337
5337
|
// weight's 4th input column is zeroed at export for RGB input). Symmetric pad.
|
|
@@ -5379,7 +5379,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5379
5379
|
let adapt_out = adapt_w[0] * down_out + adapt_b[0];
|
|
5380
5380
|
output_buf[y * p.out_w + x] = vec4<f32>(adapt_out.xyz, 0.0);
|
|
5381
5381
|
}
|
|
5382
|
-
`;var
|
|
5382
|
+
`;var ft=`enable f16;
|
|
5383
5383
|
|
|
5384
5384
|
// down_adapter \u2014 full f16 variant. See down_adapter.wgsl for layout details.
|
|
5385
5385
|
// Fused stride-N 3\xD73 conv (4\u21924) + relu + 1\xD71 adapter (4\u21923, no act).
|
|
@@ -5424,7 +5424,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5424
5424
|
let adapt_out = adapt_w[0] * down_out + adapt_b[0];
|
|
5425
5425
|
output_buf[y * p.out_w + x] = vec4<f16>(adapt_out.xyz, 0.0h);
|
|
5426
5426
|
}
|
|
5427
|
-
`;var Z=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i){super(t),this.shader=t.dtype==="f16"?
|
|
5427
|
+
`;var Z=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i){super(t),this.shader=t.dtype==="f16"?ft:ht;let o=_(e.h,3,i.stride,1),u=_(e.w,3,i.stride,1),s=m(1,e.h,o,3,i.stride),l=m(1,e.w,u,3,i.stride);this.output=t.tensor(o,u,4),this.inputs=[e],this.weights=[t.upload(d(r.weights)),t.upload(g(r.bias)),t.upload(d(n.weights)),t.upload(g(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,o,u,i.stride,s,l,0])),this.defaultSetup(),this.dispatch=[Math.ceil(u/8),Math.ceil(o/8),1];}};var gt=`// up_final: fused concat(u, rgb) \u2192 conv 3\xD73 5\u21921 \u2192 sigmoid (A/B alpha head).
|
|
5428
5428
|
// u = c_up=2 carrier (.xy); rgb = x_hr (.xyz). 5 inputs \u2192 1 alpha (output .x).
|
|
5429
5429
|
// Weight: 18 vec4 \u2014 [0..8] = (w0, w1, 0, 0) for u per kpos; [9..17] =
|
|
5430
5430
|
// (w2, w3, w4, 0) for rgb per kpos. Bias .x.
|
|
@@ -5458,7 +5458,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5458
5458
|
|
|
5459
5459
|
output_buf[y * params.w + x] = vec4<f32>(1.0 / (1.0 + exp(-acc)), 0.0, 0.0, 0.0);
|
|
5460
5460
|
}
|
|
5461
|
-
`;var
|
|
5461
|
+
`;var _t=`enable f16;
|
|
5462
5462
|
|
|
5463
5463
|
// up_final \u2014 full f16 variant. See up_final.wgsl for layout details.
|
|
5464
5464
|
// Fused concat(u, rgb) \u2192 conv 3\xD73 5\u21921 \u2192 sigmoid (A/B alpha head).
|
|
@@ -5492,7 +5492,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5492
5492
|
|
|
5493
5493
|
output_buf[y * params.w + x] = vec4<f16>(1.0h / (1.0h + exp(-acc)), 0.0h, 0.0h, 0.0h);
|
|
5494
5494
|
}
|
|
5495
|
-
`;var
|
|
5495
|
+
`;var ee=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?_t:gt,this.output=t.tensor(e.h,e.w,4),this.inputs=[e,r],this.weights=[t.upload(d(n.weights)),t.upload(g(n.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1];}};var mt=`// up_final_skip: C/D alpha head. Fused concat(u, d_full, rgb) \u2192 conv 3\xD73 9\u21921
|
|
5496
5496
|
// \u2192 sigmoid. u = c_up=2 (.xy); d_full = c_high=4 full-res skip (full vec4);
|
|
5497
5497
|
// rgb = x_hr (.xyz). Channel order concat = 2 + 4 + 3 = 9. Output .x = alpha.
|
|
5498
5498
|
// Weight: 27 vec4 (3 per kpos): [kpos*3+0]=(w0,w1,0,0) u; [kpos*3+1]=(w2..w5)
|
|
@@ -5529,7 +5529,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5529
5529
|
|
|
5530
5530
|
output_buf[y * params.w + x] = vec4<f32>(1.0 / (1.0 + exp(-acc)), 0.0, 0.0, 0.0);
|
|
5531
5531
|
}
|
|
5532
|
-
`;var
|
|
5532
|
+
`;var bt=`enable f16;
|
|
5533
5533
|
|
|
5534
5534
|
// up_final_skip \u2014 full f16 variant. See up_final_skip.wgsl for layout details.
|
|
5535
5535
|
// C/D alpha head: fused concat(u, d_full, rgb) \u2192 conv 3\xD73 9\u21921 \u2192 sigmoid.
|
|
@@ -5565,7 +5565,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5565
5565
|
|
|
5566
5566
|
output_buf[y * params.w + x] = vec4<f16>(1.0h / (1.0h + exp(-acc)), 0.0h, 0.0h, 0.0h);
|
|
5567
5567
|
}
|
|
5568
|
-
`;var
|
|
5568
|
+
`;var te=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n,i){super(t),this.shader=t.dtype==="f16"?bt:mt,this.output=t.tensor(e.h,e.w,4),this.inputs=[e,r,n],this.weights=[t.upload(d(i.weights)),t.upload(g(i.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(e.w/8),Math.ceil(e.h/8),1];}};var vt=`// Bilinear upsample + channel concat fused.
|
|
5569
5569
|
// input_a is the decoder tensor at small spatial resolution (in_h \xD7 in_w).
|
|
5570
5570
|
// input_b is the encoder skip feature already at output resolution (out_h \xD7 out_w).
|
|
5571
5571
|
// For output channels 0..a_groups-1: bilinearly interpolate from input_a.
|
|
@@ -5626,7 +5626,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5626
5626
|
output_buf[out_idx] = input_b[oy * params.out_w * params.b_groups + ox * params.b_groups + c_b];
|
|
5627
5627
|
}
|
|
5628
5628
|
}
|
|
5629
|
-
`;var
|
|
5629
|
+
`;var xt=`enable f16;
|
|
5630
5630
|
|
|
5631
5631
|
// Bilinear upsample + channel concat fused \u2014 full f16 variant.
|
|
5632
5632
|
// Bilinear weights (wx, wy) and intermediate blends computed in f32; result cast to f16.
|
|
@@ -5686,7 +5686,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5686
5686
|
output_buf[out_idx] = input_b[oy * params.out_w * params.b_groups + ox * params.b_groups + c_b];
|
|
5687
5687
|
}
|
|
5688
5688
|
}
|
|
5689
|
-
`;var
|
|
5689
|
+
`;var re=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?xt:vt;let i=e.c/4,o=r.c/4,u=i+o;this.output=t.tensor(n.outH,n.outW,e.c+r.c),this.inputs=[e,r],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,n.outH,n.outW,i,o,u,0])),this.defaultSetup(),this.dispatch=[Math.ceil(n.outW/8),Math.ceil(n.outH/8),u];}};var wt=`// Bilinear upsample + 1\xD71 pointwise conv fused.
|
|
5690
5690
|
// For each output pixel, bilinearly samples the small input for each in_group,
|
|
5691
5691
|
// immediately applies the 1\xD71 conv weights, and writes the activated result.
|
|
5692
5692
|
// Eliminates the intermediate full-resolution upsample buffer.
|
|
@@ -5753,7 +5753,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5753
5753
|
|
|
5754
5754
|
output_buf[oy * params.out_w * params.out_groups + ox * params.out_groups + og] = result;
|
|
5755
5755
|
}
|
|
5756
|
-
`;var
|
|
5756
|
+
`;var yt=`enable f16;
|
|
5757
5757
|
|
|
5758
5758
|
// Bilinear upsample + 1\xD71 pointwise conv fused \u2014 full f16 variant.
|
|
5759
5759
|
// Bilinear weights and intermediate blends computed in f32; conv accumulation in f16.
|
|
@@ -5820,7 +5820,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5820
5820
|
|
|
5821
5821
|
output_buf[oy * params.out_w * params.out_groups + ox * params.out_groups + og] = result;
|
|
5822
5822
|
}
|
|
5823
|
-
`;var
|
|
5823
|
+
`;var ne=class extends p{inputs;weights;output;dispatch;shader;constructor(t,e,r,n){super(t),this.shader=t.dtype==="f16"?yt:wt;let i=e.c/4,o=n.outChannels/4;this.output=t.tensor(n.outH,n.outW,n.outChannels),this.inputs=[e],this.weights=[t.upload(d(r.weights)),t.upload(d(r.bias))],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,n.outH,n.outW,i,o,n.activation==="relu6"?1:0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(n.outW/8),Math.ceil(n.outH/8),o];}};var kt=`// Bilinear upsample + sigmoid fused.
|
|
5824
5824
|
// Identical to bilinear_upsample.wgsl except sigmoid is applied at write time.
|
|
5825
5825
|
// Eliminates the intermediate full-resolution buffer and the separate sigmoid dispatch.
|
|
5826
5826
|
|
|
@@ -5874,7 +5874,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5874
5874
|
|
|
5875
5875
|
output_buf[oy * params.out_w * C + ox * C + c] = 1.0 / (1.0 + exp(-result));
|
|
5876
5876
|
}
|
|
5877
|
-
`;var
|
|
5877
|
+
`;var Ct=`enable f16;
|
|
5878
5878
|
|
|
5879
5879
|
// Bilinear upsample + sigmoid fused \u2014 full f16 variant.
|
|
5880
5880
|
// Interpolation computed in f32 for accuracy; sigmoid and result cast to f16.
|
|
@@ -5929,7 +5929,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
5929
5929
|
|
|
5930
5930
|
output_buf[oy * params.out_w * C + ox * C + c] = vec4<f16>(1.0 / (1.0 + exp(-result)));
|
|
5931
5931
|
}
|
|
5932
|
-
`;var
|
|
5932
|
+
`;var ae=class extends p{inputs;weights=[];output;dispatch;shader;constructor(t,e,r){super(t),this.shader=t.dtype==="f16"?Ct:kt;let n=e.c/4;this.output=t.tensor(r.outH,r.outW,e.c),this.inputs=[e],this.createUniform("params","Params"),this.setUniform("params",new Uint32Array([e.h,e.w,r.outH,r.outW,n,0,0,0])),this.defaultSetup(),this.dispatch=[Math.ceil(r.outW/8),Math.ceil(r.outH/8),n];}};var Pt=`// Composite an RGBA image over a solid background, gated by a 1-ch alpha.
|
|
5933
5933
|
// Fragment writes the canvas's swapchain texture (premultiplied output).
|
|
5934
5934
|
//
|
|
5935
5935
|
// Caller invariants (matched in CompositeSolidWebGPU):
|
|
@@ -5974,7 +5974,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
5974
5974
|
let rgb = fg * a + params.bgColor.rgb * (1.0 - a);
|
|
5975
5975
|
return vec4<f32>(rgb, 1.0);
|
|
5976
5976
|
}
|
|
5977
|
-
`;var
|
|
5977
|
+
`;var Tt=`enable f16;
|
|
5978
5978
|
|
|
5979
5979
|
// Composite an RGBA image over a solid background, gated by a 1-ch alpha.
|
|
5980
5980
|
// f16 variant: image and alpha are stored as f16; values promote to f32 on
|
|
@@ -6023,7 +6023,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6023
6023
|
let rgb = fg * a + params.bgColor.rgb * (1.0 - a);
|
|
6024
6024
|
return vec4<f32>(rgb, 1.0);
|
|
6025
6025
|
}
|
|
6026
|
-
`;var
|
|
6026
|
+
`;var ie=class{constructor(t,e,r,n){this.backend=t;if(e.h!==r.h||e.w!==r.w)throw new Error(`CompositeSolid: image (${e.h}\xD7${e.w}) and alpha (${r.h}\xD7${r.w}) must match. Run the upscaler first.`);let i=t.device;this.uniformBuffer=i.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let o=new ArrayBuffer(32);new Uint32Array(o,0,1)[0]=e.w,new Float32Array(o,16,4).set([n[0],n[1],n[2],0]),i.queue.writeBuffer(this.uniformBuffer,0,o);let u=t.dtype==="f16"?Tt:Pt,s=i.createShaderModule({code:u});this.pipeline=i.createRenderPipeline({layout:"auto",vertex:{module:s,entryPoint:"vs"},fragment:{module:s,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=i.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeSolidWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Ut=`// Like composite_solid but bg is an NHWC vec4 storage buffer (e.g. virtual
|
|
6027
6027
|
// background image, or a blurred copy of the input).
|
|
6028
6028
|
|
|
6029
6029
|
struct VertexOut {
|
|
@@ -6065,7 +6065,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6065
6065
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
6066
6066
|
return vec4<f32>(rgb, 1.0);
|
|
6067
6067
|
}
|
|
6068
|
-
`;var
|
|
6068
|
+
`;var It=`enable f16;
|
|
6069
6069
|
|
|
6070
6070
|
// Like composite_solid_f16 but bg is an NHWC vec4<f16> storage buffer (e.g. a
|
|
6071
6071
|
// virtual background image, or a blurred copy of the input).
|
|
@@ -6109,7 +6109,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6109
6109
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
6110
6110
|
return vec4<f32>(rgb, 1.0);
|
|
6111
6111
|
}
|
|
6112
|
-
`;var
|
|
6112
|
+
`;var oe=class{constructor(t,e,r,n){this.backend=t;if(e.h!==r.h||e.w!==r.w||e.h!==n.h||e.w!==n.w)throw new Error(`CompositeImage: image (${e.h}\xD7${e.w}), alpha (${r.h}\xD7${r.w}), and bg (${n.h}\xD7${n.w}) must all match. Run upscaler / resizer first.`);let i=t.device;this.uniformBuffer=i.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let o=new ArrayBuffer(16);new Uint32Array(o,0,1)[0]=e.w,i.queue.writeBuffer(this.uniformBuffer,0,o);let u=t.dtype==="f16"?It:Ut,s=i.createShaderModule({code:u});this.pipeline=i.createRenderPipeline({layout:"auto",vertex:{module:s,entryPoint:"vs"},fragment:{module:s,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=i.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:n.buffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeImageWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Bt=`// Like composite_image but bg is sampled bilinearly \u2014 bg may be smaller than
|
|
6113
6113
|
// (image, alpha). Used by CompositorBlur to skip the final full-res upsample
|
|
6114
6114
|
// in the blur pyramid and let this shader's own per-pixel scan do the
|
|
6115
6115
|
// expansion (the work is already happening here for the composite anyway).
|
|
@@ -6174,7 +6174,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6174
6174
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
6175
6175
|
return vec4<f32>(rgb, 1.0);
|
|
6176
6176
|
}
|
|
6177
|
-
`;var
|
|
6177
|
+
`;var Wt=`enable f16;
|
|
6178
6178
|
|
|
6179
6179
|
// f16 storage variant of composite_image_bilinear. bg is at a smaller
|
|
6180
6180
|
// resolution and is bilinearly sampled to match (image, alpha) at full res.
|
|
@@ -6235,7 +6235,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6235
6235
|
let rgb = fg * a + bgc * (1.0 - a);
|
|
6236
6236
|
return vec4<f32>(rgb, 1.0);
|
|
6237
6237
|
}
|
|
6238
|
-
`;var
|
|
6238
|
+
`;var ue=class{constructor(t,e,r,n){this.backend=t;if(e.h!==r.h||e.w!==r.w)throw new Error(`CompositeImageBilinear: image (${e.h}\xD7${e.w}) and alpha (${r.h}\xD7${r.w}) must match.`);let i=t.device;this.uniformBuffer=i.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let o=new ArrayBuffer(16),u=new Uint32Array(o);u[0]=e.w,u[1]=e.h,u[2]=n.w,u[3]=n.h,i.queue.writeBuffer(this.uniformBuffer,0,o);let s=t.dtype==="f16"?Wt:Bt,l=i.createShaderModule({code:s});this.pipeline=i.createRenderPipeline({layout:"auto",vertex:{module:l,entryPoint:"vs"},fragment:{module:l,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=i.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:r.buffer}},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:n.buffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositeImageBilinearWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var St=`// Passthrough "compositor" \u2014 writes the image directly to the canvas
|
|
6239
6239
|
// swapchain texture with no alpha math and no background. Used by RenderOp
|
|
6240
6240
|
// when the renderer is in disabled state, so the output canvas reflects
|
|
6241
6241
|
// the unmodified input frame instead of a stale matted result.
|
|
@@ -6273,7 +6273,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6273
6273
|
let i = y * params.width + x;
|
|
6274
6274
|
return vec4<f32>(image[i].rgb, 1.0);
|
|
6275
6275
|
}
|
|
6276
|
-
`;var
|
|
6276
|
+
`;var Gt=`enable f16;
|
|
6277
6277
|
|
|
6278
6278
|
// Passthrough "compositor" \u2014 f16 variant. Image is stored as f16; values
|
|
6279
6279
|
// promote to f32 on read and the fragment writes f32 to the canvas
|
|
@@ -6309,7 +6309,7 @@ fn fs(in: VertexOut) -> @location(0) vec4<f32> {
|
|
|
6309
6309
|
let i = y * params.width + x;
|
|
6310
6310
|
return vec4<f32>(vec3<f32>(image[i].rgb), 1.0);
|
|
6311
6311
|
}
|
|
6312
|
-
`;var
|
|
6312
|
+
`;var se=class{constructor(t,e){this.backend=t;let r=t.device;this.uniformBuffer=r.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let n=new ArrayBuffer(16);new Uint32Array(n,0,1)[0]=e.w,r.queue.writeBuffer(this.uniformBuffer,0,n);let i=t.dtype==="f16"?Gt:St,o=r.createShaderModule({code:i});this.pipeline=r.createRenderPipeline({layout:"auto",vertex:{module:o,entryPoint:"vs"},fragment:{module:o,entryPoint:"fs",targets:[{format:t.canvasFormat}]},primitive:{topology:"triangle-list"}}),this.bindGroup=r.createBindGroup({layout:this.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:e.buffer}},{binding:1,resource:{buffer:this.uniformBuffer}}]});}backend;pipeline;bindGroup;uniformBuffer;outputView=null;setOutput(t){this.outputView=t.createView();}run(){if(!this.outputView)throw new Error("CompositePassthroughWebGPU.run() called before setOutput()");let t=this.backend.device.createCommandEncoder(),e=t.beginRenderPass({colorAttachments:[{view:this.outputView,clearValue:[0,0,0,1],loadOp:"clear",storeOp:"store"}]});e.setPipeline(this.pipeline),e.setBindGroup(0,this.bindGroup),e.draw(6),e.end(),this.backend.device.queue.submit([t.finish()]),this.outputView=null;}};var Et=`// Input op \u2014 sample a regular 2D source texture (RGBA8 unorm) into the NHWC
|
|
6313
6313
|
// vec4<f32> output buffer at the target resolution. Used for ImageBitmap
|
|
6314
6314
|
// sources, which are uploaded into a persistent staging texture via
|
|
6315
6315
|
// copyExternalImageToTexture before each dispatch.
|
|
@@ -6339,7 +6339,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
6339
6339
|
let rgba = textureSampleLevel(src_tex, src_sampler, uv, 0.0);
|
|
6340
6340
|
output_buf[y * params.out_w + x] = rgba;
|
|
6341
6341
|
}
|
|
6342
|
-
`;var
|
|
6342
|
+
`;var Ft=`enable f16;
|
|
6343
6343
|
|
|
6344
6344
|
// Input op \u2014 f16 storage variant. Source is sampled as vec4<f32>; only the
|
|
6345
6345
|
// store is demoted to vec4<f16>.
|
|
@@ -6369,7 +6369,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
6369
6369
|
let rgba = textureSampleLevel(src_tex, src_sampler, uv, 0.0);
|
|
6370
6370
|
output_buf[y * params.out_w + x] = vec4<f16>(rgba);
|
|
6371
6371
|
}
|
|
6372
|
-
`;var
|
|
6372
|
+
`;var At=`// Input op \u2014 sample a GPUExternalTexture (zero-copy VideoFrame import) into
|
|
6373
6373
|
// the NHWC vec4<f32> output buffer at the target resolution. Used when the
|
|
6374
6374
|
// caller passes a VideoFrame to setSource(); requires importExternalTexture
|
|
6375
6375
|
// to be called in the same task as the dispatch (the texture is invalidated
|
|
@@ -6400,7 +6400,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
6400
6400
|
let rgba = textureSampleBaseClampToEdge(src_tex, src_sampler, uv);
|
|
6401
6401
|
output_buf[y * params.out_w + x] = rgba;
|
|
6402
6402
|
}
|
|
6403
|
-
`;var
|
|
6403
|
+
`;var Ot=`enable f16;
|
|
6404
6404
|
|
|
6405
6405
|
// Input op \u2014 texture_external + f16 storage. Sample in f32, store as f16.
|
|
6406
6406
|
|
|
@@ -6429,4 +6429,4 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
6429
6429
|
let rgba = textureSampleBaseClampToEdge(src_tex, src_sampler, uv);
|
|
6430
6430
|
output_buf[y * params.out_w + x] = vec4<f16>(rgba);
|
|
6431
6431
|
}
|
|
6432
|
-
`;var un=a=>typeof VideoFrame<"u"&&a instanceof VideoFrame,
|
|
6432
|
+
`;var un=a=>typeof VideoFrame<"u"&&a instanceof VideoFrame,pe=class{output;device;dtype;sampler;uniformBuffer;dispatch;pipeline2d=null;pipelineExternal=null;stagingTex=null;stagingW=0;stagingH=0;source=null;constructor(t,e,r){this.device=t.device,this.dtype=t.dtype,this.output=t.tensor(e,r,4),this.sampler=this.device.createSampler({magFilter:"linear",minFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),this.uniformBuffer=this.device.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});let n=new ArrayBuffer(16);new Uint32Array(n,0,2).set([r,e]),this.device.queue.writeBuffer(this.uniformBuffer,0,n),this.dispatch=[Math.ceil(r/8),Math.ceil(e/8),1],this.pipeline2d=this.buildPipeline(this.dtype==="f16"?Ft:Et);}setSource(t){this.source=t;}run(){if(!this.source)throw new Error("InputWebGPU.run() called before setSource()");un(this.source)?this.runExternal(this.source):this.run2d(this.source);}run2d(t){this.ensureStagingTexture(t.width,t.height),this.device.queue.copyExternalImageToTexture({source:t,flipY:false},{texture:this.stagingTex},[t.width,t.height]);let e=this.device.createBindGroup({layout:this.pipeline2d.getBindGroupLayout(0),entries:[{binding:0,resource:this.stagingTex.createView()},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipeline2d,e);}runExternal(t){this.pipelineExternal||(this.pipelineExternal=this.buildPipeline(this.dtype==="f16"?Ot:At));let e=this.device.importExternalTexture({source:t}),r=this.device.createBindGroup({layout:this.pipelineExternal.getBindGroupLayout(0),entries:[{binding:0,resource:e},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.uniformBuffer}},{binding:3,resource:{buffer:this.output.buffer}}]});this.dispatchOnce(this.pipelineExternal,r);}ensureStagingTexture(t,e){this.stagingTex&&this.stagingW===t&&this.stagingH===e||(this.stagingTex?.destroy(),this.stagingTex=this.device.createTexture({size:[t,e,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),this.stagingW=t,this.stagingH=e);}buildPipeline(t){let e=this.device.createShaderModule({code:t});return this.device.createComputePipeline({layout:"auto",compute:{module:e,entryPoint:"main"}})}dispatchOnce(t,e){let r=this.device.createCommandEncoder(),n=r.beginComputePass();n.setPipeline(t),n.setBindGroup(0,e),n.dispatchWorkgroups(...this.dispatch),n.end(),this.device.queue.submit([r.finish()]);}};var sn=navigator.gpu?GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST:0,_e=class a{constructor(t,e,r){this.device=t;this.canvas=e;this.dtype=r;this.bytesPerElement=r==="f16"?2:4;let n=e.getContext("webgpu");if(!n)throw new Error("Failed to get WebGPU context from canvas");this.canvasFormat=navigator.gpu.getPreferredCanvasFormat(),this.configureContext(n),this.canvasContext=n,this.contexts.set("main",n),this.ops={Conv2d:(i,o,u)=>new M(this,i,o,u),DepthwiseConv2d:(i,o,u)=>new z(this,i,o,u),Add:(i,o)=>new D(this,i,o),Sigmoid:i=>new R(this,i),Tanh:i=>new H(this,i),ElementwiseMul:(i,o)=>new L(this,i,o),BilinearUpsample:(i,o)=>new V(this,i,o),BicubicUpsample:(i,o)=>new N(this,i,o),ChannelConcat:(i,o)=>new $(this,i,o),Conv2dAdd:(i,o,u,s)=>new j(this,i,o,u,s),ProjResidual:(i,o,u,s)=>new q(this,i,o,u,s),ConcatConv2d:(i,o,u,s)=>new X(this,i,o,u,s),GatesFused:(i,o,u)=>new K(this,i,o,u),CandUpdateFused:(i,o,u,s,l)=>new Y(this,i,o,u,s,l),ConvExpand:(i,o)=>new Q(this,i,o),CatConv6to2:(i,o,u)=>new J(this,i,o,u),DownAdapter:(i,o,u,s)=>new Z(this,i,o,u,s),UpFinal:(i,o,u)=>new ee(this,i,o,u),UpFinalSkip:(i,o,u,s)=>new te(this,i,o,u,s),UpsampleConcat:(i,o,u)=>new re(this,i,o,u),UpsampleConv1x1:(i,o,u)=>new ne(this,i,o,u),UpsampleSigmoid:(i,o)=>new ae(this,i,o),Input:(i,o)=>new pe(this,i,o)},this.presenters={CompositeSolid:(i,o,u,s="main")=>{let l=new ie(this,i,o,u);return {run:()=>{l.setOutput(this.getCurrentDisplayTexture(s)),l.run();}}},CompositeImage:(i,o,u,s="main")=>{let l=new oe(this,i,o,u);return {run:()=>{l.setOutput(this.getCurrentDisplayTexture(s)),l.run();}}},CompositeImageBilinear:(i,o,u,s="main")=>{let l=new ue(this,i,o,u);return {run:()=>{l.setOutput(this.getCurrentDisplayTexture(s)),l.run();}}},CompositePassthrough:(i,o="main")=>{let u=new se(this,i);return {run:()=>{u.setOutput(this.getCurrentDisplayTexture(o)),u.run();}}}};}device;canvas;dtype;ops;presenters;canvasContext;canvasFormat;bytesPerElement;contexts=new Map;configureContext(t){t.configure({device:this.device,format:this.canvasFormat,alphaMode:"premultiplied"});}attachCanvas(t,e){if(t==="main")throw new Error("attachCanvas: 'main' is reserved for the create() canvas");let r=e.getContext("webgpu");if(!r)throw new Error(`attachCanvas: failed to get WebGPU context for target '${t}'`);this.configureContext(r),this.contexts.set(t,r);}static async isAvailable(){return navigator.gpu?await navigator.gpu.requestAdapter()!==null:false}static async hasF16Support(){if(!navigator.gpu)return false;let t=await navigator.gpu.requestAdapter();return t?t.features.has("shader-f16"):false}static async create(t){let e=t.dtype??"f32",r=t.device;if(r){if(e==="f16"&&!r.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but supplied device lacks `shader-f16`")}else {let n=await navigator.gpu.requestAdapter();if(!n)throw new Error("WebGPU adapter not available");if(e==="f16"&&!n.features.has("shader-f16"))throw new Error("WebGPU dtype='f16' requested but adapter lacks `shader-f16` feature");r=await n.requestDevice({requiredFeatures:e==="f16"?["shader-f16"]:[]});}return new a(r,t.canvas,e)}getCurrentDisplayTexture(t="main"){let e=this.contexts.get(t);if(!e)throw new Error(`getCurrentDisplayTexture: no canvas attached for target '${t}'`);return e.getCurrentTexture()}tensor(t,e,r,n){let o=t*e*r*this.bytesPerElement,u=this.device.createBuffer({size:o,usage:sn,mappedAtCreation:n!==void 0});if(n!==void 0){let s=u.getMappedRange();this.writeView(s,n),u.unmap();}return {h:t,w:e,c:r,buffer:u}}upload(t){let r=t.length*this.bytesPerElement,n=this.device.createBuffer({size:r,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:true});return this.writeView(n.getMappedRange(),t),n.unmap(),{buffer:n}}writeView(t,e){let r=this.dtype==="f16",n=e instanceof Uint16Array;if(r===n){r?new Uint16Array(t).set(e):new Float32Array(t).set(e);return}r?new Uint16Array(t).set(Fe(e)):new Float32Array(t).set(ge(e));}async readback(t){let e=this.device.createBuffer({size:t.buffer.size,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),r=this.device.createCommandEncoder();r.copyBufferToBuffer(t.buffer,0,e,0,t.buffer.size),this.device.queue.submit([r.finish()]),await e.mapAsync(GPUMapMode.READ);let n=e.getMappedRange(),i=this.dtype==="f16"?ge(new Uint16Array(n.slice(0))):new Float32Array(n.slice(0));return e.unmap(),e.destroy(),i}copyTensor(t,e){if(t.buffer.size!==e.buffer.size)throw new Error(`copyTensor: size mismatch (src ${t.buffer.size} vs dst ${e.buffer.size})`);let r=this.device.createCommandEncoder();r.copyBufferToBuffer(t.buffer,0,e.buffer,0,t.buffer.size),this.device.queue.submit([r.finish()]);}async sync(){await this.device.queue.onSubmittedWorkDone();}destroy(){this.device.destroy();}};export{fe as EffectsPipeline,_e as WebGPUBackend};
|