face-api/dist/face-api.js

4127 lines
1.1 MiB
JavaScript
Raw Normal View History

2020-11-25 14:30:53 +01:00
var faceapi=(()=>{var pQ=Object.create,lg=Object.defineProperty,hQ=Object.getPrototypeOf,fQ=Object.prototype.hasOwnProperty,dQ=Object.getOwnPropertyNames,mQ=Object.getOwnPropertyDescriptor,IE=i=>lg(i,"__esModule",{value:!0}),ug=(i,a)=>()=>(a||(a={exports:{}},i(a.exports,a)),a.exports),mh=(i,a)=>{IE(i);for(var u in a)lg(i,u,{get:a[u],enumerable:!0})},gQ=(i,a,u)=>{if(IE(i),a&&typeof a=="object"||typeof a=="function")for(let h of dQ(a))!fQ.call(i,h)&&h!=="default"&&lg(i,h,{get:()=>a[h],enumerable:!(u=mQ(a,h))||u.enumerable});return i},te=i=>i&&i.__esModule?i:gQ(lg(i!=null?pQ(hQ(i)):{},"default",{value:i,enumerable:!0}),i),DE=ug((_l,EE)=>{"use strict";var yQ=function(){if(typeof self!="undefined")return self;if(typeof window!="undefined")return window;if(typeof As!="undefined")return As;throw new Error("unable to locate global object")},As=yQ();EE.exports=_l=As.fetch;As.fetch&&(_l.default=As.fetch.bind(As));_l.Headers=As.Headers;_l.Request=As.Request;_l.Response=As.Response}),ee=ug((pg,AE)=>{(function(i,a){typeof pg=="object"&&typeof AE!="undefined"?a(pg):typeof define=="function"&&define.amd?define(["exports"],a):(i=i||self,a(i.tf=i.tf||{}))})(pg,function(i){"use strict";let a=1e-7,u=1e-4;class h{constructor(t,e){this.backend=t,this.dataMover=e,this.data=new WeakMap,this.dataIdsCount=0}get(t){return this.data.has(t)||this.dataMover.moveData(this.backend,t),this.data.get(t)}set(t,e){this.dataIdsCount++,this.data.set(t,e)}has(t){return this.data.has(t)}delete(t){return this.dataIdsCount--,this.data.delete(t)}numDataIds(){return this.dataIdsCount}}class d{time(t){return g("time")}read(t){return g("read")}readSync(t){return g("readSync")}numDataIds(){return g("numDataIds")}disposeData(t){return g("disposeData")}write(t,e,r){return g("write")}move(t,e,r,o){return g("move")}memory(){return g("memory")}floatPrecision(){return g("floatPrecision")}epsilon(){return this.floatPrecision()===32?a:u}batchMatMul(t,e,r,o){return g("batchMatMul")}fusedBatchMatMul({a:t,b:e,transposeA:r,transposeB:o,bias:s,activation:c,preluActivationWeights:l}){return g("fusedBatchMatMul")}slice(t,e,r){return g("slice")}stridedSlice(t,e,r,o){return g("stridedSlice")}unstack(t,e){return g("unstack")}reverse(t,e){return g("reverse")}concat(t,e){return g("concat")}neg(t){return g("neg")}add(t,e){return g("add")}addN(t){return g("addN")}subtract(t,e){return g("subtract")}multiply(t,e){return g("multiply")}realDivide(t,e){return g("realDivide")}floorDiv(t,e){return g("floorDiv")}sum(t,e){return g("sum")}prod(t,e){return g("prod")}unsortedSegmentSum(t,e,r){return g("unsortedSegmentSum")}argMin(t,e){return g("argMin")}argMax(t,e){return g("argMax")}equal(t,e){return g("equal")}notEqual(t,e){return g("notEqual")}less(t,e){return g("less")}lessEqual(t,e){return g("lessEqual")}greater(t,e){return g("greater")}greaterEqual(t,e){return g("greaterEqual")}logicalNot(t){return g("logicalNot")}logicalAnd(t,e){return g("logicalAnd")}logicalOr(t,e){return g("logicalOr")}where(t){return g("where")}select(t,e,r){return g("select")}topk(t,e,r){return g("topk")}min(t,e){return g("min")}minimum(t,e){return g("minimum")}mod(t,e){return g("mod")}max(t,e){return g("max")}maximum(t,e){return g("maximum")}all(t,e){return g("all")}any(t,e){return g("any")}squaredDifference(t,e){return g("squaredDifference")}ceil(t){return g("ceil")}floor(t){return g("floor")}round(t){return g("round")}sign(t){return g("sign")}isNaN(t){return g("isNaN")}isInf(t){return g("isInf")}isFinite(t){return g("isFinite")}pow(t,e){return g("pow")}exp(t){return g("exp")}expm1(t){return g("expm1")}softmax(t,e){return g("softmax")}log(t){return g("log")}log1p(t){return g("log1p")}sqrt(t){return g("sqrt")}rsqrt(t){return g("rsqrt")}square(t){return g("square")}reciprocal(t){return g("reciprocal")}relu(t){return g("relu")}relu6(t){return g("relu6")}prelu(t,e){return g("prelu")}elu(t){return g("elu")}eluDer(t,e){return g("eluDer")}selu(t){return g("selu")}int(t){return g("int")}clip(t,e,r){return g("clip")}abs(t){return g("abs")}complexAbs(t){return g("complexAbs")}sigmoid(t){return g("sigmoid")}softplus(t){return g("s
`)),p.join(`
`)}function JP(n,t,e,r){let o=G(t),s=r[r.length-1],c=new Array(s).fill(0),l=t.length,p=e==="complex64"?Qu(n):n;if(l>1)for(let f=0;f<o/s;f++){let m=f*s;for(let y=0;y<s;y++)c[y]=Math.max(c[y],Zu(p[m+y],0,e).length)}return c}function Zu(n,t,e){let r;return Array.isArray(n)?r=`${parseFloat(n[0].toFixed(Hx))} + ${parseFloat(n[1].toFixed(Hx))}j`:us(n)?r=`'${n}'`:e==="bool"?r=BN(n):r=parseFloat(n.toFixed(Hx)).toString(),fe(r,t)}function BN(n){return n===0?"false":"true"}function sd(n,t,e,r,o,s=!0){let c=e==="complex64"?2:1,l=t[0],p=t.length;if(p===0){if(e==="complex64"){let N=Qu(n);return[Zu(N[0],0,e)]}return e==="bool"?[BN(n[0])]:[n[0].toString()]}if(p===1){if(l>MN){let S=Ju*c,D=Array.from(n.slice(0,S)),I=Array.from(n.slice((l-Ju)*c,l*c));return e==="complex64"&&(D=Qu(D),I=Qu(I)),["["+D.map((P,E)=>Zu(P,o[E],e)).join(", ")+", ..., "+I.map((P,E)=>Zu(P,o[l-Ju+E],e)).join(", ")+"]"]}let N=e==="complex64"?Qu(n):Array.from(n);return["["+N.map((S,D)=>Zu(S,o[D],e)).join(", ")+"]"]}let f=t.slice(1),m=r.slice(1),y=r[0]*c,b=[];if(l>MN){for(let N=0;N<Ju;N++){let S=N*y,D=S+y;b.push(...sd(n.slice(S,D),f,e,m,o,!1))}b.push("...");for(let N=l-Ju;N<l;N++){let S=N*y,D=S+y;b.push(...sd(n.slice(S,D),f,e,m,o,N===l-1))}}else for(let N=0;N<l;N++){let S=N*y,D=S+y;b.push(...sd(n.slice(S,D),f,e,m,o,N===l-1))}let v=p===2?",":"";b[0]="["+b[0]+v;for(let N=1;N<b.length-1;N++)b[N]=" "+b[N]+v;let T=`,
`;for(let N=2;N<p;N++)T+=`
`;return b[b.length-1]=" "+b[b.length-1]+"]"+(s?"":T),b}function Qu(n){let t=[];for(let e=0;e<n.length;e+=2)t.push([n[e],n[e+1]]);return t}class hn{constructor(t,e,r){if(this.dtype=e,this.shape=t.slice(),this.size=G(t),r!=null){let o=r.length;_(o===this.size,()=>`Length of values '${o}' does not match the size inferred by the shape '${this.size}'.`)}if(e==="complex64")throw new Error("complex64 dtype TensorBuffers are not supported. Please create a TensorBuffer for the real and imaginary parts separately and call tf.complex(real, imag).");this.values=r||or(e,this.size),this.strides=Jt(t)}set(t,...e){e.length===0&&(e=[0]),_(e.length===this.rank,()=>`The number of provided coordinates (${e.length}) must match the rank (${this.rank})`);let r=this.locToIndex(e);this.values[r]=t}get(...t){t.length===0&&(t=[0]);let e=0;for(let o of t){if(o<0||o>=this.shape[e]){let s=`Requested out of range element at ${t}. Buffer shape=${this.shape}`;throw new Error(s)}e++}let r=t[t.length-1];for(let o=0;o<t.length-1;++o)r+=this.strides[o]*t[o];return this.values[r]}locToIndex(t){if(this.rank===0)return 0;if(this.rank===1)return t[0];let e=t[t.length-1];for(let r=0;r<t.length-1;++r)e+=this.strides[r]*t[r];return e}indexToLoc(t){if(this.rank===0)return[];if(this.rank===1)return[t];let e=new Array(this.shape.length);for(let r=0;r<e.length-1;++r)e[r]=Math.floor(t/this.strides[r]),t-=e[r]*this.strides[r];return e[e.length-1]=t,e}get rank(){return this.shape.length}toTensor(){return Mo().makeTensor(this.values,this.shape,this.dtype)}}let Mo=null,$c=null,zN=null;function ZP(n){Mo=n}function QP(n){$c=n}function tO(n){zN=n}class ot{constructor(t,e,r,o){this.kept=!1,this.isDisposedInternal=!1,this.shape=t.slice(),this.dtype=e||"float32",this.size=G(t),this.strides=Jt(t),this.dataId=r,this.id=o,this.rankType=this.rank<5?this.rank.toString():"higher"}get rank(){return this.shape.length}async buffer(){let t=await this.data();return $c.buffer(this.shape,this.dtype,t)}bufferSync(){return $c.buffer(this.shape,this.dtype,this.dataSync())}async array(){let t=await this.data();return Dr(this.shape,t)}arraySync(){return Dr(this.shape,this.dataSync())}async data(){this.throwIfDisposed();let t=Mo().read(this.dataId);if(this.dtype==="string"){let e=await t;try{return e.map(r=>Yu(r))}catch(r){throw new Error("Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().")}}return t}dataSync(){this.throwIfDisposed();let t=Mo().readSync(this.dataId);if(this.dtype==="string")try{return t.map(e=>Yu(e))}catch(e){throw new Error("Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().")}return t}async bytes(){this.throwIfDisposed();let t=await Mo().read(this.dataId);return this.dtype==="string"?t:new Uint8Array(t.buffer)}dispose(){if(this.isDisposed)return;Mo().disposeTensor(this),this.isDisposedInternal=!0}get isDisposed(){return this.isDisposedInternal}throwIfDisposed(){if(this.isDisposed)throw new Error("Tensor is disposed.")}print(t=!1){return $c.print(this,t)}clone(){return this.throwIfDisposed(),$c.clone(this)}toString(t=!1){let e=this.dataSync();return YP(e,this.shape,this.dtype,t)}cast(t){return this.throwIfDisposed(),$c.cast(this,t)}variable(t=!0,e,r){return this.throwIfDisposed(),Mo().makeVariable(this,t,e,r)}}Object.defineProperty(ot,Symbol.hasInstance,{value:n=>!!n&&n.data!=null&&n.dataSync!=null&&n.throwIfDisposed!=null});class tp extends ot{constructor(t,e,r,o){super(t.shape,t.dtype,t.dataId,o);this.trainable=e,this.name=r}assign(t){if(t.dtype!==this.dtype)throw new Error(`dtype of the new value (${t.dtype}) and previous value (${this.dtype}) must match`);if(!lt(t.shape,this.shape))throw new Error(`shape of the new value (${t.shape}) and previous value (${this.shape}) must match`);Mo().disposeTensor(this),this.dataId=t.dataId,Mo().incRef(this,null)}dispose(){Mo().disposeVariable(this),this.isDisposedInternal=!0}}Object.defineProperty(tp,Symbol.hasInstance,{value:n=>n instanceof ot&&n.assign!=null&&n.assign instanceof Function});(function(n){n.R0="R0",n.R1="R1",n.R2="R2",n.R3="R3",n.R4="
Manifest JSON has weights with names: ${l.join(", ")}.`)}let p=o.reduce((v,T,N)=>(T&&v.push(N),v),[]),f=[];p.forEach(v=>{t[v].paths.forEach(T=>{let N=e+(e.endsWith("/")?"":"/")+T;f.push(N)})});let m=await n(f),y={},b=0;return p.forEach(v=>{let T=t[v].paths.length,N=0;for(let E=0;E<T;E++)N+=m[b+E].byteLength;let S=new ArrayBuffer(N),D=new Uint8Array(S),I=0;for(let E=0;E<T;E++){let L=new Uint8Array(m[b+E]);D.set(L,I),I+=L.byteLength}let P=s[v];P.forEach(E=>{let L=S.slice(E.groupOffset,E.groupOffset+E.sizeBytes),B=ld(L,[E.manifestEntry]);for(let q in B)y[q]=B[q]}),b+=T}),y}}let qO="application/octet-stream",HO="application/json";class iw{constructor(t,e){if(this.DEFAULT_METHOD="POST",e==null&&(e={}),this.weightPathPrefix=e.weightPathPrefix,this.onProgress=e.onProgress,this.weightUrlConverter=e.weightUrlConverter,e.fetchFunc!=null?(_(typeof e.fetchFunc=="function",()=>"Must pass a function that matches the signature of `fetch` (see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)"),this.fetch=e.fetchFunc):this.fetch=ct().platform.fetch,_(t!=null&&t.length>0,()=>"URL path for http must not be null, undefined or empty."),Array.isArray(t)&&_(t.length===2,()=>`URL paths for http must have a length of 2, (actual length is ${t.length}).`),this.path=t,e.requestInit!=null&&e.requestInit.body!=null)throw new Error("requestInit is expected to have no pre-existing body, but has one.");this.requestInit=e.requestInit||{}}async save(t){if(t.modelTopology instanceof ArrayBuffer)throw new Error("BrowserHTTPRequest.save() does not support saving model topology in binary formats yet.");let e=Object.assign({method:this.DEFAULT_METHOD},this.requestInit);e.body=new FormData;let r=[{paths:["./model.weights.bin"],weights:t.weightSpecs}],o={modelTopology:t.modelTopology,format:t.format,generatedBy:t.generatedBy,convertedBy:t.convertedBy,userDefinedMetadata:t.userDefinedMetadata,weightsManifest:r};e.body.append("model.json",new Blob([JSON.stringify(o)],{type:HO}),"model.json"),t.weightData!=null&&e.body.append("model.weights.bin",new Blob([t.weightData],{type:qO}),"model.weights.bin");let s=await this.fetch(this.path,e);if(s.ok)return{modelArtifactsInfo:np(t),responses:[s]};throw new Error(`BrowserHTTPRequest.save() failed due to HTTP response status ${s.status}.`)}async load(){let t=await this.fetch(this.path,this.requestInit);if(!t.ok)throw new Error(`Request to ${this.path} failed with status code ${t.status}. Please verify this URL points to the model JSON of the model to load.`);let e;try{e=await t.json()}catch(v){let T=`Failed to parse model JSON of response from ${this.path}.`;throw this.path.endsWith(".pb")?T+=" Your path contains a .pb file extension. Support for .pb models have been removed in TensorFlow.js 1.0 in favor of .json models. You can re-convert your Python TensorFlow model using the TensorFlow.js 1.0 conversion scripts or you can convert your.pb models with the 'pb2json'NPM script in the tensorflow/tfjs-converter repository.":T+=" Please make sure the server is serving valid JSON for this request.",new Error(T)}let r=e.modelTopology,o=e.weightsManifest,s=e.generatedBy,c=e.convertedBy,l=e.format,p=e.userDefinedMetadata;if(r==null&&o==null)throw new Error(`The JSON from HTTP path ${this.path} contains neither model topology or manifest for weights.`);let f,m;if(o!=null){let v=await this.loadWeights(o);[f,m]=v}let y={modelTopology:r,weightSpecs:f,weightData:m,userDefinedMetadata:p,generatedBy:s,convertedBy:c,format:l},b=e.modelInitializer;return b&&(y.modelInitializer=b),y}async loadWeights(t){let e=Array.isArray(this.path)?this.path[1]:this.path,[r,o]=jO(e),s=this.weightPathPrefix||r,c=[];for(let m of t)c.push(...m.weights);let l=[],p=[];for(let m of t)for(let y of m.paths)this.weightUrlConverter!=null?p.push(this.weightUrlConverter(y)):l.push(s+y+o);this.weightUrlConverter&&l.push(...await Promise.all(p));let f=await i_(l,{requestInit:this.requestInit,fetchFunc:this.fetch,onProgress:this.onProgress});return[c,ud(f)]}}iw.URL_SCHEME_REGEX=/^https?:\/\//;function jO(n){let t=n.lastIndexOf("/"),e=n.lastIndexOf("?"),r=n.su
Actual: ${o}.
Expected: ${s}.`);for(let c=0;c<s.length;++c){let l=o[c],p=s[c];if(!e(l,p))throw new Error(`Arrays differ: actual[${c}] = ${l}, expected[${c}] = ${p}.
Actual: ${o}.
Expected: ${s}.`)}}function fL(n,t){n().then(()=>t.fail(),()=>t())}function dL(n,t){let e=typeof t=="string"||typeof t=="number"||typeof t=="boolean"?[t]:t;return us(n)||us(n[0])||us(t)||us(t[0])?mw(n,e,(r,o)=>r==o):mw(n,t,(r,o)=>yw(r,o,0))}function gw(n,t,e){if(e==null&&(e=bd()),!yw(n,t,e))throw new Error(`Numbers differ: actual === ${n}, expected === ${t}`)}function yw(n,t,e){return!isFinite(n)&&!isFinite(t)?!0:!(isNaN(n)||isNaN(t)||Math.abs(n-t)>e)}function mL(n,t,e){for(let r=0;r<n.length;r++)if(n[r]<t||n[r]>e)throw new Error(`Value out of range:${n[r]} low: ${t}, high: ${e}`)}function gL(n,t){expect(new Float32Array(n)).toEqual(new Float32Array(t))}var yL=Object.freeze({__proto__:null,TEST_EPSILON_FLOAT16:T_,expectArraysClose:hL,testEpsilon:bd,expectPromiseToFail:fL,expectArraysEqual:dL,expectNumbersClose:gw,expectValuesInRange:mL,expectArrayBuffersEqual:gL});let k_="2.7.0";function bL(){ct().set("PROD",!0)}function xL(){ct().set("DEBUG",!0)}function wL(){ct().set("DEPRECATION_WARNINGS_ENABLED",!1),console.warn("TensorFlow.js deprecation warnings have been disabled.")}function yn(n){ct().getBool("DEPRECATION_WARNINGS_ENABLED")&&console.warn(n+" You can disable deprecation warnings with tf.disableDeprecationWarnings().")}tO(yn);function vL(){X.disposeVariables()}function ds(){return X}function xd(){return X.memory()}function TL(n){return X.profile(n)}function rt(n,t){return X.tidy(n,t)}function Xt(n){let t=ps(n);t.forEach(e=>e.dispose())}function Sn(n){return X.keep(n)}function kL(n){return X.time(n)}function N_(n){return X.setBackend(n)}function NL(){return X.ready()}function _L(){return X.backendName}function CL(n){X.removeBackend(n)}function SL(n){return X.findBackend(n)}function $L(n){return X.findBackendFactory(n)}function bw(n,t,e=1){return X.registerBackend(n,t,e)}function __(){return X.backend}function IL(n,t){ct().setPlatform(n,t)}function EL(n,t){let e=M(n,"a","add"),r=M(t,"b","add");[e,r]=Je(e,r);let o=(c,l)=>{let p=c.add(e,r);return l([e,r]),p},s={a:e,b:r};return X.runKernelFunc(o,s,null,Zi)}let Tt=j({add_:EL});function DL(n,t){let e=M(n,"a","floorDiv"),r=M(t,"b","floorDiv");[e,r]=Je(e,r);let o=(c,l)=>{let p=c.floorDiv(e,r);return l([e,r]),p},s={a:e,b:r};return X.runKernelFunc(o,s,null,gx)}let wd=j({floorDiv_:DL});function AL(n,t){let e=M(n,"a","div"),r=M(t,"b","div");if([e,r]=Je(e,r),e.dtype==="int32"&&r.dtype==="int32")return wd(e,r);let o=(l,p)=>{let f=l.realDivide(e,r);return p([e,r]),f},s={a:e,b:r},c={};return X.runKernelFunc(o,s,null,vc,c)}let Bt=j({div_:AL});function FL(n,t){let e=M(n,"a","mul"),r=M(t,"b","mul");[e,r]=Je(e,r);let o=(c,l)=>{let p=c.multiply(e,r);return l([e,r]),p},s={a:e,b:r};return X.runKernelFunc(o,s,null,Tc)}let nt=j({mul_:FL});function RL(n){let t=M(n,"x","abs"),e={x:t};return X.runKernelFunc((r,o)=>(o([t]),t.dtype==="complex64"?r.complexAbs(t):r.abs(t)),e,null,kf)}let bn=j({abs_:RL});function PL(n){let t=M(n,"x","acos"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.acos(t);return o([t]),s},e,null,au)}let xw=j({acos_:PL});function OL(n){let t=M(n,"x","acosh"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.acosh(t);return o([t]),s},e,null,cu)}let ww=j({acosh_:OL});function LL(n){_(Array.isArray(n),()=>"The argument passed to tf.addN() must be a list of tensors"),_(n.length>=1,()=>`Must pass at least one tensor to tf.addN(), but got ${n.length}`);let t=n.map((s,c)=>M(s,`tensors${c}`,"addN")),e=t[0];t.forEach(s=>{if(s.dtype!==e.dtype)throw new Error("All tensors passed to tf.addN() must have the same dtype")}),t.forEach(s=>{if(!lt(s.shape,e.shape))throw new Error("All tensors passed to tf.addN() must have the same shape")});let r=(s,c)=>{let l=s.addN(t);return c(t),l},o=t;return X.runKernelFunc(r,o,null,rx)}let C_=j({addN_:LL});function vw(n,t){for(let e=0;e<n.length;++e)if(n[n.length-e-1]!==t-1-e)return!1;return!0}function S_(n,t,e){let r=n.length+t.length,o=[],s=0,c=0;for(let l=0;l<r;l++)e.indexOf(l)===-1?o.push(n[s++]):o.push(t[c++]);return o}function Rn(n,t){let e=[],r=n.length;for(let s=0;s<r;s++)t.indexOf(s)===-1&&e.push(n[s]);let o=t.map(s=>n[s]);return[e,o]}function Pn(n,
with dtype ${c.dtype}. `)});let r=(c,l)=>{let p=Vt(t,e[0].shape)[0],f=ms(e.map(b=>b.shape),p);if(G(f)===0)return un([],f);if(e=e.filter(b=>b.size>0),e.length===1)return e[0];let m=e.map(b=>b.shape);Nd(m,p);let y=c.concat(e,p);return l(e),y},o=e,s={axis:t};return X.runKernelFunc(r,o,null,gu,s)}let Qe=j({concat_:QL});function tM(n){let t=M(n,"x","sigmoid"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.sigmoid(t);return o([s]),s},e,null,Gu)}let Wo=j({sigmoid_:tM});function eM(n,t,e){let r=M(n,"x","slice");if(r.rank===0)throw new Error("Slicing scalar is not possible");let o=(l,p)=>{let[f,m]=yd(r,t,e);return hw(r,f,m),p([r]),l.slice(r,f,m)},s={x:r},c={begin:t,size:e};return X.runKernelFunc(o,s,null,jf,c)}let ce=j({slice_:eM});function nM(n){let t=M(n,"x","tanh"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.tanh(t);return o([s]),s},e,null,Hu)}let Pc=j({tanh_:nM});function rM(n,t,e,r,o,s){let c=M(n,"forgetBias","basicLSTMCell"),l=M(t,"lstmKernel","basicLSTMCell"),p=M(e,"lstmBias","basicLSTMCell"),f=M(r,"data","basicLSTMCell"),m=M(o,"c","basicLSTMCell"),y=M(s,"h","basicLSTMCell"),b=Qe([f,y],1),v=ge(b,l),T=Tt(v,p),N=T.shape[0],S=T.shape[1]/4,D=[N,S],I=ce(T,[0,0],D),P=ce(T,[0,S],D),E=ce(T,[0,S*2],D),L=ce(T,[0,S*3],D),B=Tt(nt(Wo(I),Pc(P)),nt(m,Wo(Tt(c,E)))),q=nt(Pc(B),Wo(L));return[B,q]}let oM=j({basicLSTMCell_:rM});function sM(n,t,e){let r=M(n,"x","batchToSpaceND"),o=t.reduce((p,f)=>p*f);_(r.rank>=1+t.length,()=>`input rank is ${r.rank} but should be > than blockShape.length ${t.length}`),_(e.length===t.length,()=>`crops.length is ${e.length} but should be equal to blockShape.length ${t.length}`),_(r.shape[0]%o===0,()=>`input tensor batch is ${r.shape[0]} but is not divisible by the product of the elements of blockShape ${t.join(" * ")} === ${o}`);let s=p=>p.batchToSpaceND(r,t,e),c={x:r},l={blockShape:t,crops:e};return X.runKernelFunc(s,c,null,ax,l)}let cp=j({batchToSpaceND_:sM});function iM(n){let t;return n.rank===0||n.rank===1?t=Q(n,[1,1,1,n.size]):n.rank===2?t=Q(n,[1,1,n.shape[0],n.shape[1]]):n.rank===3?t=Q(n,[1,n.shape[0],n.shape[1],n.shape[2]]):t=n,t}function aM(n,t,e,r,o,s){s==null&&(s=.001);let c=M(n,"x","batchNorm"),l=M(t,"mean","batchNorm"),p=M(e,"variance","batchNorm"),f;o!=null&&(f=M(o,"scale","batchNorm"));let m;r!=null&&(m=M(r,"offset","batchNorm")),_(l.rank===p.rank,()=>"Batch normalization gradient requires mean and variance to have equal ranks."),_(m==null||l.rank===m.rank,()=>"Batch normalization gradient requires mean and offset to have equal ranks."),_(f==null||l.rank===f.rank,()=>"Batch normalization gradient requires mean and scale to have equal ranks.");let y=iM(c),b=(S,D)=>(D([y,l,p,f]),S.batchNorm(y,_d(l),_d(p),_d(m),_d(f),s)),v={x:y,scale:f,offset:m,mean:l,variance:p},T={varianceEpsilon:s},N=X.runKernelFunc(b,v,null,ku,T);return Q(N,c.shape)}function _d(n){return n==null?null:n.rank===0?Q(n,[n.size]):n.rank===1?n:n.rank===2?Q(n,[1,1,n.shape[0],n.shape[1]]):n.rank===3?Q(n,[1,n.shape[0],n.shape[1],n.shape[2]]):n}let aa=j({batchNorm_:aM});function cM(n,t,e,r,o,s){let c=M(n,"x","batchNorm"),l=M(t,"mean","batchNorm"),p=M(e,"variance","batchNorm"),f;o!=null&&(f=M(o,"scale","batchNorm"));let m;return r!=null&&(m=M(r,"offset","batchNorm")),_(c.rank===2,()=>`Error in batchNorm2D: x must be rank 2 but got rank ${c.rank}.`),_(l.rank===2||l.rank===1,()=>`Error in batchNorm2D: mean must be rank 2 or rank 1 but got rank ${l.rank}.`),_(p.rank===2||p.rank===1,()=>`Error in batchNorm2D: variance must be rank 2 or rank 1 but got rank ${p.rank}.`),f!=null&&_(f.rank===2||f.rank===1,()=>`Error in batchNorm2D: scale must be rank 2 or rank 1 but got rank ${f.rank}.`),m!=null&&_(m.rank===2||m.rank===1,()=>`Error in batchNorm2D: offset must be rank 2 or rank 1 but got rank ${m.rank}.`),aa(c,l,p,m,f,s)}let $_=j({batchNorm2d_:cM});function lM(n,t,e,r,o,s){let c=M(n,"x","batchNorm"),l=M(t,"mean","batchNorm"),p=M(e,"variance","batchNorm"),f;o!=null&&(f=M(o,"scale","batchNorm"));let m;return r!=null&&(m=M(r,"offset","batchNorm")),_(c.rank===3,()=>`Error in batchNorm3D: x must be rank 3 but got rank ${c.rank}.`),_(l.ran
${o} and ${t} for depthToSpace with input shape
${r.shape}`),_(s*t>=0,()=>`Negative dimension size caused by overflow when multiplying
${s} and ${t} for depthToSpace with input shape
${r.shape}`),_(c%(t*t)===0,()=>`Dimension size must be evenly divisible by ${t*t} but is ${c} for depthToSpace with input shape ${r.shape}`);let l=m=>m.depthToSpace(r,t,e),p={x:r},f={blockSize:t,dataFormat:e};return X.runKernelFunc(l,p,null,dN,f)}let Rw=j({depthToSpace_:IM});function EM(n,t,e,r,o="NHWC",s=[1,1],c){let l=M(n,"x","depthwiseConv2d"),p=M(t,"filter","depthwiseConv2d"),f=l,m=!1;l.rank===3&&(m=!0,f=Q(l,[1,l.shape[0],l.shape[1],l.shape[2]])),_(f.rank===4,()=>`Error in depthwiseConv2d: input must be rank 4, but got rank ${f.rank}.`),_(p.rank===4,()=>`Error in depthwiseConv2d: filter must be rank 4, but got rank ${p.rank}.`),_(f.shape[3]===p.shape[2],()=>`Error in depthwiseConv2d: number of input channels (${f.shape[3]}) must match the inChannels dimension in filter ${p.shape[2]}.`),c!=null&&_(gt(r),()=>`Error in depthwiseConv2d: pad must be an integer when using, dimRoundingMode ${c} but got pad ${r}.`);let y=(N,S)=>{s==null&&(s=[1,1]),_(fn(e,s),()=>`Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${e} and dilations '${s}'`);let D=Un(f.shape,p.shape,e,s,r,c,!0),I=N.depthwiseConv2D(f,p,D);return S([f,p]),I},b={x:f,filter:p},v={strides:e,pad:r,dataFormat:o,dilations:s,dimRoundingMode:c},T=X.runKernelFunc(y,b,null,Df,v);return m?Q(T,[T.shape[1],T.shape[2],T.shape[3]]):T}let ca=j({depthwiseConv2d_:EM});function DM(n){let t=M(n,"x","diag"),e=o=>{let s=Q(t,[t.size]),c=o.diag(s),l=[...n.shape,...n.shape];return Q(c,l)},r={x:t};return X.runKernelFunc(e,r,null,mN)}let AM=j({diag_:DM});function FM(n,t,e,r,o=[1,1],s="NHWC"){let c=M(n,"x","dilation2d"),l=M(t,"filter","dilation2d");_(c.rank===3||c.rank===4,()=>`Error in dilation2d: input must be rank 3 or 4, but got rank ${c.rank}.`),_(l.rank===3,()=>`Error in dilation2d: filter must be rank 3, but got rank ${l.rank}.`),_(s==="NHWC",()=>`Error in dilation2d: Only NHWC is currently supported, but got dataFormat of ${s}`);let p=c,f=!1;c.rank===3&&(p=Q(c,[1,c.shape[0],c.shape[1],c.shape[2]]),f=!0);let m={x:p,filter:l},y={strides:e,pad:r,dilations:o},b=X.runKernel(Af,m,y);return f?Q(b,[b.shape[1],b.shape[2],b.shape[3]]):b}let Pw=j({dilation2d_:FM});function la(n,t){let e=n.length,r=[];for(let o=0;o<e;o++){let s=e-1-o,c=n[s]||1,l=t[t.length-1-o]||1;l>1&&c===1&&r.unshift(s)}return r}function xn(n,t){let e=[];for(let r=0;r<t.length;r++){let o=n[n.length-r-1],s=t.length-r-1,c=t[s];(o==null||o===1&&c>1)&&e.unshift(s)}return e}function le(n,t){let e=[],r=Math.max(n.length,t.length);for(let o=0;o<r;o++){let s=n[n.length-o-1];s==null&&(s=1);let c=t[t.length-o-1];if(c==null&&(c=1),s===1)e.unshift(c);else if(c===1)e.unshift(s);else if(s!==c){let l=`Operands could not be broadcast together with shapes ${n} and ${t}.`;throw Error(l)}else e.unshift(s)}return e}function RM(n,t){let e=M(n,"a","equal"),r=M(t,"b","equal");[e,r]=Je(e,r),le(e.shape,r.shape);let o=c=>c.equal(e,r),s={a:e,b:r};return X.runKernelFunc(o,s,null,yN)}let ho=j({equal_:RM});function PM(n,t,e){let r=M(t,"a","where"),o=M(e,"b","where"),s=M(n,"condition","where","bool"),c=le(r.shape,o.shape),l=lp(r,c),p=lp(o,c);s.rank===1&&_(s.shape[0]===r.shape[0],()=>"The first dimension of `a` must match the size of `condition`."),s.rank!==1&&W(s.shape,p.shape,"Error in where: ");let f=(y,b)=>{let v=y.select(s,l,p);return b([s]),v},m={condition:s,t:l,e:p};return X.runKernelFunc(f,m,null,Px)}let Yn=j({where_:PM});function OM(n){let t=M(n,"x","zerosLike"),e={x:t};return X.runKernelFunc(r=>r.zerosLike(t),e,null,Vx)}let re=j({zerosLike_:OM});function LM(n,t){let e=M(n,"a","div"),r=M(t,"b","div");[e,r]=Je(e,r);let o=Bt(e,r),s=re(o),c=ho(r,s);return Yn(c,s,o)}let Ow=j({divNoNan_:LM});function MM(n,t){let e=M(n,"t1","dot"),r=M(t,"t2","dot");_((e.rank===1||e.rank===2)&&(r.rank===1||r.rank===2),()=>`Error in dot: inputs must all be rank 1 or 2, but got ranks ${e.rank} and ${r.rank}.`);let o=e.rank===1?e.size:e.shape[1],s=r.rank===1?r.size:r.shape[0];if(_(o===s,()=>`Error in dot: inner dimensions of inputs must match, but got ${o} and ${s}.`),e.rank===1&&r.rank===1){let c=Q(e,[1,-1]),l=Q(r,[-1,1]),p=ge(c,l);return
rank ${s.rank}.`),_(gt(t),()=>`Error in localResponseNormalization: depthRadius must be an integer but got depthRadius ${t}.`);let c=s,l=!1;s.rank===3&&(l=!0,c=Q(s,[1,s.shape[0],s.shape[1],s.shape[2]]));let p=(b,v)=>{let T=b.localResponseNormalization4D(c,t,e,r,o);return v([c,T]),T},f={x:c},m={depthRadius:t,bias:e,alpha:r,beta:o},y=X.runKernelFunc(p,f,null,wx,m);return l?Q(y,[y.shape[1],y.shape[2],y.shape[3]]):y}let zw=j({localResponseNormalization_:aB});function cB(n){let t=M(n,"x","log"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.log(t);return o([t]),s},e,null,$u)}let wr=j({log_:cB});function lB(n){let t=M(n,"x","log1p"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.log1p(t);return o([t]),s},e,null,Iu)}let Ad=j({log1p_:lB});function uB(n){return _(ni(n),()=>"The f passed in grad(f) must be a function"),(t,e)=>{let r=M(t,"x","tf.grad",null),o=e!=null?M(e,"dy","tf.grad"):null;return X.tidy(()=>{let{value:s,grads:c}=X.gradients(()=>n(r),[r],o);return o!=null&&W(s.shape,o.shape,"The shape of dy passed in grad(f)(x, dy) must match the shape returned by f(x)"),Fd(c),c[0]})}}function pB(n){return _(ni(n),()=>"The f passed in grads(f) must be a function"),(t,e)=>{_(Array.isArray(t),()=>"The args passed in grads(f)(args) must be an array of `Tensor`s or `TensorLike`s");let r=ep(t,"args","tf.grads",null),o=e!=null?M(e,"dy","tf.grads"):null;return X.tidy(()=>{let{value:s,grads:c}=X.gradients(()=>n(...r),r,o);return o!=null&&W(s.shape,o.shape,"The shape of dy passed in grads(f)([x1,...], dy) must match the shape returned by f([x1,...])"),Fd(c),c})}}function hB(n){return _(ni(n),()=>"The f passed in valueAndGrad(f) must be a function"),(t,e)=>{_(t instanceof ot,()=>"The x passed in valueAndGrad(f)(x) must be a tensor"),_(e==null||e instanceof ot,()=>"The dy passed in valueAndGrad(f)(x, dy) must be a tensor");let{grads:r,value:o}=X.gradients(()=>n(t),[t],e);return Fd(r),{grad:r[0],value:o}}}function fB(n){return _(ni(n),()=>"The f passed in valueAndGrads(f) must be a function"),(t,e)=>{_(Array.isArray(t)&&t.every(o=>o instanceof ot),()=>"The args passed in valueAndGrads(f)(args) must be array of tensors"),_(e==null||e instanceof ot,()=>"The dy passed in valueAndGrads(f)(args, dy) must be a tensor");let r=X.gradients(()=>n(...t),t,e);return e!=null&&W(r.value.shape,e.shape,"The shape of dy passed in valueAndGrads(f)([x1,...], dy) must match the shape returned by f([x1,...])"),Fd(r.grads),r}}function Ww(n,t){_(ni(n),()=>"The f passed in variableGrads(f) must be a function"),_(t==null||Array.isArray(t)&&t.every(f=>f instanceof tp),()=>"The varList passed in variableGrads(f, varList) must be an array of variables");let e=t!=null;if(!e){t=[];for(let f in X.registeredVariables)t.push(X.registeredVariables[f])}let r=e?t.filter(f=>!f.trainable):null,o=t.length;t=t.filter(f=>f.trainable),_(t.length>0,()=>`variableGrads() expects at least one of the input variables to be trainable, but none of the ${o} variables is trainable.`);let s=!0,{value:c,grads:l}=X.gradients(n,t,null,s);_(l.some(f=>f!=null),()=>"Cannot find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize()."),_(c.rank===0,()=>`The f passed in variableGrads(f) must return a scalar, but it returned a rank-${c.rank} tensor`);let p={};return t.forEach((f,m)=>{l[m]!=null&&(p[f.name]=l[m])}),r!=null&&r.forEach(f=>p[f.name]=null),{value:c,grads:p}}function Vo(n){return X.customGrad(n)}function Fd(n){let t=n.filter(e=>e==null).length;if(t>0)throw new Error(`Cannot compute gradient of y=f(x) with respect to x. Make sure that
the f you passed encloses all operations that lead from x to y.`)}function dB(n){let t=M(n,"x","neg"),e={x:t};return X.runKernelFunc(r=>r.neg(t),e,null,Sx)}let tn=j({neg_:dB});function mB(n){let t=M(n,"x","softplus"),e={x:t};return X.runKernelFunc((r,o)=>{let s=r.softplus(t);return o([t]),s},e,null,Uu)}let zc=j({softplus_:mB});function gB(n){let t=M(n,"x","logSigmoid"),e=Vo(r=>{let o=tn(zc(tn(r))),s=c=>{let l=nt(c,Wo(tn(r)));return l};return{value:o,gradFunc:s}});return e(t)}let V_=j({logSigmoid_:gB});function yB(n,t=null,e=!1){let r=M(n,"x","max"),o=(l,p)=>{let f=Vt(t,r.shape),m=f,y=ar(m,r.rank),b=r;y!=null&&(b=Kt(r,y),m=xr(m.length,b.rank));let v=l.max(b,m);y!=null&&b.dispose();let T=v;if(e){let N=Pn(T.shape,Vt(t,r.shape));T=Q(T,N),v.dispose()}return p([r,T]),T},s={x:r},c={reductionIndices:t,keepDims:e};return X.runKernelFunc(o,s,null,Eu,c)}let ur=j({max_:yB});function bB(n,t){let e=M(n,"a","sub"),r=M(t,"b","sub");[e,r]=Je(e,r);let o=(c,l)=>{let p=c.subtract(e,r);return l([e,r]),p},s={a:e,b:r};return X.runKernelFunc(o,s,null,_c)}let Dt=j({sub_:bB});function xB(n,t=null,e=!1){let r=M(n,"x","sum");r.dtype==="bool"&&(r=$t(r,"int32"));let o=(l,p)=>{p([r]);let f=Vt(t,r.shape),m=ar(f,r.rank),y=f,b=r;m!=null&&(b=Kt(r,m),y=xr(y.length,r.rank));let v=l.sum(b,y);if(e){let T=Pn(v.shape,f);v=Q(v,T)}return v},s={x:r},c={axis:t,keepDims:e};return X.runKernelFunc(o,s,null,Ox,c)}let zt=j({sum_:xB});function wB(n,t=-1){let e=M(n,"logits","logSoftmax");if(t===-1&&(t=e.rank-1),t!==e.rank-1)throw Error(`Log Softmax along a non-last dimension is not yet supported. Logits was rank ${e.rank} and axis was ${t}`);let r=(c,l)=>{let p=!0,f=ur(n,t,!0),m=Dt(n,f),y=Dt($t(m,"float32"),wr(zt(Fr(m),t,p)));return l([y]),y},o={logits:e},s={axis:t};return X.runKernelFunc(r,o,null,xx,s)}let Rd=j({logSoftmax_:wB});function vB(n,t=null,e=!1){let r=M(n,"x","logSumExp"),o=Vt(t,r.shape),s=ur(r,o,!0),c=Dt(r,s),l=Fr(c),p=zt(l,o),f=wr(p),m=Tt(Q(s,f.shape),f);if(e){let y=Pn(m.shape,o);return Q(m,y)}return m}let Vw=j({logSumExp_:vB});function TB(n,t){let e=M(n,"a","logicalAnd","bool"),r=M(t,"b","logicalAnd","bool");le(e.shape,r.shape);let o={a:e,b:r};return X.runKernelFunc(s=>s.logicalAnd(e,r),o,null,kN)}let Zr=j({logicalAnd_:TB});function kB(n){let t=M(n,"x","logicalNot","bool"),e={x:t};return X.runKernelFunc(r=>r.logicalNot(t),e,null,Bf)}let dp=j({logicalNot_:kB});function NB(n,t){let e=M(n,"a","logicalOr","bool"),r=M(t,"b","logicalOr","bool");le(e.shape,r.shape);let o={a:e,b:r};return X.runKernelFunc(s=>s.logicalOr(e,r),o,null,NN)}let Pd=j({logicalOr_:NB});function _B(n,t){let e=M(n,"a","logicalXor","bool"),r=M(t,"b","logicalXor","bool");return le(e.shape,r.shape),Zr(Pd(n,t),dp(Zr(n,t)))}let G_=j({logicalXor_:_B});function CB(n,t,e,r,o){let s=M(n,"x","maxPool"),c=1,l=s,p=!1;s.rank===3&&(p=!0,l=Q(s,[1,s.shape[0],s.shape[1],s.shape[2]])),_(l.rank===4,()=>`Error in maxPool: input must be rank 4 but got rank ${l.rank}.`),_(fn(e,c),()=>`Error in maxPool: Either strides or dilations must be 1. Got strides ${e} and dilations '${c}'`),o!=null&&_(gt(r),()=>`Error in maxPool: pad must be an integer when using, dimRoundingMode ${o} but got pad ${r}.`);let f=(v,T)=>{let N=Xn(l.shape,t,e,1,r,o),S;return N.filterWidth===1&&N.filterHeight===1&&lt(N.inShape,N.outShape)?S=l.clone():S=v.maxPool(l,N),T([l,S]),S},m={x:l},y={filterSize:t,strides:e,pad:r,dimRoundingMode:o},b=X.runKernelFunc(f,m,null,Du,y);return p?Q(b,[b.shape[1],b.shape[2],b.shape[3]]):b}let mp=j({maxPool_:CB});function SB(n,t=[1,1,1],e,r,o,s="NDHWC",c){c==null?c=[1,1,1]:yn("dilations is deprecated, this field will be gone in v3.0.0.");let l=M(n,"x","maxPool3d"),p=l,f=!1;l.rank===4&&(f=!0,p=Q(l,[1,l.shape[0],l.shape[1],l.shape[2],l.shape[3]])),_(p.rank===5,()=>`Error in maxPool3d: x must be rank 5 but got rank ${p.rank}.`),_(s==="NDHWC",()=>`Error in maxPool3d: Only NDHWC is currently supported, but got dataFormat of ${s}`),_(fn(e,c),()=>`Error in maxPool3d: Either strides or dilations must be 1. Got strides ${e} and dilations '${c}'`),o!=null&&_(gt(r),()=>`Error in maxPool3d: pad must be an integer when using,
1. The ${r} is defined in Python, in which case it needs to be ported to TensorFlow.js or your JavaScript code.
2. The custom ${r} is defined in JavaScript, but is not registered properly with tf.serialization.registerClass().`);return c}else{let s=n;if(s.className==null||s.config==null)throw new Y(`${r}: Improper config format: ${JSON.stringify(s)}.
'className' and 'config' must set.`);let c=s.className,l,p;if(c in e?[l,p]=e[c]:c in to?[l,p]=to.className:c in t&&([l,p]=t[c]),l==null)throw new Y(`Unknown ${r}: ${c}. This may be due to one of the following reasons:
1. The ${r} is defined in Python, in which case it needs to be ported to TensorFlow.js or your JavaScript code.
2. The custom ${r} is defined in JavaScript, but is not registered properly with tf.serialization.registerClass().`);if(p!=null){let f={};for(let v of Object.keys(to))f[v]=to[v];for(let v of Object.keys(e))f[v]=e[v];let m=s.config;m.customObjects=f;let y=Object.assign({},to);for(let v of Object.keys(e))to[v]=e[v];Sv(s.config);let b=p(l,s.config,e,o);return to=Object.assign({},y),b}else{let f=Object.assign({},to);for(let y of Object.keys(e))to[y]=e[y];let m=new l(s.config);return to=Object.assign({},f),m}}}function rG(n,t){return n<t?-1:n>t?1:0}function am(n,t){return-1*rG(n,t)}function Not(n){switch(n){case"float32":return"float32";default:throw new Y(`Invalid dtype: ${n}`)}}function _ot(n,t){if(n==null||t==null)return n===t;if(n.length!==t.length)return!1;for(let e=0;e<n.length;++e)if(n[e]!==t[e])return!1;return!0}function gi(n){if(n==null)return n;let t=[];for(let e of n)t.indexOf(e)===-1&&t.push(e);return t}function oG(n){if(n==null)throw new Y(`Invalid value in obj: ${JSON.stringify(n)}`);for(let t in n)if(n.hasOwnProperty(t))return!1;return!0}function Jc(n,t,e){if(e==null)return;if(n.indexOf(e)<0)throw new Y(`${e} is not a valid ${t}. Valid values are ${n} or null/undefined.`)}function $v(n,t,e=0,r=Infinity){return Or(e>=0),Or(r>=e),Array.isArray(n)&&n.length>=e&&n.length<=r&&n.every(o=>typeof o===t)}function $n(n,t){Array.isArray(n)?(_(n.length>0,()=>`${t} is unexpectedly an empty array.`),n.forEach((e,r)=>$n(e,`element ${r+1} of ${t}`))):_(Number.isInteger(n)&&n>0,()=>`Expected ${t} to be a positive integer, but got ${VC(n)}.`)}function VC(n){return n===null?"null":Array.isArray(n)?"["+n.map(t=>VC(t)).join(",")+"]":typeof n=="string"?`"${n}"`:`${n}`}function sG(n,t){let e=sr(),r,o=(...s)=>{let c=sr();return c-e<t||(e=c,r=n(...s)),r};return o}function GC(n){return n==="relu"?"relu":n==="linear"?"linear":n==="elu"?"elu":null}function Cot(...n){Or(n.length>0,"arrayOfValues is empty");for(let t of n)Or(Array.isArray(t),"one of the values is not an array"),Or(t.length>0,"one of the values is empty");return n.reduce((t,e)=>t.length===0?e.map(r=>[r]):e.map(r=>t.map(o=>[...o,r])).reduce((r,o)=>r.concat(o),[]),[])}function Iv(n,t){return rt(()=>On(zt(nt(n,n),t,!0)))}class Rp extends sa{getConfig(){return{}}}class Ev extends Rp{constructor(t){super();this.defaultMaxValue=2,this.defaultAxis=0,this.maxValue=t.maxValue!=null?t.maxValue:this.defaultMaxValue,this.axis=t.axis!=null?t.axis:this.defaultAxis}apply(t){return rt(()=>{let e=Iv(t,this.axis),r=cr(e,0,this.maxValue);return nt(t,Bt(r,Tt(wn(),e)))})}getConfig(){return{maxValue:this.maxValue,axis:this.axis}}}Ev.className="MaxNorm",vt(Ev);class Dv extends Rp{constructor(t){super();this.defaultAxis=0,this.axis=t.axis!=null?t.axis:this.defaultAxis}apply(t){return rt(()=>Bt(t,Tt(wn(),Iv(t,this.axis))))}getConfig(){return{axis:this.axis}}}Dv.className="UnitNorm",vt(Dv);class Av extends Rp{apply(t){return Uo(t)}}Av.className="NonNeg",vt(Av);class Fv extends Rp{constructor(t){super();this.defaultMinValue=0,this.defaultMaxValue=1,this.defaultRate=1,this.defaultAxis=0,this.minValue=t.minValue!=null?t.minValue:this.defaultMinValue,this.maxValue=t.maxValue!=null?t.maxValue:this.defaultMaxValue,this.rate=t.rate!=null?t.rate:this.defaultRate,this.axis=t.axis!=null?t.axis:this.defaultAxis}apply(t){return rt(()=>{let e=Iv(t,this.axis),r=Tt(nt(this.rate,cr(e,this.minValue,this.maxValue)),nt(1-this.rate,e));return nt(t,Bt(r,Tt(wn(),e)))})}getConfig(){return{minValue:this.minValue,maxValue:this.maxValue,rate:this.rate,axis:this.axis}}}Fv.className="MinMaxNorm",vt(Fv);let UC={maxNorm:"MaxNorm",minMaxNorm:"MinMaxNorm",nonNeg:"NonNeg",unitNorm:"UnitNorm"};function vn(n){return Cv(n)}function qC(n,t={}){return Fp(n,Ar.getMap().classNameMap,t,"constraint")}function Tn(n){if(n==null)return null;if(typeof n=="string"){let t=n in UC?UC[n]:n,e={className:t,config:{}};return qC(e)}else return n instanceof Rp?n:qC(n)}function iG(n){return new Ev(n)}function aG(n){return new Dv(n)}function cG(){return new Av}function lG(n){return new Fv(n)}var uG=Object.freeze({__proto__:null,maxNorm:iG,unitNorm:aG,non
because the value dtype is ${e.dtype}, but TensorArray dtype is ${this.dtype}.`);if(this.size()===0&&(this.elementShape==null||this.elementShape.length===0)&&(this.elementShape=e.shape),no(this.elementShape,e.shape,`TensorArray ${this.name}: Could not write to TensorArray index ${t}.`),r.read)throw new Error(`TensorArray ${this.name}: Could not write to TensorArray index ${t}, because it has already been read.`);if(r.written)throw new Error(`TensorArray ${this.name}: Could not write to TensorArray index ${t}, because it has already been written.`);r.tensor=e,Sn(e),r.written=!0,this.tensors[t]=r}writeMany(t,e){if(t.length!==e.length)throw new Error(`TensorArray ${this.name}: could not write multiple tensors,because the index size: ${t.length} is not the same as tensors size: ${e.length}.`);t.forEach((r,o)=>this.write(r,e[o]))}gather(t,e){if(!!e&&e!==this.dtype)throw new Error(`TensorArray dtype is ${this.dtype} but gather requested dtype ${e}`);if(t)t=t.slice(0,this.size());else{t=[];for(let o=0;o<this.size();o++)t.push(o)}if(t.length===0)return un([],[0].concat(this.elementShape));let r=this.readMany(t);return no(this.elementShape,r[0].shape,"TensorArray shape mismatch: "),pr(r,0)}concat(t){if(!!t&&t!==this.dtype)throw new Error(`TensorArray dtype is ${this.dtype} but concat requested dtype ${t}`);if(this.size()===0)return un([],[0].concat(this.elementShape));let e=[];for(let o=0;o<this.size();o++)e.push(o);let r=this.readMany(e);return no(this.elementShape,r[0].shape,`TensorArray shape mismatch: tensor array shape (${this.elementShape}) vs first tensor shape (${r[0].shape})`),Qe(r,0)}scatter(t,e){if(e.dtype!==this.dtype)throw new Error(`TensorArray dtype is ${this.dtype} but tensor has dtype ${e.dtype}`);if(t.length!==e.shape[0])throw new Error(`Expected len(indices) == tensor.shape[0], but saw: ${t.length} vs. ${e.shape[0]}`);let r=Math.max(...t);if(!this.dynamicSize&&r>=this.maxSize)throw new Error(`Max index must be < array size (${r} vs. ${this.maxSize})`);this.writeMany(t,go(e,0))}split(t,e){if(e.dtype!==this.dtype)throw new Error(`TensorArray dtype is ${this.dtype} but tensor has dtype ${e.dtype}`);let r=0,o=t.map(p=>(r+=p,r));if(r!==e.shape[0])throw new Error(`Expected sum of lengths to be equal to
2020-10-11 18:41:17 +02:00
tensor.shape[0], but sum of lengths is
2020-11-25 14:30:53 +01:00
${r}, and tensor's shape is: ${e.shape}`);if(!this.dynamicSize&&t.length!==this.maxSize)throw new Error(`TensorArray's size is not equal to the size of lengths (${this.maxSize} vs. ${t.length}), and the TensorArray is not marked as dynamically resizeable`);let s=r===0?0:e.size/r,c=[];rt(()=>{e=Q(e,[1,r,s]);for(let p=0;p<t.length;++p){let f=p===0?0:o[p-1],m=[0,f,0],y=[1,t[p],s];c[p]=Q(ce(e,m,y),this.elementShape)}return c});let l=[];for(let p=0;p<t.length;p++)l[p]=p;this.writeMany(l,c)}}class al{constructor(t,e,r,o=-1){this.tensors=t,this.elementShape=e,this.elementDtype=r,t!=null&&t.forEach(s=>{if(r!==s.dtype)throw new Error(`Invalid data types; op elements ${r}, but list elements ${s.dtype}`);no(e,s.shape,"TensorList shape mismatch: "),Sn(s)}),this.idTensor=Et(0),this.maxNumElements=o,Sn(this.idTensor)}get id(){return this.idTensor.id}copy(){return new al([...this.tensors],this.elementShape,this.elementDtype)}clearAndClose(t){this.tensors.forEach(e=>{(t==null||!t.has(e.id))&&e.dispose()}),this.tensors.length=0,this.idTensor.dispose()}size(){return this.tensors.length}stack(t,e,r=-1){if(e!==this.elementDtype)throw new Error(`Invalid data types; op elements ${e}, but list elements ${this.elementDtype}`);if(r!==-1&&this.tensors.length!==r)throw new Error(`Operation expected a list with ${r} elements but got a list with ${this.tensors.length} elements.`);return no(t,this.elementShape,"TensorList shape mismatch: "),rt(()=>{let o=this.tensors.map(s=>Q(s,t));return pr(o,0)})}popBack(t,e){if(e!==this.elementDtype)throw new Error(`Invalid data types; op elements ${e}, but list elements ${this.elementDtype}`);if(this.size()===0)throw new Error("Trying to pop from an empty list.");let r=this.tensors.pop();return no(r.shape,t,"TensorList shape mismatch: "),Q(r,t)}pushBack(t){if(t.dtype!==this.elementDtype)throw new Error(`Invalid data types; op elements ${t.dtype}, but list elements ${this.elementDtype}`);if(no(t.shape,this.elementShape,"TensorList shape mismatch: "),this.maxNumElements===this.size())throw new Error("Trying to push element into a full list.");Sn(t),this.tensors.push(t)}resize(t){if(t<0)throw new Error(`TensorListResize expects size to be non-negative. Got: ${t}`);if(this.maxNumElements!==-1&&t>this.maxNumElements)throw new Error(`TensorListResize input size ${t} is greater maxNumElement ${this.maxNumElements}.`);this.tensors.length=t}getItem(t,e,r){if(r!==this.elementDtype)throw new Error(`Invalid data types; op elements ${r}, but list elements ${this.elementDtype}`);if(t<0||t>this.tensors.length)throw new Error(`Trying to access element ${t} in a list with ${this.tensors.length} elements.`);if(this.tensors[t]==null)throw new Error(`element at index ${t} is null.`);return no(this.tensors[t].shape,e,"TensorList shape mismatch: "),this.tensors[t]}setItem(t,e){if(e.dtype!==this.elementDtype)throw new Error(`Invalid data types; op elements ${e.dtype}, but list elements ${this.elementDtype}`);if(t<0||this.maxNumElements!==-1&&t>=this.maxNumElements)throw new Error(`Trying to set element ${t} in a list with max ${this.maxNumElements} elements.`);no(this.elementShape,e.shape,"TensorList shape mismatch: "),Sn(e),this.tensors[t]=e}gather(t,e,r){if(e!==this.elementDtype)throw new Error(`Invalid data types; op elements ${e}, but list elements ${this.elementDtype}`);return no(this.elementShape,r,"TensorList shape mismatch: "),t=t.slice(0,this.size()),t.length===0?un([],[0].concat(this.elementShape)):rt(()=>{let o=t.map(s=>Q(this.tensors[s],r));return pr(o,0)})}concat(t,e){if(!!t&&t!==this.elementDtype)throw new Error(`TensorList dtype is ${this.elementDtype} but concat requested dtype ${t}`);return no(this.elementShape,e,"TensorList shape mismatch: "),this.size()===0?un([],[0].concat(this.elementShape)):rt(()=>{let r=this.tensors.map(o=>Q(o,e));return Qe(r,0)})}}function Ij(n,t,e){let r=n.dtype;if(n.shape.length<1)throw new Error(`Tensor must be at least a vector, but saw shape: ${n.shape}`);if(n.dtype!==e)throw new Error(`Invalid data types; op elements ${n.dtype}, but list elements ${e}`);let o=n.shape.slice(1);no(o
2020-10-11 18:41:17 +02:00
tensor.shape[0], but sum of lengths is
2020-11-25 14:30:53 +01:00
${r}, and tensor's shape is: ${n.shape}`);let s=r===0?0:n.size/r,c=rt(()=>{let p=[];n=Q(n,[1,r,s]);for(let f=0;f<t.length;++f){let m=f===0?0:o[f-1],y=[0,m,0],b=[1,t[f],s];p[f]=Q(ce(n,y,b),e)}return n.dispose(),p}),l=new al([],e,n.dtype,t.length);for(let p=0;p<c.length;p++)l.setItem(p,c[p]);return l}let Fj=async(n,t,e)=>{switch(n.op){case"If":case"StatelessIf":{let r=A("thenBranch",n,t,e),o=A("elseBranch",n,t,e),s=A("cond",n,t,e),c=A("args",n,t,e),l=await s.data();return l[0]?e.functionMap[r].executeFunctionAsync(c,e.tensorArrayMap,e.tensorListMap):e.functionMap[o].executeFunctionAsync(c,e.tensorArrayMap,e.tensorListMap)}case"While":case"StatelessWhile":{let r=A("body",n,t,e),o=A("cond",n,t,e),s=A("args",n,t,e),c=await e.functionMap[o].executeFunctionAsync(s,e.tensorArrayMap,e.tensorListMap),l=s.map(m=>m.id),p=await c[0].data();c.forEach(m=>{!m.kept&&l.indexOf(m.id)===-1&&m.dispose()});let f=s;for(;p[0];){let m=f;f=await e.functionMap[r].executeFunctionAsync(f,e.tensorArrayMap,e.tensorListMap);let y=f.map(v=>v.id);m.forEach(v=>{!v.kept&&l.indexOf(v.id)===-1&&y.indexOf(v.id)===-1&&v.dispose()});let b=await e.functionMap[o].executeFunctionAsync(f,e.tensorArrayMap,e.tensorListMap);p=await b[0].data(),b.forEach(v=>{!v.kept&&l.indexOf(v.id)===-1&&y.indexOf(v.id)===-1&&v.dispose()})}return f}case"LoopCond":{let r=A("pred",n,t,e);return[_s(r)]}case"Switch":{let r=A("pred",n,t,e),o=A("data",n,t,e);return o.kept||(o=_s(o)),(await r.data())[0]?[void 0,o]:[o,void 0]}case"Merge":{let r=n.inputNames.find(o=>dr(o,t,e)!==void 0);if(r){let o=dr(r,t,e);return[_s(o)]}return}case"Enter":{let r=A("frameName",n,t,e),o=A("tensor",n,t,e);return e.enterFrame(r),[_s(o)]}case"Exit":{let r=A("tensor",n,t,e);return e.exitFrame(),[_s(r)]}case"NextIteration":{let r=A("tensor",n,t,e);return e.nextIteration(),[_s(r)]}case"TensorArrayV3":{let r=A("size",n,t,e),o=A("dtype",n,t,e),s=A("elementShape",n,t,e),c=A("dynamicSize",n,t,e),l=A("clearAfterRead",n,t,e),p=A("identicalElementShapes",n,t,e),f=A("name",n,t,e),m=new $j(f,o,r,s,p,c,l);return e.addTensorArray(m),[m.idTensor,Et(1)]}case"TensorArrayWriteV3":{let r=A("tensorArrayId",n,t,e),o=A("index",n,t,e),s=A("tensor",n,t,e),c=e.getTensorArray(r.id);return c.write(o,s),[c.idTensor]}case"TensorArrayReadV3":{let r=A("tensorArrayId",n,t,e),o=A("index",n,t,e),s=e.getTensorArray(r.id);return[s.read(o)]}case"TensorArrayGatherV3":{let r=A("tensorArrayId",n,t,e),o=A("indices",n,t,e),s=A("dtype",n,t,e),c=e.getTensorArray(r.id);return[c.gather(o,s)]}case"TensorArrayScatterV3":{let r=A("tensorArrayId",n,t,e),o=A("indices",n,t,e),s=A("tensor",n,t,e),c=e.getTensorArray(r.id);return c.scatter(o,s),[c.idTensor]}case"TensorArrayConcatV3":{let r=A("tensorArrayId",n,t,e),o=e.getTensorArray(r.id),s=A("dtype",n,t,e);return[o.concat(s)]}case"TensorArraySplitV3":{let r=A("tensorArrayId",n,t,e),o=A("tensor",n,t,e),s=A("lengths",n,t,e),c=e.getTensorArray(r.id);return c.split(s,o),[c.idTensor]}case"TensorArraySizeV3":{let r=A("tensorArrayId",n,t,e),o=e.getTensorArray(r.id);return[Et(o.size(),"int32")]}case"TensorArrayCloseV3":{let r=A("tensorArrayId",n,t,e),o=e.getTensorArray(r.id);return o.clearAndClose(),[o.idTensor]}case"TensorListSetItem":{let r=A("tensorListId",n,t,e),o=A("index",n,t,e),s=A("tensor",n,t,e),c=e.getTensorList(r.id);return c.setItem(o,s),[c.idTensor]}case"TensorListGetItem":{let r=A("tensorListId",n,t,e),o=A("index",n,t,e),s=A("elementShape",n,t,e),c=A("elementDType",n,t,e),l=e.getTensorList(r.id);return[l.getItem(o,s,c)]}case"TensorListScatterV2":case"TensorListScatter":{let r=A("indices",n,t,e),o=A("tensor",n,t,e),s=A("elementShape",n,t,e),c=A("numElements",n,t,e),l=Dj(o,r,s,c);return e.addTensorList(l),[l.idTensor]}case"TensorListReserve":{let r=A("elementShape",n,t,e),o=A("elementDType",n,t,e),s=A("numElements",n,t,e),c=Ej(r,o,s);return e.addTensorList(c),[c.idTensor]}case"TensorListGather":{let r=A("tensorListId",n,t,e),o=A("indices",n,t,e),s=A("elementShape",n,t,e),c=A("elementDType",n,t,e),l=e.getTensorList(r.id);return[l.gather(o,c,s)]}case"TensorListStack":{let r=A("tensorListId",n,t,e),o=A("ele
${t}`);let o;return this.size===Infinity||this.size==null?o=this.size:e?o=Math.ceil(this.size/t):o=Math.floor(this.size/t),_r(async()=>(await r.iterator()).columnMajorBatch(t,e,C6),o)}concatenate(t){let e=this,r;return this.size===Infinity||t.size===Infinity?r=Infinity:this.size!=null&&t.size!=null?r=this.size+t.size:r=null,_r(async()=>(await e.iterator()).concatenate(await t.iterator()),r)}filter(t){let e=this,r;return this.size===Infinity?r=Infinity:r=null,_r(async()=>(await e.iterator()).filter(o=>rt(()=>t(o))),r)}async forEachAsync(t){return(await this.iterator()).forEachAsync(t)}map(t){let e=this;return _r(async()=>(await e.iterator()).map(r=>rt(()=>t(r))),this.size)}mapAsync(t){let e=this;return _r(async()=>(await e.iterator()).mapAsync(t),this.size)}prefetch(t){if(t==null)throw new RangeError("`Dataset.prefetch()` requires bufferSize to be specified.");let e=this;return _r(async()=>(await e.iterator()).prefetch(t),this.size)}repeat(t){let e=this,r;return this.size!=null&&t>0?r=this.size*t:t===0?r=0:this.size!=null&&(t===void 0||t<0)?r=Infinity:r=null,_r(async()=>{let o=nh(async()=>({value:await e.iterator(),done:!1}));return O$(o.take(t))},r)}skip(t){let e=this,r;return this.size!=null&&t>=0&&this.size>=t?r=this.size-t:this.size!=null&&(this.size<t||t===void 0||t<0)?r=0:r=null,_r(async()=>(await e.iterator()).skip(t),r)}shuffle(t,e,r=!0){if(t==null||t<0)throw this.size==null?new RangeError("`Dataset.shuffle()` requires bufferSize to be specified."):new RangeError(`\`Dataset.shuffle()\` requires bufferSize to be specified. If your data fits in main memory (for regular JS objects), and/or GPU memory (for \`tf.Tensor\`s), consider setting bufferSize to the dataset size (${this.size} elements)`);let o=this,s=Uc(e||sr().toString());return _r(async()=>{let c=s.int32();return r&&(c+=s.int32()),(await o.iterator()).shuffle(t,c.toString())},this.size)}take(t){let e=this,r;return this.size!=null&&this.size>t?r=t:this.size!=null&&this.size<=t?r=this.size:r=null,_r(async()=>(await e.iterator()).take(t),r)}async toArray(){if(this.size===Infinity)throw new Error("Can not convert infinite data stream to array.");return(await this.iterator()).toArray()}async toArrayForTest(){if(this.size===Infinity)throw new Error("Can not convert infinite data stream to array.");return(await this.iterator()).toArrayForTest()}}ll.MAX_BUFFER_SIZE=1e4;function _r(n,t=null){return new class extends ll{constructor(){super(...arguments);this.size=t}async iterator(){return n()}}}function N6(n){return _r(async()=>P$(n),n.length)}function _6(n){if(!cl(n))throw new Error("The argument to zip() must be an object or array.");let t;if(Array.isArray(n))for(let e=0;e<n.length;e++)t=t==null?n[e].size:Math.min(t,n[e].size);else if(n instanceof Object)for(let e in n)t=t==null?n[e].size:Math.min(t,n[e].size);return _r(async()=>{let e=await F$(n,r=>{if(r instanceof ll)return{value:r.iterator(),recurse:!1};if(cl(r))return{value:null,recurse:!0};throw new Error("Leaves of the structure passed to zip() must be Datasets, not primitives.")});return p6(e,_i.SHORTEST)},t)}function C6(n){if(n===null)return null;let t=n[0];if(a6(t)){let e=S6(n);return{value:e,recurse:!1}}return{value:null,recurse:!0}}function S6(n){if(n.length===0)throw new Error("Can't make a batch of zero elements.");return n[0]instanceof ot?pr(n):un(n)}class z$ extends ll{constructor(t){super();this.input=t}async iterator(){let t=await this.input.iterator(),e=t.decodeUTF8(),r=e.split(`
`).map(o=>(o.endsWith("\r")&&(o=o.slice(0,-1)),o));return r}}let Hm='"',rh=Symbol("out"),W$=Symbol("field"),jm=Symbol("quote"),b1=Symbol("quoteafterquote"),V$=Symbol("quoteinquote");class G$ extends ll{constructor(t,e){super();this.input=t,this.hasHeader=!0,this.fullColumnNames=null,this.columnNamesValidated=!1,this.columnConfigs=null,this.configuredColumnsOnly=!1,this.delimiter=",",this.delimWhitespace=!1,this.base=new z$(t),e||(e={}),this.hasHeader=!(e.hasHeader===!1),this.fullColumnNames=e.columnNames,this.columnConfigs=e.columnConfigs,this.configuredColumnsOnly=e.configuredColumnsOnly,e.delimWhitespace?(_(e.delimiter==null,()=>"Delimiter should not be provided when delimWhitespace is true."),this.delimWhitespace=!0,this.delimiter=" "):this.delimiter=e.delimiter?e.delimiter:","}async columnNames(){return this.columnNamesValidated||await this.setColumnNames(),this.configuredColumnsOnly?Object.keys(this.columnConfigs):this.fullColumnNames}async setColumnNames(){let t=await this.maybeReadHeaderLine();if(!this.fullColumnNames&&!t)throw new Error("Column names must be provided if there is no header line.");this.fullColumnNames&&t&&_(t.length===this.fullColumnNames.length,()=>"The length of provided columnNames ("+this.fullColumnNames.length.toString()+") does not match the length of the header line read from file ("+t.length.toString()+")."),this.fullColumnNames||(this.fullColumnNames=t);let e=this.fullColumnNames.reduce((o,s)=>(o[s]=o[s]+1||1,o),{}),r=Object.keys(e).filter(o=>e[o]>1);if(_(r.length===0,()=>"Duplicate column names found: "+r.toString()),this.columnConfigs)for(let o of Object.keys(this.columnConfigs)){let s=this.fullColumnNames.indexOf(o);if(s===-1)throw new Error('The key "'+o+'" provided in columnConfigs does not match any of the column names ('+this.fullColumnNames.toString()+").")}this.columnNamesValidated=!0}async maybeReadHeaderLine(){if(this.hasHeader){let t=await this.base.iterator(),e=await t.next();if(e.done)throw new Error("No data was found for CSV parsing.");let r=e.value,o=this.parseRow(r,!1);return o}else return null}async iterator(){this.columnNamesValidated||await this.setColumnNames();let t=await this.base.iterator();return this.hasHeader&&(t=t.skip(1)),t.map(e=>this.makeDataElement(e))}makeDataElement(t){let e=this.parseRow(t),r={},o={};for(let s=0;s<this.fullColumnNames.length;s++){let c=this.fullColumnNames[s],l=this.columnConfigs?this.columnConfigs[c]:null;if(this.configuredColumnsOnly&&!l)continue;{let p=e[s],f=null;if(p==="")if(l&&l.default!==void 0)f=l.default;else{if(l&&(l.required||l.isLabel))throw new Error(`Required column ${c} is empty in this line: ${t}`);f=void 0}else{let m=Number(p);if(isNaN(m))l&&l.dtype==="bool"?f=this.getBoolean(p):f=p;else if(!l||!l.dtype)f=m;else switch(l.dtype){case"float32":f=m;break;case"int32":f=Math.floor(m);break;case"bool":f=this.getBoolean(p);break;default:f=m}}l&&l.isLabel?o[c]=f:r[c]=f}}return Object.keys(o).length===0?r:{xs:r,ys:o}}getBoolean(t){return t==="1"||t.toLowerCase()==="true"?1:0}parseRow(t,e=!0){let r=[],o=0,s=t.length,c=rh;for(let l=0;l<s;l++)switch(c){case rh:switch(t.charAt(l)){case Hm:o=l+1,c=jm;break;case this.delimiter:if(o=l+1,this.delimiter===" "&&this.delimWhitespace)break;r.push(""),c=rh;break;default:c=W$,o=l;break}break;case W$:switch(t.charAt(l)){case this.delimiter:r.push(t.substring(o,l)),c=rh,o=l+1;break;default:}break;case jm:switch(t.charAt(l)){case Hm:c=b1;break;default:}break;case b1:switch(t.charAt(l)){case this.delimiter:r.push(t.substring(o,l-1)),c=rh,o=l+1;break;case Hm:c=jm;break;default:c=V$;break}break;case V$:switch(t.charAt(l)){case Hm:c=jm;break;default:}break;default:}if(c===b1?r.push(t.substring(o,s-1)):r.push(t.substring(o)),e&&r.length!==this.fullColumnNames.length)throw new Error(`Invalid row in csv file. Should have ${this.fullColumnNames.length} elements in a row, but got ${r}`);return r}}class x1 extends En{constructor(t){super();this.microphoneConfig=t,this.isClosed=!1,this.fftSize=t.fftSize||1024;let e=Math.log2(this.fftSize);if(this.fftSize<0||e<4||e>14||!Number.isInteger(e))throw new Error(
2020-10-11 18:41:17 +02:00
============================
2020-11-25 14:30:53 +01:00
Hi there \u{1F44B}. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================`));let o={};return this.data.set(o,{values:t,dtype:r,refCount:1}),o}makeTensorInfo(t,e,r){let o;if(e==="string"&&r!=null&&r.length>0&&us(r[0])){let s=r.map(c=>od(c));o=this.write(s,t,e)}else o=this.write(r,t,e);return{dataId:o,shape:t,dtype:e}}incRef(t){let e=this.data.get(t);e.refCount++}decRef(t){if(this.data.has(t)){let e=this.data.get(t);e.refCount--}}move(t,e,r,o){this.data.set(t,{values:e,dtype:o,refCount:1})}numDataIds(){return this.data.numDataIds()}async read(t){return this.readSync(t)}readSync(t){let{dtype:e,complexTensorInfos:r}=this.data.get(t);if(e==="complex64"){let o=this.readSync(r.real.dataId),s=this.readSync(r.imag.dataId);return ws(o,s)}return this.data.get(t).values}bufferSync(t){let e=this.readSync(t.dataId),r=e;if(t.dtype==="string")try{r=e.map(o=>Yu(o))}catch(o){throw new Error("Failed to decode encoded string bytes into utf-8")}return Se(t.shape,t.dtype,r)}makeOutput(t,e,r){let o=this.write(t,e,r);return ds().makeTensorFromDataId(o,e,r,this)}disposeData(t){if(this.data.has(t)){let{complexTensorInfos:e}=this.data.get(t);e!=null&&(this.disposeData(e.real.dataId),this.disposeData(e.imag.dataId)),this.data.delete(t)}}disposeIntermediateTensorInfo(t){let e=t.dataId;if(this.data.has(e)){let r=this.data.get(e);r.refCount--,r.refCount<1&&this.disposeData(e)}}async time(t){let e=sr();t();let r=sr()-e;return{kernelMs:r}}memory(){return{unreliable:!0,reasons:["The reported memory is an upper bound. Due to automatic garbage collection, the true allocated memory may be less."]}}stridedSlice(t,e,r,o){Ct(t,"stridedSlice");let s=gd(e,r,o);if(s.some(p=>p===0))return un([],s);let c=Se(s,t.dtype),l=this.bufferSync(t);for(let p=0;p<c.size;p++){let f=c.indexToLoc(p),m=new Array(f.length);for(let y=0;y<m.length;y++)m[y]=f[y]*o[y]+e[y];c.set(l.get(...m),...f)}return c.toTensor()}diag(t){let e=this.readSync(t.dataId),r=Se([t.size,t.size],t.dtype),o=r.values;for(let s=0;s<e.length;s++)o[s*t.size+s]=e[s];return r.toTensor()}unstack(t,e){let r=t.shape[e],o=new Array(t.rank-1),s=0;for(let f=0;f<t.rank;f++)f!==e&&(o[s++]=t.shape[f]);let c=new Array(t.rank).fill(0),l=t.shape.slice();l[e]=1;let p=new Array(r);for(let f=0;f<p.length;f++)c[e]=f,p[f]=ce(t,c,l).reshape(o);return p}reverse(t,e){Ct(t,"reverse");let r=Se(t.shape,t.dtype),o=this.bufferSync(t);for(let s=0;s<r.size;s++){let c=r.indexToLoc(s),l=c.slice();e.forEach(p=>l[p]=t.shape[p]-1-l[p]),r.set(o.get(...l),...c)}return r.toTensor()}neg(t){return Ct(t,"neg"),nt(Et(-1),t)}addN(t){Ct(t,"addN");let e=t.map(s=>this.readSync(s.dataId)),r=Se(t[0].shape,t[0].dtype),o=r.values;for(let s=0;s<t.length;s++){let c=e[s];for(let l=0;l<o.length;l++)o[l]+=c[l]}return r.toTensor()}softmax(t,e){let r=Vt([e],t.shape),o=ur(t,r),s=Pn(o.shape,r),c=Dt(t,o.reshape(s)),l=Fr(c),p=this.sum(l,r).reshape(s);return Bt(l,p)}pow(t,e){return Ct([t,e],"pow"),this.broadcastedBinaryOp(t,e,t.dtype,(r,o)=>Math.pow(r,o))}floorDiv(t,e){Ct([t,e],"floorDiv");let r=(s,c)=>Math.floor(s/c),o="int32";return this.broadcastedBinaryOp(t,e,o,r)}sum(t,e){Ct(t,"sum"),ir("sum",e,t.rank);let[r,o]=Rn(t.shape,e),s=Kn(t.dtype,"int32"),c=xe(r,s),l=G(o),p=this.readSync(c.dataId),f=this.readSync(t.dataId);for(let m=0;m<p.length;++m){let y=m*l,b=0;for(let v=0;v<l;++v)b+=f[y+v];p[m]=b}return c}prod(t,e){Ct(t,"sum");let[r,o]=Rn(t.shape,e),s=Kn(t.dtype,"int32"),c=xe(r,s),l=G(o),p=this.readSync(c.dataId),f=this.readSync(t.dataId);for(let m=0;m<p.length;++m){let y=m*l,b=1;for(let v=0;v<l;++v)b*=f[y+v];p[m]=b}return c}unsortedSegmentSum(t,e,r){Ct(t,"unsortedSegmentSum");let o=[],s=t.rank-e.rank;for(let c=0;c<s;++c)e=e.expandDims(c+1);for(let c=0;c<r;++c){let l=Et(c,"int32"),p=ho(l,e).asType("float32"),f=p.mul(t).sum(0);o.push(f)}return pr(o)}argMin(t,e){Ct(t,"argMin");let r=[e];ir("argMin",r,t.rank);let[o,s]=Rn(t.shape,r),c=xe(o,"int32"),l=G(s),p=this.readSync(c.dataId),f=this.readSync(t.dataId);for(let m=0;m<p.length;++m){let y=m*l,b=f[y],v=0;for(let T=0;T<l;++T){let N=f[y+T];N<b&&(b=N,v=T)}p[m]=v}return c}argMax(t,e){Ct(t,"argMax");let r=[e];ir("argMax",r,t.rank);let[o,s]=Rn(t.shape,r),c=xe(o,"int32"),l=G
`),s=o.length.toString().length+2,c=o.map((y,b)=>fe((b+1).toString(),s)+y),l=0;for(let y=0;y<c.length;y++)l=Math.max(c[y].length,l);let p=c.slice(0,r-1),f=c.slice(r-1,r),m=c.slice(r);console.log(p.join(`
2020-10-11 18:41:17 +02:00
`)),console.log(t.split(`
2020-11-25 14:30:53 +01:00
`)[0]),console.log(`%c ${fe(f[0],l)}`,"border:1px solid red; background-color:#e3d2d2; color:#a61717"),console.log(m.join(`
`))}function dX(n){return Cs(n,()=>n.createProgram(),"Unable to create WebGLProgram.")}function mX(n,t){if(Rt(n,()=>n.linkProgram(t)),n.getProgramParameter(t,n.LINK_STATUS)===!1)throw console.log(n.getProgramInfoLog(t)),new Error("Failed to link vertex and fragment shaders.")}function E1(n,t){if(Rt(n,()=>n.validateProgram(t)),n.getProgramParameter(t,n.VALIDATE_STATUS)===!1)throw console.log(n.getProgramInfoLog(t)),new Error("Shader program validation failed.")}function gX(n,t){let e=Cs(n,()=>n.createBuffer(),"Unable to create WebGLBuffer");return Rt(n,()=>n.bindBuffer(n.ARRAY_BUFFER,e)),Rt(n,()=>n.bufferData(n.ARRAY_BUFFER,t,n.STATIC_DRAW)),e}function yX(n,t){let e=Cs(n,()=>n.createBuffer(),"Unable to create WebGLBuffer");return Rt(n,()=>n.bindBuffer(n.ELEMENT_ARRAY_BUFFER,e)),Rt(n,()=>n.bufferData(n.ELEMENT_ARRAY_BUFFER,t,n.STATIC_DRAW)),e}function Hst(){return ct().getNumber("WEBGL_VERSION")===2?1:4}function bX(n){return Cs(n,()=>n.createTexture(),"Unable to create WebGLTexture.")}function xX(n,t){let e=ct().getNumber("WEBGL_MAX_TEXTURE_SIZE");if(n<=0||t<=0){let r=`[${n}x${t}]`;throw new Error("Requested texture size "+r+" is invalid.")}if(n>e||t>e){let r=`[${n}x${t}]`,o=`[${e}x${e}]`;throw new Error("Requested texture size "+r+" greater than WebGL maximum on this browser / GPU "+o+".")}}function wX(n){return Cs(n,()=>n.createFramebuffer(),"Unable to create WebGLFramebuffer.")}function CI(n,t,e,r,o,s,c){let l=n.getAttribLocation(t,e);return l===-1?!1:(Rt(n,()=>n.bindBuffer(n.ARRAY_BUFFER,r)),Rt(n,()=>n.vertexAttribPointer(l,o,n.FLOAT,!1,s,c)),Rt(n,()=>n.enableVertexAttribArray(l)),!0)}function vX(n,t,e){$I(n,e),Rt(n,()=>n.activeTexture(n.TEXTURE0+e)),Rt(n,()=>n.bindTexture(n.TEXTURE_2D,t))}function jst(n,t){$I(n,t),Rt(n,()=>n.activeTexture(n.TEXTURE0+t)),Rt(n,()=>n.bindTexture(n.TEXTURE_2D,null))}function TX(n,t,e){return Cs(n,()=>n.getUniformLocation(t,e),'uniform "'+e+'" not present in program.')}function kX(n,t,e){return n.getUniformLocation(t,e)}function NX(n,t,e,r){Rt(n,()=>vX(n,t,r)),Rt(n,()=>n.uniform1i(e,r))}function Kst(n){Rt(n,()=>n.bindFramebuffer(n.FRAMEBUFFER,null)),Rt(n,()=>n.viewport(0,0,n.canvas.width,n.canvas.height)),Rt(n,()=>n.scissor(0,0,n.canvas.width,n.canvas.height))}function D1(n,t,e){Rt(n,()=>n.bindFramebuffer(n.FRAMEBUFFER,e)),Rt(n,()=>n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,t,0))}function SI(n,t){Rt(n,()=>n.bindFramebuffer(n.FRAMEBUFFER,t)),Rt(n,()=>n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,null,0))}function Ym(n){let t=n.checkFramebufferStatus(n.FRAMEBUFFER);if(t!==n.FRAMEBUFFER_COMPLETE)throw new Error("Error binding framebuffer: "+_X(n,t))}function _X(n,t){switch(t){case n.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_ATTACHMENT";case n.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";case n.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:return"FRAMEBUFFER_INCOMPLETE_DIMENSIONS";case n.FRAMEBUFFER_UNSUPPORTED:return"FRAMEBUFFER_UNSUPPORTED";default:return`unknown error ${t}`}}function Cs(n,t,e){let r=Rt(n,()=>t());if(r==null)throw new Error(e);return r}function $I(n,t){let e=n.MAX_COMBINED_TEXTURE_IMAGE_UNITS-1,r=t+n.TEXTURE0;if(r<n.TEXTURE0||r>e){let o=`[gl.TEXTURE0, gl.TEXTURE${e}]`;throw new Error(`textureUnit must be in ${o}.`)}}function dl(n,t=2){return G(n.slice(0,n.length-t))}function ml(n){if(n.length===0)throw Error("Cannot get rows and columns of an empty shape array.");return[n.length>1?n[n.length-2]:1,n[n.length-1]]}function A1(n){let t=[1,1,1],e=n.length===0||n.length===1&&n[0]===1;return e||(t=[dl(n),...ml(n)]),t}function CX(n,t=!1){let e=ct().getNumber("WEBGL_MAX_TEXTURE_SIZE");if(t&&(e=e*2,n=n.map((o,s)=>s>=n.length-2?k(n[s]):n[s]),n.length===1&&(n=[2,n[0]])),n.length!==2){let o=ln(n);n=o.newShape}let r=G(n);if(n.length<=1&&r<=e)return[1,r];if(n.length===2&&n[0]<=e&&n[1]<=e)return n;if(n.length===3&&n[0]*n[1]<=e&&n[2]<=e)return[n[0]*n[1],n[2]];if(n.length===3&&n[0]<=e&&n[1]*n[2]<=e)return[n[0],n[1]*n[2]];if(n.length===4&&n[0]*n[1]*n[2]<=e&&n[3]<=e)return[n[0]*n[1]*n[2]
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${r.join(`
2020-10-11 18:41:17 +02:00
`)}
2020-11-25 14:30:53 +01:00
float result = ${o};
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class KX{constructor(t,e){this.outputShape=[],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t,this.variableNames=e.map((s,c)=>`T${c}`);let r=[];this.variableNames.forEach(s=>{r.push(`vec4 v${s} = get${s}AtOutCoords();`)});let o=this.variableNames.map(s=>`v${s}`).join(" + ");this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${r.join(`
2020-10-11 18:41:17 +02:00
`)}
2020-11-25 14:30:53 +01:00
vec4 result = ${o};
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class XX{constructor(t,e,r){this.variableNames=["A"];let{windowSize:o,batchSize:s,outSize:c}=t;r||this.variableNames.push("bestIndicesA"),this.outputShape=[s,c];let l=e==="max"?">":"<",p=r?"inOffset + i;":"round(getBestIndicesA(batch, inOffset + i));";this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec2 coords = getOutputCoords();
int batch = coords[0];
int outIdx = coords[1];
2020-11-25 14:30:53 +01:00
int inOffset = outIdx * ${o};
2020-10-11 18:41:17 +02:00
int bestIndex = inOffset;
float bestValue = getA(batch, bestIndex);
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${o}; i++) {
int inIdx = ${p};
2020-10-11 18:41:17 +02:00
float candidate = getA(batch, inIdx);
2020-11-25 14:30:53 +01:00
if (candidate ${l} bestValue) {
2020-10-11 18:41:17 +02:00
bestValue = candidate;
bestIndex = inIdx;
}
}
setOutput(float(bestIndex));
}
2020-11-25 14:30:53 +01:00
`}}function EI(n,t){return["x","y","z","w","u","v"].slice(0,t).map(e=>`${n}.${e}`)}function Jn(n,t){return t===1?[n]:EI(n,t)}function YX(n,t){if(n===1)return"rc";let e="";for(let r=0;r<n;r++)e+=t[r],r<n-1&&(e+=",");return e}function Zn(){let n,t,e,r,o,s,c,l,p,f;return ct().getNumber("WEBGL_VERSION")===2?(n="#version 300 es",t="in",e="out",r="in",o="texture",s="outputColor",c="out vec4 outputColor;",l=`
2020-10-11 18:41:17 +02:00
bool isnan_custom(float val) {
return (val > 0.0 || val < 0.0) ? false : val != 0.0;
}
bvec4 isnan_custom(vec4 val) {
return bvec4(isnan_custom(val.x),
isnan_custom(val.y), isnan_custom(val.z), isnan_custom(val.w));
}
#define isnan(value) isnan_custom(value)
2020-11-25 14:30:53 +01:00
`,p="",f=`
2020-10-11 18:41:17 +02:00
#define round(value) newRound(value)
int newRound(float value) {
return int(floor(value + 0.5));
}
ivec4 newRound(vec4 value) {
return ivec4(floor(value + vec4(0.5)));
}
2020-11-25 14:30:53 +01:00
`):(n="",t="attribute",e="varying",r="varying",o="texture2D",s="gl_FragColor",c="",l=`
2020-10-11 18:41:17 +02:00
#define isnan(value) isnan_custom(value)
bool isnan_custom(float val) {
return (val > 0. || val < 1. || val == 0.) ? false : true;
}
bvec4 isnan_custom(vec4 val) {
return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w));
}
2020-11-25 14:30:53 +01:00
`,p=`
2020-10-11 18:41:17 +02:00
uniform float INFINITY;
bool isinf(float val) {
return abs(val) == INFINITY;
}
bvec4 isinf(vec4 val) {
return equal(abs(val), vec4(INFINITY));
}
2020-11-25 14:30:53 +01:00
`,f=`
2020-10-11 18:41:17 +02:00
int round(float value) {
return int(floor(value + 0.5));
}
ivec4 round(vec4 value) {
return ivec4(floor(value + vec4(0.5)));
}
2020-11-25 14:30:53 +01:00
`),{version:n,attribute:t,varyingVs:e,varyingFs:r,texture2D:o,output:s,defineOutput:c,defineSpecialNaN:l,defineSpecialInf:p,defineRound:f}}function _a(n,t,e="index"){let r=Jt(t);return r.map((o,s)=>{let c=`int ${n[s]} = ${e} / ${o}`,l=s===r.length-1?`int ${n[s+1]} = ${e} - ${n[s]} * ${o}`:`index -= ${n[s]} * ${o}`;return`${c}; ${l};`}).join("")}function eg(n){return n.length===1?`${n[0]}`:`vec${n.length}(${n.join(",")})`}function Jst(n,t){if(n.length!==t.length)throw new Error(`Vectors to be dotted must be of the same length -got ${n.length} and ${t.length}`);let e=[],r=Math.floor(n.length/4),o=n.length%4;for(let s=0;s<r;s++){let c=n.slice(s*4,s*4+4),l=t.slice(s*4,s*4+4);e.push(`${eg(c)}, ${eg(l)}`)}if(o!==0){let s=n.slice(r*4),c=t.slice(r*4);s.length===1&&(s=s.map(l=>`float(${l})`),c=c.map(l=>`float(${l})`)),e.push(`${eg(s)}, ${eg(c)}`)}return e.map((s,c)=>`dot(${s})`).join("+")}function P1(n){let t=Jt(n).map(e=>e.toString());return`
2020-10-11 18:41:17 +02:00
int getFlatIndex(ivec3 coords) {
return coords.x * ${t[0]} + coords.y * ${t[1]} + coords.z;
}
2020-11-25 14:30:53 +01:00
`}let DI=`
2020-10-11 18:41:17 +02:00
const float FLOAT_MAX = 1.70141184e38;
const float FLOAT_MIN = 1.17549435e-38;
lowp vec4 encode_float(highp float v) {
if (isnan(v)) {
return vec4(255, 255, 255, 255);
}
highp float av = abs(v);
if(av < FLOAT_MIN) {
return vec4(0.0, 0.0, 0.0, 0.0);
} else if(v > FLOAT_MAX) {
return vec4(0.0, 0.0, 128.0, 127.0) / 255.0;
} else if(v < -FLOAT_MAX) {
return vec4(0.0, 0.0, 128.0, 255.0) / 255.0;
}
highp vec4 c = vec4(0,0,0,0);
highp float e = floor(log2(av));
highp float m = exp2(fract(log2(av))) - 1.0;
c[2] = floor(128.0 * m);
m -= c[2] / 128.0;
c[1] = floor(32768.0 * m);
m -= c[1] / 32768.0;
c[0] = floor(8388608.0 * m);
highp float ebias = e + 127.0;
c[3] = floor(ebias / 2.0);
ebias -= c[3] * 2.0;
c[2] += floor(ebias) * 128.0;
c[3] += 128.0 * step(0.0, -v);
return c / 255.0;
}
2020-11-25 14:30:53 +01:00
`;let{getBroadcastDims:AI}=vv;function JX(n,t,e,r){let o=[];n.forEach(T=>{let N=G(T.shapeInfo.logicalShape);T.shapeInfo.isUniform?o.push(`uniform float ${T.name}${N>1?`[${N}]`:""};`):(o.push(`uniform sampler2D ${T.name};`),o.push(`uniform int offset${T.name};`))});let s=o.join(`
`),c=n.map(T=>ZX(T,t,r)).join(`
`),l=t.texShape,p=Zn(),f=eY(p),m,y,b=oY(p);t.isPacked?(m=QX(t.logicalShape,l),y=rY(p)):(m=tY(t.logicalShape,l),y=nY(p)),r&&(b+=cY);let v=[b,f,y,s,m,c,e].join(`
`);return v}function gl(n){let t=n.shapeInfo.logicalShape;switch(t.length){case 0:return wY(n);case 1:return TY(n);case 2:return NY(n);case 3:return CY(n);case 4:return $Y(n);case 5:return IY(n);case 6:return EY(n);default:throw new Error(`${t.length}-D input sampling is not yet supported`)}}function FI(n){let t=n.shapeInfo.logicalShape;switch(t.length){case 0:return xY(n);case 1:return vY(n);case 2:return kY(n);case 3:return _Y(n);default:return SY(n)}}function ZX(n,t,e=!1){let r="";e?r+=FI(n):r+=gl(n);let o=n.shapeInfo.logicalShape,s=t.logicalShape;return o.length<=s.length&&(e?r+=DY(n,t):r+=AY(n,t)),r}function QX(n,t){switch(n.length){case 0:return RI();case 1:return lY(n,t);case 2:return yY(n,t);case 3:return pY(n,t);default:return fY(n,t)}}function tY(n,t){switch(n.length){case 0:return RI();case 1:return uY(n,t);case 2:return bY(n,t);case 3:return hY(n,t);case 4:return dY(n,t);case 5:return mY(n,t);case 6:return gY(n,t);default:throw new Error(`${n.length}-D output sampling is not yet supported`)}}function eY(n){return`
2020-10-11 18:41:17 +02:00
float sampleTexture(sampler2D textureSampler, vec2 uv) {
2020-11-25 14:30:53 +01:00
return ${n.texture2D}(textureSampler, uv).r;
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function nY(n){return`
2020-10-11 18:41:17 +02:00
void setOutput(float val) {
2020-11-25 14:30:53 +01:00
${n.output} = vec4(val, 0, 0, 0);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function rY(n){return`
2020-10-11 18:41:17 +02:00
void setOutput(vec4 val) {
2020-11-25 14:30:53 +01:00
${n.output} = val;
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function oY(n){let t=`${n.version}
2020-10-11 18:41:17 +02:00
precision highp float;
precision highp int;
precision highp sampler2D;
2020-11-25 14:30:53 +01:00
${n.varyingFs} vec2 resultUV;
${n.defineOutput}
2020-10-11 18:41:17 +02:00
const vec2 halfCR = vec2(0.5, 0.5);
struct ivec5
{
int x;
int y;
int z;
int w;
int u;
};
struct ivec6
{
int x;
int y;
int z;
int w;
int u;
int v;
};
uniform float NAN;
2020-11-25 14:30:53 +01:00
${n.defineSpecialNaN}
${n.defineSpecialInf}
${n.defineRound}
2020-10-11 18:41:17 +02:00
int imod(int x, int y) {
return x - y * (x / y);
}
int idiv(int a, int b, float sign) {
int res = a / b;
int mod = imod(a, b);
if (sign < 0. && mod != 0) {
res -= 1;
}
return res;
}
//Based on the work of Dave Hoskins
//https://www.shadertoy.com/view/4djSRW
#define HASHSCALE1 443.8975
float random(float seed){
vec2 p = resultUV * seed;
vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.x + p3.y) * p3.z);
}
2020-11-25 14:30:53 +01:00
${sY}
${iY}
${aY}
`;return t}let sY=`
2020-10-11 18:41:17 +02:00
vec2 uvFromFlat(int texNumR, int texNumC, int index) {
int texR = index / texNumC;
int texC = index - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
vec2 packedUVfrom1D(int texNumR, int texNumC, int index) {
int texelIndex = index / 2;
int texR = texelIndex / texNumC;
int texC = texelIndex - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
2020-11-25 14:30:53 +01:00
`,iY=`
2020-10-11 18:41:17 +02:00
vec2 packedUVfrom2D(int texelsInLogicalRow, int texNumR,
int texNumC, int row, int col) {
int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2);
int texR = texelIndex / texNumC;
int texC = texelIndex - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
2020-11-25 14:30:53 +01:00
`,aY=`
2020-10-11 18:41:17 +02:00
vec2 packedUVfrom3D(int texNumR, int texNumC,
int texelsInBatch, int texelsInLogicalRow, int b,
int row, int col) {
int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2);
int texR = index / texNumC;
int texC = index - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
2020-11-25 14:30:53 +01:00
`,cY=`
2020-10-11 18:41:17 +02:00
float getChannel(vec4 frag, vec2 innerDims) {
vec2 modCoord = mod(innerDims, 2.);
return modCoord.x == 0. ?
(modCoord.y == 0. ? frag.r : frag.g) :
(modCoord.y == 0. ? frag.b : frag.a);
}
float getChannel(vec4 frag, int dim) {
float modCoord = mod(float(dim), 2.);
return modCoord == 0. ? frag.r : frag.g;
}
2020-11-25 14:30:53 +01:00
`;function RI(){return`
2020-10-11 18:41:17 +02:00
int getOutputCoords() {
return 0;
}
2020-11-25 14:30:53 +01:00
`}function lY(n,t){let e=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)];return e[0]===1?`
2020-10-11 18:41:17 +02:00
int getOutputCoords() {
2020-11-25 14:30:53 +01:00
return 2 * int(resultUV.x * ${e[1]}.0);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`:e[1]===1?`
2020-10-11 18:41:17 +02:00
int getOutputCoords() {
2020-11-25 14:30:53 +01:00
return 2 * int(resultUV.y * ${e[0]}.0);
2020-10-11 18:41:17 +02:00
}
`:`
int getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
2020-11-25 14:30:53 +01:00
vec2(${e[0]}, ${e[1]}));
return 2 * (resTexRC.x * ${e[1]} + resTexRC.y);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function uY(n,t){return t[0]===1?`
2020-10-11 18:41:17 +02:00
int getOutputCoords() {
return int(resultUV.x * ${t[1]}.0);
}
`:t[1]===1?`
int getOutputCoords() {
return int(resultUV.y * ${t[0]}.0);
}
`:`
int getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
return resTexRC.x * ${t[1]} + resTexRC.y;
}
2020-11-25 14:30:53 +01:00
`}function pY(n,t){let e=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)],r=Math.ceil(n[2]/2),o=r*Math.ceil(n[1]/2);return`
2020-10-11 18:41:17 +02:00
ivec3 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
2020-11-25 14:30:53 +01:00
vec2(${e[0]}, ${e[1]}));
int index = resTexRC.x * ${e[1]} + resTexRC.y;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
int b = index / ${o};
index -= b * ${o};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
int r = 2 * (index / ${r});
int c = imod(index, ${r}) * 2;
2020-10-11 18:41:17 +02:00
return ivec3(b, r, c);
}
2020-11-25 14:30:53 +01:00
`}function hY(n,t){let e=_a(["r","c","d"],n);return`
2020-10-11 18:41:17 +02:00
ivec3 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
2020-11-25 14:30:53 +01:00
${e}
2020-10-11 18:41:17 +02:00
return ivec3(r, c, d);
}
2020-11-25 14:30:53 +01:00
`}function fY(n,t){let e=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)],r=Math.ceil(n[n.length-1]/2),o=r*Math.ceil(n[n.length-2]/2),s=o,c="",l="b, r, c";for(let p=2;p<n.length-1;p++)s*=n[n.length-p-1],c=`
int b${p} = index / ${s};
index -= b${p} * ${s};
`+c,l=`b${p}, `+l;return`
ivec${n.length} getOutputCoords() {
2020-10-11 18:41:17 +02:00
ivec2 resTexRC = ivec2(resultUV.yx *
2020-11-25 14:30:53 +01:00
vec2(${e[0]}, ${e[1]}));
int index = resTexRC.x * ${e[1]} + resTexRC.y;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
${c}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
int b = index / ${o};
index -= b * ${o};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
int r = 2 * (index / ${r});
int c = imod(index, ${r}) * 2;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
return ivec${n.length}(${l});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function dY(n,t){let e=_a(["r","c","d","d2"],n);return`
2020-10-11 18:41:17 +02:00
ivec4 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
2020-11-25 14:30:53 +01:00
${e}
2020-10-11 18:41:17 +02:00
return ivec4(r, c, d, d2);
}
2020-11-25 14:30:53 +01:00
`}function mY(n,t){let e=_a(["r","c","d","d2","d3"],n);return`
2020-10-11 18:41:17 +02:00
ivec5 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx * vec2(${t[0]},
${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
2020-11-25 14:30:53 +01:00
${e}
2020-10-11 18:41:17 +02:00
ivec5 outShape = ivec5(r, c, d, d2, d3);
return outShape;
}
2020-11-25 14:30:53 +01:00
`}function gY(n,t){let e=_a(["r","c","d","d2","d3","d4"],n);return`
2020-10-11 18:41:17 +02:00
ivec6 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
2020-11-25 14:30:53 +01:00
${e}
2020-10-11 18:41:17 +02:00
ivec6 result = ivec6(r, c, d, d2, d3, d4);
return result;
}
2020-11-25 14:30:53 +01:00
`}function yY(n,t){let e=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)];if(lt(n,t))return`
2020-10-11 18:41:17 +02:00
ivec2 getOutputCoords() {
2020-11-25 14:30:53 +01:00
return 2 * ivec2(resultUV.yx * vec2(${e[0]}, ${e[1]}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let r=Math.ceil(n[1]/2);return`
2020-10-11 18:41:17 +02:00
ivec2 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
2020-11-25 14:30:53 +01:00
vec2(${e[0]}, ${e[1]}));
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
int index = resTexRC.x * ${e[1]} + resTexRC.y;
int r = 2 * (index / ${r});
int c = imod(index, ${r}) * 2;
2020-10-11 18:41:17 +02:00
return ivec2(r, c);
}
2020-11-25 14:30:53 +01:00
`}function bY(n,t){return lt(n,t)?`
2020-10-11 18:41:17 +02:00
ivec2 getOutputCoords() {
return ivec2(resultUV.yx * vec2(${t[0]}, ${t[1]}));
}
2020-11-25 14:30:53 +01:00
`:n[1]===1?`
2020-10-11 18:41:17 +02:00
ivec2 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
return ivec2(index, 0);
}
2020-11-25 14:30:53 +01:00
`:n[0]===1?`
2020-10-11 18:41:17 +02:00
ivec2 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
return ivec2(0, index);
}
`:`
ivec2 getOutputCoords() {
ivec2 resTexRC = ivec2(resultUV.yx *
vec2(${t[0]}, ${t[1]}));
int index = resTexRC.x * ${t[1]} + resTexRC.y;
2020-11-25 14:30:53 +01:00
int r = index / ${n[1]};
int c = index - r * ${n[1]};
2020-10-11 18:41:17 +02:00
return ivec2(r, c);
}
2020-11-25 14:30:53 +01:00
`}function Ca(n){return`offset${n}`}function xY(n){let t=n.name,e="get"+t.charAt(0).toUpperCase()+t.slice(1),r=Zn();return`
vec4 ${e}() {
return ${r.texture2D}(${t}, halfCR);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function wY(n){let t=n.name,e="get"+t.charAt(0).toUpperCase()+t.slice(1);if(n.shapeInfo.isUniform)return`float ${e}() {return ${t};}`;let[r,o]=n.shapeInfo.texShape;if(r===1&&o===1)return`
float ${e}() {
2020-10-11 18:41:17 +02:00
return sampleTexture(${t}, halfCR);
}
2020-11-25 14:30:53 +01:00
`;let[s,c]=n.shapeInfo.texShape,l=Ca(t);return`
float ${e}() {
vec2 uv = uvFromFlat(${s}, ${c}, ${l});
2020-10-11 18:41:17 +02:00
return sampleTexture(${t}, uv);
}
2020-11-25 14:30:53 +01:00
`}function vY(n){let t=n.name,e="get"+t.charAt(0).toUpperCase()+t.slice(1),r=n.shapeInfo.texShape,o=[Math.ceil(r[0]/2),Math.ceil(r[1]/2)],s=Zn();return`
vec4 ${e}(int index) {
2020-10-11 18:41:17 +02:00
vec2 uv = packedUVfrom1D(
2020-11-25 14:30:53 +01:00
${o[0]}, ${o[1]}, index);
return ${s.texture2D}(${t}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function TY(n){let t=n.name,e="get"+t.charAt(0).toUpperCase()+t.slice(1);if(n.shapeInfo.isUniform)return`
float ${e}(int index) {
${yl(n)}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let r=n.shapeInfo.texShape,o=r[0],s=r[1];if(s===1&&o===1)return`
float ${e}(int index) {
2020-10-11 18:41:17 +02:00
return sampleTexture(${t}, halfCR);
}
2020-11-25 14:30:53 +01:00
`;let c=Ca(t);return s===1?`
float ${e}(int index) {
vec2 uv = vec2(0.5, (float(index + ${c}) + 0.5) / ${o}.0);
2020-10-11 18:41:17 +02:00
return sampleTexture(${t}, uv);
}
2020-11-25 14:30:53 +01:00
`:o===1?`
float ${e}(int index) {
vec2 uv = vec2((float(index + ${c}) + 0.5) / ${s}.0, 0.5);
2020-10-11 18:41:17 +02:00
return sampleTexture(${t}, uv);
}
`:`
2020-11-25 14:30:53 +01:00
float ${e}(int index) {
vec2 uv = uvFromFlat(${o}, ${s}, index + ${c});
2020-10-11 18:41:17 +02:00
return sampleTexture(${t}, uv);
}
2020-11-25 14:30:53 +01:00
`}function kY(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),o=n.shapeInfo.texShape,s=o[0],c=o[1],l=Zn();if(o!=null&&lt(t,o))return`
vec4 ${r}(int row, int col) {
vec2 uv = (vec2(col, row) + halfCR) / vec2(${c}.0, ${s}.0);
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
return ${l.texture2D}(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let p=[Math.ceil(o[0]/2),Math.ceil(o[1]/2)],f=Math.ceil(t[1]/2);return`
vec4 ${r}(int row, int col) {
vec2 uv = packedUVfrom2D(${f}, ${p[0]}, ${p[1]}, row, col);
return ${l.texture2D}(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function NY(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),o=n.shapeInfo.texShape;if(o!=null&&lt(t,o)){let y=o[0],b=o[1];return`
float ${r}(int row, int col) {
vec2 uv = (vec2(col, row) + halfCR) / vec2(${b}.0, ${y}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}let{newShape:s,keptDims:c}=ln(t),l=s;if(l.length<t.length){let y=bl(n,l),b=["row","col"];return`
${gl(y)}
float ${r}(int row, int col) {
return ${r}(${xl(b,c)});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}if(n.shapeInfo.isUniform)return`
float ${r}(int row, int col) {
2020-10-11 18:41:17 +02:00
int index = round(dot(vec2(row, col), vec2(${t[1]}, 1)));
2020-11-25 14:30:53 +01:00
${yl(n)}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let p=o[0],f=o[1],m=Ca(e);return f===1?`
float ${r}(int row, int col) {
2020-10-13 22:57:06 +02:00
float index = dot(vec3(row, col, ${m}), vec3(${t[1]}, 1, 1));
2020-11-25 14:30:53 +01:00
vec2 uv = vec2(0.5, (index + 0.5) / ${p}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`:p===1?`
float ${r}(int row, int col) {
2020-10-13 22:57:06 +02:00
float index = dot(vec3(row, col, ${m}), vec3(${t[1]}, 1, 1));
2020-11-25 14:30:53 +01:00
vec2 uv = vec2((index + 0.5) / ${f}.0, 0.5);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
`:`
2020-11-25 14:30:53 +01:00
float ${r}(int row, int col) {
2020-10-11 18:41:17 +02:00
// Explicitly use integer operations as dot() only works on floats.
2020-10-13 22:57:06 +02:00
int index = row * ${t[1]} + col + ${m};
2020-11-25 14:30:53 +01:00
vec2 uv = uvFromFlat(${p}, ${f}, index);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function _Y(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),o=n.shapeInfo.texShape,s=[Math.ceil(o[0]/2),Math.ceil(o[1]/2)];if(t[0]===1){let y=t.slice(1),b=[1,2],v=bl(n,y),T=["b","row","col"];return`
${FI(v)}
vec4 ${r}(int b, int row, int col) {
return ${r}(${xl(T,b)});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}let c=s[0],l=s[1],p=Math.ceil(t[2]/2),f=p*Math.ceil(t[1]/2),m=Zn();return`
vec4 ${r}(int b, int row, int col) {
2020-10-11 18:41:17 +02:00
vec2 uv = packedUVfrom3D(
2020-11-25 14:30:53 +01:00
${c}, ${l}, ${f}, ${p}, b, row, col);
return ${m.texture2D}(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function CY(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),o=t[1]*t[2],s=t[2],{newShape:c,keptDims:l}=ln(t),p=c;if(p.length<t.length){let T=bl(n,p),N=["row","col","depth"];return`
${gl(T)}
float ${r}(int row, int col, int depth) {
return ${r}(${xl(N,l)});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}if(n.shapeInfo.isUniform)return`
float ${r}(int row, int col, int depth) {
2020-10-11 18:41:17 +02:00
int index = round(dot(vec3(row, col, depth),
2020-11-25 14:30:53 +01:00
vec3(${o}, ${s}, 1)));
${yl(n)}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let f=n.shapeInfo.texShape,m=f[0],y=f[1],b=n.shapeInfo.flatOffset;if(y===o&&b==null)return`
float ${r}(int row, int col, int depth) {
2020-10-11 18:41:17 +02:00
float texR = float(row);
2020-11-25 14:30:53 +01:00
float texC = dot(vec2(col, depth), vec2(${s}, 1));
2020-10-11 18:41:17 +02:00
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${y}.0, ${m}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;if(y===s&&b==null)return`
float ${r}(int row, int col, int depth) {
2020-10-11 18:41:17 +02:00
float texR = dot(vec2(row, col), vec2(${t[1]}, 1));
float texC = float(depth);
2020-11-25 14:30:53 +01:00
vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${y}.0, ${m}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let v=Ca(e);return`
float ${r}(int row, int col, int depth) {
2020-10-11 18:41:17 +02:00
// Explicitly use integer operations as dot() only works on floats.
2020-11-25 14:30:53 +01:00
int index = row * ${o} + col * ${s} + depth + ${v};
vec2 uv = uvFromFlat(${m}, ${y}, index);
return sampleTexture(${e}, uv);
2020-10-13 22:57:06 +02:00
}
2020-11-25 14:30:53 +01:00
`}function SY(n){let t=n.shapeInfo.logicalShape,e=t.length,r=n.name,o="get"+r.charAt(0).toUpperCase()+r.slice(1),s=n.shapeInfo.texShape,c=[Math.ceil(s[0]/2),Math.ceil(s[1]/2)],l=c[0],p=c[1],f=Math.ceil(t[e-1]/2),m=f*Math.ceil(t[e-2]/2),y="int b, int row, int col",b=`b * ${m} + (row / 2) * ${f} + (col / 2)`;for(let T=2;T<e-1;T++)y=`int b${T}, `+y,m*=t[e-T-1],b=`b${T} * ${m} + `+b;let v=Zn();return`
vec4 ${o}(${y}) {
2020-10-13 22:57:06 +02:00
int index = ${b};
2020-11-25 14:30:53 +01:00
int texR = index / ${p};
int texC = index - texR * ${p};
vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${p}, ${l});
return ${v.texture2D}(${r}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function $Y(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),o=t[3],s=t[2]*o,c=t[1]*s,{newShape:l,keptDims:p}=ln(t);if(l.length<t.length){let T=bl(n,l),N=["row","col","depth","depth2"];return`
${gl(T)}
float ${r}(int row, int col, int depth, int depth2) {
return ${r}(${xl(N,p)});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}if(n.shapeInfo.isUniform)return`
float ${r}(int row, int col, int depth, int depth2) {
2020-10-11 18:41:17 +02:00
int index = round(dot(vec4(row, col, depth, depth2),
2020-11-25 14:30:53 +01:00
vec4(${c}, ${s}, ${o}, 1)));
${yl(n)}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let f=n.shapeInfo.flatOffset,m=n.shapeInfo.texShape,y=m[0],b=m[1];if(b===c&&f==null)return`
float ${r}(int row, int col, int depth, int depth2) {
2020-10-11 18:41:17 +02:00
float texR = float(row);
float texC =
dot(vec3(col, depth, depth2),
2020-11-25 14:30:53 +01:00
vec3(${s}, ${o}, 1));
2020-10-11 18:41:17 +02:00
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${b}.0, ${y}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;if(b===o&&f==null)return`
float ${r}(int row, int col, int depth, int depth2) {
2020-10-11 18:41:17 +02:00
float texR = dot(vec3(row, col, depth),
vec3(${t[1]*t[2]}, ${t[2]}, 1));
float texC = float(depth2);
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${b}.0, ${y}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let v=Ca(e);return`
float ${r}(int row, int col, int depth, int depth2) {
2020-10-11 18:41:17 +02:00
// Explicitly use integer operations as dot() only works on floats.
2020-11-25 14:30:53 +01:00
int index = row * ${c} + col * ${s} +
depth * ${o} + depth2;
vec2 uv = uvFromFlat(${y}, ${b}, index + ${v});
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function IY(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),o=t[4],s=t[3]*o,c=t[2]*s,l=t[1]*c,{newShape:p,keptDims:f}=ln(t);if(p.length<t.length){let N=bl(n,p),S=["row","col","depth","depth2","depth3"];return`
${gl(N)}
float ${r}(int row, int col, int depth, int depth2, int depth3) {
return ${r}(${xl(S,f)});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}if(n.shapeInfo.isUniform)return`
float ${r}(int row, int col, int depth, int depth2, int depth3) {
2020-10-11 18:41:17 +02:00
float index = dot(
vec4(row, col, depth, depth2),
2020-11-25 14:30:53 +01:00
vec4(${l}, ${c}, ${s}, ${o})) +
2020-10-11 18:41:17 +02:00
depth3;
2020-11-25 14:30:53 +01:00
${yl(n)}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let m=n.shapeInfo.flatOffset,y=n.shapeInfo.texShape,b=y[0],v=y[1];if(v===l&&m==null)return`
float ${r}(int row, int col, int depth, int depth2, int depth3) {
2020-10-11 18:41:17 +02:00
int texR = row;
float texC = dot(vec4(col, depth, depth2, depth3),
2020-11-25 14:30:53 +01:00
vec4(${c}, ${s}, ${o}, 1));
2020-10-11 18:41:17 +02:00
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${v}.0, ${b}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;if(v===o&&m==null)return`
float ${r}(int row, int col, int depth, int depth2, int depth3) {
2020-10-11 18:41:17 +02:00
float texR = dot(
vec4(row, col, depth, depth2),
vec4(${t[1]*t[2]*t[3]},
${t[2]*t[3]}, ${t[3]}, 1));
int texC = depth3;
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${v}.0, ${b}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let T=Ca(e);return`
float ${r}(int row, int col, int depth, int depth2, int depth3) {
2020-10-11 18:41:17 +02:00
// Explicitly use integer operations as dot() only works on floats.
2020-11-25 14:30:53 +01:00
int index = row * ${l} + col * ${c} + depth * ${s} +
depth2 * ${o} + depth3 + ${T};
vec2 uv = uvFromFlat(${b}, ${v}, index);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function EY(n){let t=n.shapeInfo.logicalShape,e=n.name,r="get"+e.charAt(0).toUpperCase()+e.slice(1),{newShape:o,keptDims:s}=ln(t);if(o.length<t.length){let S=bl(n,o),D=["row","col","depth","depth2","depth3","depth4"];return`
${gl(S)}
float ${r}(int row, int col, int depth,
2020-10-11 18:41:17 +02:00
int depth2, int depth3, int depth4) {
2020-11-25 14:30:53 +01:00
return ${r}(${xl(D,s)});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}let c=t[5],l=t[4]*c,p=t[3]*l,f=t[2]*p,m=t[1]*f;if(n.shapeInfo.isUniform)return`
float ${r}(int row, int col, int depth,
2020-10-11 18:41:17 +02:00
int depth2, int depth3, int depth4) {
int index = round(dot(
vec4(row, col, depth, depth2),
2020-11-25 14:30:53 +01:00
vec4(${m}, ${f}, ${p}, ${l})) +
2020-10-11 18:41:17 +02:00
dot(
vec2(depth3, depth4),
2020-11-25 14:30:53 +01:00
vec2(${c}, 1)));
${yl(n)}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let y=n.shapeInfo.flatOffset,b=n.shapeInfo.texShape,v=b[0],T=b[1];if(T===m&&y==null)return`
float ${r}(int row, int col, int depth,
2020-10-11 18:41:17 +02:00
int depth2, int depth3, int depth4) {
int texR = row;
float texC = dot(vec4(col, depth, depth2, depth3),
2020-11-25 14:30:53 +01:00
vec4(${f}, ${p}, ${l}, ${c})) +
2020-10-11 18:41:17 +02:00
float(depth4);
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${T}.0, ${v}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;if(T===c&&y==null)return`
float ${r}(int row, int col, int depth,
2020-10-11 18:41:17 +02:00
int depth2, int depth3, int depth4) {
float texR = dot(vec4(row, col, depth, depth2),
vec4(${t[1]*t[2]*t[3]*t[4]},
${t[2]*t[3]*t[4]},
${t[3]*t[4]},
${t[4]})) + float(depth3);
int texC = depth4;
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${T}.0, ${v}.0);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;let N=Ca(e);return`
float ${r}(int row, int col, int depth,
2020-10-11 18:41:17 +02:00
int depth2, int depth3, int depth4) {
// Explicitly use integer operations as dot() only works on floats.
2020-11-25 14:30:53 +01:00
int index = row * ${m} + col * ${f} + depth * ${p} +
depth2 * ${l} + depth3 * ${c} + depth4 + ${N};
vec2 uv = uvFromFlat(${v}, ${T}, index);
return sampleTexture(${e}, uv);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function yl(n){let t=n.name,e=G(n.shapeInfo.logicalShape);return e<2?`return ${t};`:`
for (int i = 0; i < ${e}; i++) {
2020-10-11 18:41:17 +02:00
if (i == index) {
return ${t}[i];
}
}
2020-11-25 14:30:53 +01:00
`}function DY(n,t){let e=n.name,r=e.charAt(0).toUpperCase()+e.slice(1),o="get"+r+"AtOutCoords",s=n.shapeInfo.logicalShape.length,c=t.logicalShape.length,l=AI(n.shapeInfo.logicalShape,t.logicalShape),p=Oe(c),f=c-s,m,y=["x","y","z","w","u","v"];s===0?m="":c<2&&l.length>=1?m="coords = 0;":m=l.map(I=>`coords.${y[I+f]} = 0;`).join(`
`);let b="";c<2&&s>0?b="coords":b=n.shapeInfo.logicalShape.map((I,P)=>`coords.${y[P+f]}`).join(", ");let v="return outputValue;",T=G(n.shapeInfo.logicalShape),N=T===1,S=G(t.logicalShape),D=S===1;if(s===1&&!N&&!D)v=`
2020-10-11 18:41:17 +02:00
return vec4(outputValue.xy, outputValue.xy);
2020-11-25 14:30:53 +01:00
`;else if(N&&!D)c===1?v=`
2020-10-11 18:41:17 +02:00
return vec4(outputValue.x, outputValue.x, 0., 0.);
2020-11-25 14:30:53 +01:00
`:v=`
2020-10-11 18:41:17 +02:00
return vec4(outputValue.x);
2020-11-25 14:30:53 +01:00
`;else if(l.length){let I=s-2,P=s-1;l.indexOf(I)>-1&&l.indexOf(P)>-1?v="return vec4(outputValue.x);":l.indexOf(I)>-1?v="return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);":l.indexOf(P)>-1&&(v="return vec4(outputValue.xx, outputValue.zz);")}return`
vec4 ${o}() {
${p} coords = getOutputCoords();
2020-10-13 22:57:06 +02:00
${m}
2020-11-25 14:30:53 +01:00
vec4 outputValue = get${r}(${b});
${v}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function AY(n,t){let e=n.name,r=e.charAt(0).toUpperCase()+e.slice(1),o="get"+r+"AtOutCoords",s=t.texShape,c=n.shapeInfo.texShape,l=n.shapeInfo.logicalShape.length,p=t.logicalShape.length;if(!n.shapeInfo.isUniform&&l===p&&n.shapeInfo.flatOffset==null&&lt(c,s))return`
float ${o}() {
return sampleTexture(${e}, resultUV);
}
`;let f=Oe(p),m=AI(n.shapeInfo.logicalShape,t.logicalShape),y=p-l,b,v=["x","y","z","w","u","v"];l===0?b="":p<2&&m.length>=1?b="coords = 0;":b=m.map(N=>`coords.${v[N+y]} = 0;`).join(`
`);let T="";return p<2&&l>0?T="coords":T=n.shapeInfo.logicalShape.map((N,S)=>`coords.${v[S+y]}`).join(", "),`
float ${o}() {
${f} coords = getOutputCoords();
2020-10-13 22:57:06 +02:00
${b}
2020-11-25 14:30:53 +01:00
return get${r}(${T});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}function Oe(n){if(n<=1)return"int";if(n===2)return"ivec2";if(n===3)return"ivec3";if(n===4)return"ivec4";if(n===5)return"ivec5";if(n===6)return"ivec6";throw Error(`GPU for rank ${n} is not yet supported`)}function bl(n,t){let e=JSON.parse(JSON.stringify(n));return e.shapeInfo.logicalShape=t,e}function xl(n,t){return t.map(e=>n[e]).join(", ")}class FY{constructor(t,e,r,o){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,_(t.length>2,()=>`Packed arg${r.charAt(0).toUpperCase()+r.slice(1)} supports only inputs with rank above 2.`);let s=t[t.length-1],c=Math.ceil(s/e);this.outputShape=t.slice(0,-1),c>1&&this.outputShape.push(c),o||this.variableNames.push("bestIndicesA");let l=this.outputShape,p=l.length,f=Oe(p),m=Jn("coords",p),y,b;if(c===1){b=p+1;let H=Oe(b);y=`
${H} sourceLocR = ${H}(${m.join()}, 0);
++${m[p-1]};
${H} sourceLocG = ${H}(${m.join()}, 0);
++${m[p-2]};
${H} sourceLocA = ${H}(${m.join()}, 0);
--${m[p-1]};
${H} sourceLocB = ${H}(${m.join()}, 0);
--${m[p-2]};`}else b=p,y=`
${f} sourceLocR = coords;
++${m[p-1]};
${f} sourceLocG = coords;
++${m[p-2]};
${f} sourceLocA = coords;
--${m[p-1]};
${f} sourceLocB = coords;
--${m[p-2]};`;let v=["x","y","z","w","u","v"].slice(0,b),T="."+v[b-1],N=v.map(H=>"int "+H),S=Jn("sourceLocR",b-1).concat("inIdx.r"),D=Jn("sourceLocG",b-1).concat("inIdx.g"),I=Jn("sourceLocB",b-1).concat("inIdx.b"),P=Jn("sourceLocA",b-1).concat("inIdx.a"),E=r==="max"?"greaterThan":"lessThan",L=o?"":`
inIdx = round(vec4(getBestIndicesAChannel(${S.join()}),
getBestIndicesAChannel(${D.join()}),
getBestIndicesAChannel(${I.join()}),
getBestIndicesAChannel(${P.join()})));`,B=`vec4(
getAChannel(${S.join()}),
hasNextCol ? getAChannel(${D.join()}) : 0.,
hasNextRow ? getAChannel(${I.join()}) : 0.,
hasNextRow && hasNextCol ? getAChannel(${P.join()}) : 0.)`,q=o?"":`
float getBestIndicesAChannel(${N.join()}) {
return getChannel(getBestIndicesA(${v.join()}),
vec2(${v.slice(-2).join()}));
2020-10-11 18:41:17 +02:00
}`;this.userCode=`
2020-11-25 14:30:53 +01:00
float getAChannel(${N.join()}) {
return getChannel(getA(${v.join()}),
vec2(${v.slice(-2).join()}));
}
${q}
void main() {
${f} coords = getOutputCoords();
bool hasNextCol = ${m[p-1]} < ${l[p-1]-1};
bool hasNextRow = ${m[p-2]} < ${l[p-2]-1};
${y}
ivec4 srcIdx = ivec4(sourceLocR${T}, sourceLocG${T},
sourceLocB${T}, sourceLocA${T}) * ${e};
2020-10-11 18:41:17 +02:00
ivec4 inIdx = srcIdx;
vec4 bestIndex = vec4(inIdx);
2020-11-25 14:30:53 +01:00
vec4 bestValue = ${B};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${e}; i++) {
2020-10-11 18:41:17 +02:00
inIdx = srcIdx;
2020-11-25 14:30:53 +01:00
${L}
vec4 candidate = ${B};
2020-10-11 18:41:17 +02:00
bvec4 nan = isnan(candidate);
bvec4 replace = bvec4(
2020-10-29 05:16:50 +01:00
vec4(${E}(candidate, bestValue)) * (vec4(1.0) - vec4(nan)));
2020-10-11 18:41:17 +02:00
bestValue = vec4(replace.x ? candidate.x : bestValue.x,
replace.y ? candidate.y : bestValue.y,
replace.z ? candidate.z : bestValue.z,
replace.w ? candidate.w : bestValue.w);
bestIndex = mix(bestIndex, vec4(inIdx), vec4(replace));
srcIdx++;
}
setOutput(bestIndex);
}
2020-11-25 14:30:53 +01:00
`}}class RY{constructor(t){this.variableNames=["dy"],this.outputShape=t.inShape;let e=t.filterHeight,r=t.filterWidth,o=t.strideHeight,s=t.strideWidth,c=t.dilationHeight,l=t.dilationWidth,p=t.effectiveFilterHeight,f=t.effectiveFilterWidth,m=p-1-t.padInfo.top,y=f-1-t.padInfo.left,b=1/(e*r);this.userCode=`
const ivec2 pads = ivec2(${m}, ${y});
const float avgMultiplier = float(${b});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
ivec2 dyRCCorner = coords.yz - pads;
int dyRCorner = dyRCCorner.x;
int dyCCorner = dyRCCorner.y;
// Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${p};
wR += ${c}) {
float dyR = float(dyRCorner + wR) / ${o}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 || fract(dyR) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${f};
wC+= ${l}) {
float dyC = float(dyCCorner + wC) / ${s}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
float dyValue = getDy(b, idyR, idyC, d);
dotProd += dyValue * avgMultiplier;
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class PY{constructor(t){this.variableNames=["dy"],this.outputShape=t.inShape;let e=t.filterDepth,r=t.filterHeight,o=t.filterWidth,s=t.strideDepth,c=t.strideHeight,l=t.strideWidth,p=t.dilationDepth,f=t.dilationHeight,m=t.dilationWidth,y=t.effectiveFilterDepth,b=t.effectiveFilterHeight,v=t.effectiveFilterWidth,T=y-1-t.padInfo.front,N=b-1-t.padInfo.top,S=v-1-t.padInfo.left,D=1/(e*r*o);this.userCode=`
const ivec3 pads = ivec3(${T}, ${N}, ${S});
const float avgMultiplier = float(${D});
2020-10-11 18:41:17 +02:00
void main() {
ivec5 coords = getOutputCoords();
int batch = coords.x;
int ch = coords.u;
ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;
int dyDCorner = dyCorner.x;
int dyRCorner = dyCorner.y;
int dyCCorner = dyCorner.z;
// Convolve dy(?, ?, ?, d) with pos mask(:, :, :, ch) to get
// dx(xD, xR, xC, ch).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wD = 0; wD < ${y};
wD += ${p}) {
float dyD = float(dyDCorner + wD) / ${s}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyD < 0.0 || dyD >= ${t.outDepth}.0 || fract(dyD) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyD = int(dyD);
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${b};
wR += ${f}) {
float dyR = float(dyRCorner + wR) / ${c}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyR) > 0.0) {
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${v};
wC += ${m}) {
float dyC = float(dyCCorner + wC) / ${l}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
float dyValue = getDy(batch, idyD, idyR, idyC, ch);
dotProd += dyValue * avgMultiplier;
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}let PI=`
2020-10-11 18:41:17 +02:00
if (isnan(a)) return a;
if (isnan(b)) return b;
2020-11-25 14:30:53 +01:00
`,OY=`
2020-10-11 18:41:17 +02:00
float s = sign(a) * sign(b);
int ia = round(a);
int ib = round(b);
if (ib != 0) {
// Windows (D3D) wants guaranteed non-zero int division at compile-time.
return float(idiv(ia, ib, s));
} else {
return NAN;
}
2020-11-25 14:30:53 +01:00
`,LY=`
2020-10-11 18:41:17 +02:00
if(a < 0.0 && floor(b) < b){
return NAN;
}
if (b == 0.0) {
return 1.0;
}
return (round(mod(b, 2.0)) != 1) ?
pow(abs(a), b) : sign(a) * pow(abs(a), b);
2020-11-25 14:30:53 +01:00
`,Zst="return (a - b) * (a - b);",MY="return float(a == b);",BY="return float(a < b);",zY="return float(a <= b);",WY="return float(a > b);",VY="return float(a >= b);",GY="return float(a >= 1.0 && b >= 1.0);",UY="return float(a >= 1.0 || b >= 1.0);",qY=PI+`
2020-10-11 18:41:17 +02:00
return max(a, b);
2020-11-25 14:30:53 +01:00
`,HY=PI+`
2020-10-11 18:41:17 +02:00
return min(a, b);
2020-11-25 14:30:53 +01:00
`,jY=`if (b == 0.0) return NAN;
return mod(a, b);`,KY="return (b >= 1.0) ? a : a * (b + 1.0);",OI="return (a < 0.) ? b * a : a;";class Hn{constructor(t,e,r){this.variableNames=["A","B"],this.outputShape=le(e,r),this.userCode=`
2020-10-11 18:41:17 +02:00
float binaryOperation(float a, float b) {
2020-11-25 14:30:53 +01:00
${t}
2020-10-11 18:41:17 +02:00
}
void main() {
float a = getAAtOutCoords();
float b = getBAtOutCoords();
setOutput(binaryOperation(a, b));
}
2020-11-25 14:30:53 +01:00
`}}let ng=`
2020-10-11 18:41:17 +02:00
result.r = isNaN.r > 0. ? NAN : result.r;
result.g = isNaN.g > 0. ? NAN : result.g;
result.b = isNaN.b > 0. ? NAN : result.b;
result.a = isNaN.a > 0. ? NAN : result.a;
2020-11-25 14:30:53 +01:00
`,XY=`
2020-10-11 18:41:17 +02:00
ivec4 ia = round(a);
ivec4 ib = round(b);
bvec4 cond = notEqual(ib, ivec4(0));
ivec4 result = ivec4(0);
vec4 s = sign(a) * sign(b);
// Windows (D3D) wants guaranteed non-zero int division at compile-time.
if (cond[0]) {
result[0] = idiv(ia[0], ib[0], s[0]);
}
if (cond[1]) {
result[1] = idiv(ia[1], ib[1], s[1]);
}
if (cond[2]) {
result[2] = idiv(ia[2], ib[2], s[2]);
}
if (cond[3]) {
result[3] = idiv(ia[3], ib[3], s[3]);
}
return vec4(result);
2020-11-25 14:30:53 +01:00
`,YY=`
2020-10-11 18:41:17 +02:00
// isModRound1 has 1 for components with round(mod(b, 2.0)) == 1, 0 otherwise.
vec4 isModRound1 = vec4(equal(round(mod(b, 2.0)), ivec4(1)));
vec4 multiplier = sign(a) * isModRound1 + (vec4(1.0) - isModRound1);
vec4 result = multiplier * pow(abs(a), b);
// Ensure that a^0 = 1, including 0^0 = 1 as this correspond to TF and JS
bvec4 isExpZero = equal(b, vec4(0.0));
result.r = isExpZero.r ? 1.0 : result.r;
result.g = isExpZero.g ? 1.0 : result.g;
result.b = isExpZero.b ? 1.0 : result.b;
result.a = isExpZero.a ? 1.0 : result.a;
vec4 isNaN = vec4(lessThan(a, vec4(0.0))) * vec4(lessThan(floor(b), b));
2020-11-25 14:30:53 +01:00
`+ng+`
2020-10-11 18:41:17 +02:00
return result;
2020-11-25 14:30:53 +01:00
`,LI=`
2020-10-11 18:41:17 +02:00
vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));
return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);
2020-11-25 14:30:53 +01:00
`,JY=`
2020-10-11 18:41:17 +02:00
vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.)));
return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0))));
2020-11-25 14:30:53 +01:00
`,ZY=`
2020-10-11 18:41:17 +02:00
return vec4(equal(a, b));
2020-11-25 14:30:53 +01:00
`,Qst=`
2020-10-11 18:41:17 +02:00
return vec4(notEqual(a, b));
2020-11-25 14:30:53 +01:00
`,QY=`
2020-10-11 18:41:17 +02:00
return vec4(lessThan(a, b));
2020-11-25 14:30:53 +01:00
`,t7=`
2020-10-11 18:41:17 +02:00
return vec4(lessThanEqual(a, b));
2020-11-25 14:30:53 +01:00
`,e7=`
2020-10-11 18:41:17 +02:00
return vec4(greaterThan(a, b));
2020-11-25 14:30:53 +01:00
`,n7=`
2020-10-11 18:41:17 +02:00
return vec4(greaterThanEqual(a, b));
2020-11-25 14:30:53 +01:00
`,r7=`
2020-10-11 18:41:17 +02:00
return vec4(
vec4(greaterThanEqual(a, vec4(1.0))) *
vec4(greaterThanEqual(b, vec4(1.0))));
2020-11-25 14:30:53 +01:00
`,o7=`
2020-10-11 18:41:17 +02:00
return min(
vec4(greaterThanEqual(a, vec4(1.0))) +
vec4(greaterThanEqual(b, vec4(1.0))),
vec4(1.0));
2020-11-25 14:30:53 +01:00
`,s7=`
2020-10-11 18:41:17 +02:00
vec4 result = vec4(max(a, b));
vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));
2020-11-25 14:30:53 +01:00
`+ng+`
2020-10-11 18:41:17 +02:00
return result;
2020-11-25 14:30:53 +01:00
`,i7=`
2020-10-11 18:41:17 +02:00
vec4 result = vec4(min(a, b));
vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));
2020-11-25 14:30:53 +01:00
`+ng+`
2020-10-11 18:41:17 +02:00
return result;
2020-11-25 14:30:53 +01:00
`,a7=`
2020-10-11 18:41:17 +02:00
vec4 result = mod(a, b);
vec4 isNaN = vec4(equal(b, vec4(0.0)));
2020-11-25 14:30:53 +01:00
`+ng+`
2020-10-11 18:41:17 +02:00
return result;
2020-11-25 14:30:53 +01:00
`;class Ss{constructor(t,e,r,o=!1){this.variableNames=["A","B"],this.supportsBroadcasting=!0,this.packedInputs=!0,this.packedOutput=!0,this.outputShape=le(e,r);let s=this.outputShape.length,c="";if(o)if(s===0||G(this.outputShape)===1)c=`
2020-10-11 18:41:17 +02:00
result.y = 0.;
result.z = 0.;
result.w = 0.;
2020-11-25 14:30:53 +01:00
`;else{let l=Oe(s);if(c=`
${l} coords = getOutputCoords();
`,s===1)c+=`
2020-10-11 18:41:17 +02:00
result.y = (coords + 1) >= ${this.outputShape[0]} ? 0. : result.y;
result.z = 0.;
result.w = 0.;
2020-11-25 14:30:53 +01:00
`;else{let p=Jn("coords",s);c+=`
2020-10-11 18:41:17 +02:00
bool nextRowOutOfBounds =
2020-11-25 14:30:53 +01:00
(${p[s-2]} + 1) >= ${this.outputShape[s-2]};
2020-10-11 18:41:17 +02:00
bool nextColOutOfBounds =
2020-11-25 14:30:53 +01:00
(${p[s-1]} + 1) >= ${this.outputShape[s-1]};
2020-10-11 18:41:17 +02:00
result.y = nextColOutOfBounds ? 0. : result.y;
result.z = nextRowOutOfBounds ? 0. : result.z;
result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w;
`}}this.userCode=`
vec4 binaryOperation(vec4 a, vec4 b) {
2020-11-25 14:30:53 +01:00
${t}
2020-10-11 18:41:17 +02:00
}
void main() {
vec4 a = getAAtOutCoords();
vec4 b = getBAtOutCoords();
vec4 result = binaryOperation(a, b);
2020-11-25 14:30:53 +01:00
${c}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class c7{constructor(t){this.variableNames=["A"],this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
uniform float minVal;
uniform float maxVal;
void main() {
float value = getAAtOutCoords();
if (isnan(value)) {
setOutput(value);
return;
}
setOutput(clamp(value, minVal, maxVal));
}
2020-11-25 14:30:53 +01:00
`}getCustomSetupFunc(t,e){return(r,o)=>{this.minLoc==null&&(this.minLoc=r.getUniformLocationNoThrow(o,"minVal"),this.maxLoc=r.getUniformLocationNoThrow(o,"maxVal")),r.gl.uniform1f(this.minLoc,t),r.gl.uniform1f(this.maxLoc,e)}}}class l7{constructor(t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
uniform float minVal;
uniform float maxVal;
void main() {
vec4 value = getAAtOutCoords();
if (any(isnan(value))) {
setOutput(value);
return;
}
setOutput(clamp(value, vec4(minVal), vec4(maxVal)));
}
2020-11-25 14:30:53 +01:00
`}getCustomSetupFunc(t,e){return(r,o)=>{this.minLoc==null&&(this.minLoc=r.getUniformLocationNoThrow(o,"minVal"),this.maxLoc=r.getUniformLocationNoThrow(o,"maxVal")),r.gl.uniform1f(this.minLoc,t),r.gl.uniform1f(this.maxLoc,e)}}}class u7{constructor(t){this.variableNames=["real","imag"],this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
float re = abs(getRealAtOutCoords());
float im = abs(getImagAtOutCoords());
float mx = max(re, im);
// sadly the length function in glsl is not underflow-safe
// (at least not on Intel GPUs). So the safe solution is
// to ensure underflow-safety in all cases.
setOutput(
mx == 0.0 ? 0.0 : mx * length(vec2(1, min(re, im)/mx))
);
}
2020-11-25 14:30:53 +01:00
`}}class p7{constructor(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;let e=t.strideHeight,r=t.strideWidth,o=t.padInfo.top,s=t.padInfo.left,c=t.dataFormat==="channelsLast";this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int wR = coords.x;
int wC = coords.y;
int d1 = coords.z;
int d2 = coords.w;
// Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int b = 0; b < ${t.batchSize}; b++) {
for (int yR = 0; yR < ${t.outHeight}; yR++) {
int xR = wR + yR * ${e} - ${o};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int yC = 0; yC < ${t.outWidth}; yC++) {
int xC = wC + yC * ${r} - ${s};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
if (${c}) {
2020-10-11 18:41:17 +02:00
float dyValue = getDy(b, yR, yC, d2);
float xValue = getX(b, xR, xC, d1);
dotProd += (xValue * dyValue);
} else {
float dyValue = getDy(b, d2, yR, yC);
float xValue = getX(b, d1, xR, xC);
dotProd += (xValue * dyValue);
}
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class h7{constructor(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;let e=t.filterHeight,r=t.filterWidth,o=t.strideHeight,s=t.strideWidth,c=t.dataFormat==="channelsLast",l=e-1-t.padInfo.top,p=r-1-t.padInfo.left,f=c?1:2,m=c?2:3,y=c?3:1;this.userCode=`
const ivec2 pads = ivec2(${l}, ${p});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int batch = coords[0];
2020-11-25 14:30:53 +01:00
int d1 = coords[${y}];
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
ivec2 dyCorner = ivec2(coords[${f}], coords[${m}]) - pads;
2020-10-11 18:41:17 +02:00
int dyRCorner = dyCorner.x;
int dyCCorner = dyCorner.y;
// Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${e}; wR++) {
float dyR = float(dyRCorner + wR) / ${o}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 || fract(dyR) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
int wRPerm = ${e} - 1 - wR;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${r}; wC++) {
float dyC = float(dyCCorner + wC) / ${s}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
2020-11-25 14:30:53 +01:00
int wCPerm = ${r} - 1 - wC;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int d2 = 0; d2 < ${t.outChannels}; d2++) {
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (${c}) {
2020-10-11 18:41:17 +02:00
float xValue = getDy(batch, idyR, idyC, d2);
float wValue = getW(wRPerm, wCPerm, d1, d2);
dotProd += xValue * wValue;
} else {
float xValue = getDy(batch, d2, idyR, idyC);
float wValue = getW(wRPerm, wCPerm, d1, d2);
dotProd += xValue * wValue;
}
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class f7{constructor(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;let e=t.strideDepth,r=t.strideHeight,o=t.strideWidth,s=t.padInfo.front,c=t.padInfo.top,l=t.padInfo.left;this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec5 coords = getOutputCoords();
int wF = coords.x;
int wR = coords.y;
int wC = coords.z;
int d1 = coords.w;
int d2 = coords.u;
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int b = 0; b < ${t.batchSize}; b++) {
for (int yF = 0; yF < ${t.outDepth}; yF++) {
int xF = wF + yF * ${e} - ${s};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xF < 0 || xF >= ${t.inDepth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int yR = 0; yR < ${t.outHeight}; yR++) {
int xR = wR + yR * ${r} - ${c};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int yC = 0; yC < ${t.outWidth}; yC++) {
int xC = wC + yC * ${o} - ${l};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
float dyValue = getDy(b, yF, yR, yC, d2);
float xValue = getX(b, xF, xR, xC, d1);
dotProd += (xValue * dyValue);
}
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class d7{constructor(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;let e=t.filterDepth,r=t.filterHeight,o=t.filterWidth,s=t.strideDepth,c=t.strideHeight,l=t.strideWidth,p=e-1-t.padInfo.front,f=r-1-t.padInfo.top,m=o-1-t.padInfo.left;this.userCode=`
const ivec3 pads = ivec3(${p}, ${f}, ${m});
2020-10-11 18:41:17 +02:00
void main() {
ivec5 coords = getOutputCoords();
int batch = coords.x;
int d1 = coords.u;
ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;
int dyFCorner = dyCorner.x;
int dyRCorner = dyCorner.y;
int dyCCorner = dyCorner.z;
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wF = 0; wF < ${e}; wF++) {
float dyF = float(dyFCorner + wF) / ${s}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyF < 0.0 || dyF >= ${t.outDepth}.0 || fract(dyF) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyF = int(dyF);
2020-11-25 14:30:53 +01:00
int wFPerm = ${e} - 1 - wF;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${r}; wR++) {
float dyR = float(dyRCorner + wR) / ${c}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyR) > 0.0) {
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
int wRPerm = ${r} - 1 - wR;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${o}; wC++) {
float dyC = float(dyCCorner + wC) / ${l}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
2020-11-25 14:30:53 +01:00
int wCPerm = ${o} - 1 - wC;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int d2 = 0; d2 < ${t.outChannels}; d2++) {
2020-10-11 18:41:17 +02:00
float xValue = getDy(batch, idyF, idyR, idyC, d2);
float wValue = getW(wFPerm, wRPerm, wCPerm, d1, d2);
dotProd += xValue * wValue;
}
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class m7{constructor(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;let e=t.strideHeight,r=t.strideWidth,o=t.padInfo.top,s=t.padInfo.left,c=t.outChannels/t.inChannels;this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int wR = coords.x;
int wC = coords.y;
int d1 = coords.z;
int dm = coords.w;
2020-11-25 14:30:53 +01:00
int d2 = d1 * ${c} + dm;
2020-10-11 18:41:17 +02:00
float dotProd = 0.0;
// TO DO: Vec4 over the batch size
2020-11-25 14:30:53 +01:00
for (int b = 0; b < ${t.batchSize}; b++) {
for (int yR = 0; yR < ${t.outHeight}; yR++) {
int xR = wR + yR * ${e} - ${o};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int yC = 0; yC < ${t.outWidth}; yC++) {
int xC = wC + yC * ${r} - ${s};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
float dyValue = getDy(b, yR, yC, d2);
float xValue = getX(b, xR, xC, d1);
dotProd += (xValue * dyValue);
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class g7{constructor(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;let e=t.filterHeight,r=t.filterWidth,o=t.strideHeight,s=t.strideWidth,c=e-1-t.padInfo.top,l=r-1-t.padInfo.left,p=t.outChannels/t.inChannels;this.userCode=`
const ivec2 pads = ivec2(${c}, ${l});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int batch = coords[0];
int d1 = coords[3];
ivec2 dyCorner = coords.yz - pads;
int dyRCorner = dyCorner.x;
int dyCCorner = dyCorner.y;
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${e}; wR++) {
float dyR = float(dyRCorner + wR) / ${o}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 || fract(dyR) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
int wRPerm = ${e} - 1 - wR;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${r}; wC++) {
float dyC = float(dyCCorner + wC) / ${s}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
2020-11-25 14:30:53 +01:00
int wCPerm = ${r} - 1 - wC;
2020-10-11 18:41:17 +02:00
// TO DO: Vec4 over the channelMul
2020-11-25 14:30:53 +01:00
for (int dm = 0; dm < ${p}; dm++) {
int d2 = d1 * ${p} + dm;
2020-10-11 18:41:17 +02:00
float xValue = getDy(batch, idyR, idyC, d2);
float wValue = getW(wRPerm, wCPerm, d1, dm);
dotProd += xValue * wValue;
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class MI{constructor(t,e=!1,r=null,o=!1){this.variableNames=["x","W"],this.outputShape=t.outShape;let s=t.padInfo.top,c=t.padInfo.left,l=t.strideHeight,p=t.strideWidth,f=t.dilationHeight,m=t.dilationWidth,y=t.filterHeight,b=t.filterWidth,v=Math.floor(t.inChannels/4)*4,T=t.inChannels%4,N=t.dataFormat==="channelsLast",S=N?1:2,D=N?2:3,I=N?3:1,P="",E="";r&&(o?P=`float activation(float a) {
2020-10-11 18:41:17 +02:00
float b = getPreluActivationWeightsAtOutCoords();
2020-11-25 14:30:53 +01:00
${r}
}`:P=`
2020-10-11 18:41:17 +02:00
float activation(float x) {
2020-11-25 14:30:53 +01:00
${r}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`,E="result = activation(result);");let L=e?"result += getBiasAtOutCoords();":"";e&&this.variableNames.push("bias"),o&&this.variableNames.push("preluActivationWeights"),this.userCode=`
${P}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const ivec2 strides = ivec2(${l}, ${p});
const ivec2 pads = ivec2(${s}, ${c});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int batch = coords[0];
2020-11-25 14:30:53 +01:00
int d2 = coords[${I}];
2020-10-11 18:41:17 +02:00
ivec2 xRCCorner =
2020-11-25 14:30:53 +01:00
ivec2(coords[${S}], coords[${D}]) * strides - pads;
2020-10-11 18:41:17 +02:00
int xRCorner = xRCCorner.x;
int xCCorner = xRCCorner.y;
// Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${y}; wR++) {
int xR = xRCorner + wR * ${f};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${b}; wC++) {
int xC = xCCorner + wC * ${m};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int d1 = 0; d1 < ${v}; d1 += 4) {
2020-10-11 18:41:17 +02:00
vec4 wValues = vec4(
getW(wR, wC, d1, d2),
getW(wR, wC, d1 + 1, d2),
getW(wR, wC, d1 + 2, d2),
getW(wR, wC, d1 + 3, d2)
);
2020-11-25 14:30:53 +01:00
if (${N}) {
2020-10-11 18:41:17 +02:00
vec4 xValues = vec4(
getX(batch, xR, xC, d1),
getX(batch, xR, xC, d1 + 1),
getX(batch, xR, xC, d1 + 2),
getX(batch, xR, xC, d1 + 3)
);
dotProd += dot(xValues, wValues);
} else {
vec4 xValues = vec4(
getX(batch, d1, xR, xC),
getX(batch, d1 + 1, xR, xC),
getX(batch, d1 + 2, xR, xC),
getX(batch, d1 + 3, xR, xC)
);
dotProd += dot(xValues, wValues);
}
}
2020-11-25 14:30:53 +01:00
if (${T===1}) {
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (${N}) {
2020-10-11 18:41:17 +02:00
dotProd +=
2020-11-25 14:30:53 +01:00
getX(batch, xR, xC, ${v}) *
getW(wR, wC, ${v}, d2);
2020-10-11 18:41:17 +02:00
} else {
dotProd +=
2020-11-25 14:30:53 +01:00
getX(batch, ${v}, xR, xC) *
getW(wR, wC, ${v}, d2);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
} else if (${T===2}) {
2020-10-11 18:41:17 +02:00
vec2 wValues = vec2(
2020-11-25 14:30:53 +01:00
getW(wR, wC, ${v}, d2),
getW(wR, wC, ${v} + 1, d2)
2020-10-11 18:41:17 +02:00
);
2020-11-25 14:30:53 +01:00
if (${N}) {
2020-10-11 18:41:17 +02:00
vec2 xValues = vec2(
2020-11-25 14:30:53 +01:00
getX(batch, xR, xC, ${v}),
getX(batch, xR, xC, ${v} + 1)
2020-10-11 18:41:17 +02:00
);
dotProd += dot(xValues, wValues);
} else {
vec2 xValues = vec2(
2020-11-25 14:30:53 +01:00
getX(batch, ${v}, xR, xC),
getX(batch, ${v} + 1, xR, xC)
2020-10-11 18:41:17 +02:00
);
dotProd += dot(xValues, wValues);
}
2020-11-25 14:30:53 +01:00
} else if (${T===3}) {
2020-10-11 18:41:17 +02:00
vec3 wValues = vec3(
2020-11-25 14:30:53 +01:00
getW(wR, wC, ${v}, d2),
getW(wR, wC, ${v} + 1, d2),
getW(wR, wC, ${v} + 2, d2)
2020-10-11 18:41:17 +02:00
);
2020-11-25 14:30:53 +01:00
if (${N}) {
2020-10-11 18:41:17 +02:00
vec3 xValues = vec3(
2020-11-25 14:30:53 +01:00
getX(batch, xR, xC, ${v}),
getX(batch, xR, xC, ${v} + 1),
getX(batch, xR, xC, ${v} + 2)
2020-10-11 18:41:17 +02:00
);
dotProd += dot(xValues, wValues);
} else {
vec3 xValues = vec3(
2020-11-25 14:30:53 +01:00
getX(batch, ${v}, xR, xC),
getX(batch, ${v} + 1, xR, xC),
getX(batch, ${v} + 2, xR, xC)
2020-10-11 18:41:17 +02:00
);
dotProd += dot(xValues, wValues);
}
}
}
}
float result = dotProd;
2020-11-25 14:30:53 +01:00
${L}
2020-10-29 05:16:50 +01:00
${E}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class y7{constructor(t){this.variableNames=["x","W"],this.outputShape=t.outShape;let e=t.padInfo.front,r=t.padInfo.top,o=t.padInfo.left,s=t.strideDepth,c=t.strideHeight,l=t.strideWidth,p=t.dilationDepth,f=t.dilationHeight,m=t.dilationWidth,y=t.filterDepth,b=t.filterHeight,v=t.filterWidth,T=Math.floor(t.inChannels/4)*4,N=t.inChannels%4;this.userCode=`
const ivec3 strides = ivec3(${s}, ${c}, ${l});
const ivec3 pads = ivec3(${e}, ${r}, ${o});
2020-10-11 18:41:17 +02:00
void main() {
ivec5 coords = getOutputCoords();
int batch = coords.x;
int d2 = coords.u;
ivec3 xFRCCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;
int xFCorner = xFRCCorner.x;
int xRCorner = xFRCCorner.y;
int xCCorner = xFRCCorner.z;
// Convolve x(?, ?, ?, d1) with w(:, :, :, d1, d2) to get
// y(yF, yR, yC, d2). ? = to be determined. : = across all
// values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wF = 0; wF < ${y}; wF++) {
int xF = xFCorner + wF * ${p};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xF < 0 || xF >= ${t.inDepth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${b}; wR++) {
int xR = xRCorner + wR * ${f};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${v}; wC++) {
int xC = xCCorner + wC * ${m};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int d1 = 0; d1 < ${T}; d1 += 4) {
2020-10-11 18:41:17 +02:00
vec4 xValues = vec4(
getX(batch, xF, xR, xC, d1),
getX(batch, xF, xR, xC, d1 + 1),
getX(batch, xF, xR, xC, d1 + 2),
getX(batch, xF, xR, xC, d1 + 3)
);
vec4 wValues = vec4(
getW(wF, wR, wC, d1, d2),
getW(wF, wR, wC, d1 + 1, d2),
getW(wF, wR, wC, d1 + 2, d2),
getW(wF, wR, wC, d1 + 3, d2)
);
dotProd += dot(xValues, wValues);
}
2020-11-25 14:30:53 +01:00
if (${N===1}) {
2020-10-11 18:41:17 +02:00
dotProd +=
2020-11-25 14:30:53 +01:00
getX(batch, xF, xR, xC, ${T}) *
getW(wF, wR, wC, ${T}, d2);
} else if (${N===2}) {
2020-10-11 18:41:17 +02:00
vec2 xValues = vec2(
2020-11-25 14:30:53 +01:00
getX(batch, xF, xR, xC, ${T}),
getX(batch, xF, xR, xC, ${T} + 1)
2020-10-11 18:41:17 +02:00
);
vec2 wValues = vec2(
2020-11-25 14:30:53 +01:00
getW(wF, wR, wC, ${T}, d2),
getW(wF, wR, wC, ${T} + 1, d2)
2020-10-11 18:41:17 +02:00
);
dotProd += dot(xValues, wValues);
2020-11-25 14:30:53 +01:00
} else if (${N===3}) {
2020-10-11 18:41:17 +02:00
vec3 xValues = vec3(
2020-11-25 14:30:53 +01:00
getX(batch, xF, xR, xC, ${T}),
getX(batch, xF, xR, xC, ${T} + 1),
getX(batch, xF, xR, xC, ${T} + 2)
2020-10-11 18:41:17 +02:00
);
vec3 wValues = vec3(
2020-11-25 14:30:53 +01:00
getW(wF, wR, wC, ${T}, d2),
getW(wF, wR, wC, ${T} + 1, d2),
getW(wF, wR, wC, ${T} + 2, d2)
2020-10-11 18:41:17 +02:00
);
dotProd += dot(xValues, wValues);
}
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class BI{constructor(t,e=!1,r=null,o=!1){this.variableNames=["x","W"],this.outputShape=t.outShape;let s=t.inHeight,c=t.inWidth,l=t.padInfo.top,p=t.padInfo.left,f=t.strideHeight,m=t.strideWidth,y=t.dilationHeight,b=t.dilationWidth,v=t.filterHeight,T=t.filterWidth,N=t.outChannels/t.inChannels,S="",D="";r&&(o?S=`float activation(float a) {
2020-10-11 18:41:17 +02:00
float b = getPreluActivationWeightsAtOutCoords();
2020-11-25 14:30:53 +01:00
${r}
}`:S=`
2020-10-11 18:41:17 +02:00
float activation(float x) {
2020-11-25 14:30:53 +01:00
${r}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`,D="result = activation(result);");let I=e?"result += getBiasAtOutCoords();":"";e&&this.variableNames.push("bias"),o&&this.variableNames.push("preluActivationWeights"),this.userCode=`
${S}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const ivec2 strides = ivec2(${f}, ${m});
const ivec2 pads = ivec2(${l}, ${p});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int batch = coords.x;
ivec2 xRCCorner = coords.yz * strides - pads;
int d2 = coords.w;
2020-11-25 14:30:53 +01:00
int d1 = d2 / ${N};
int q = d2 - d1 * ${N};
2020-10-11 18:41:17 +02:00
int xRCorner = xRCCorner.x;
int xCCorner = xRCCorner.y;
// Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
// TO DO(dsmilkov): Flatten the two for loops and vec4 the operations.
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${v}; wR++) {
int xR = xRCorner + wR * ${y};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${s}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${T}; wC++) {
int xC = xCCorner + wC * ${b};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${c}) {
2020-10-11 18:41:17 +02:00
continue;
}
float xVal = getX(batch, xR, xC, d1);
float wVal = getW(wR, wC, d1, q);
dotProd += xVal * wVal;
}
}
float result = dotProd;
2020-11-25 14:30:53 +01:00
${I}
${D}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class zI{constructor(t,e=!1,r=null,o=!1){this.variableNames=["x","W"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t.outShape;let s=t.inHeight,c=t.inWidth,l=t.padInfo.top,p=t.padInfo.left,f=t.strideHeight,m=t.strideWidth,y=t.dilationHeight,b=t.dilationWidth,v=t.filterHeight,T=t.filterWidth,N=T,S="int xR; int xC; int xCOffset;";for(let E=0;E<v;E++)for(let L=0;L<T;L++)S+=`
vec4 xTexelR${E}C${L*2} = vec4(0.);
vec4 wR${E}C${L} = vec4(0.);
vec4 xR${E}C${L} = vec4(0.);`;for(let E=0;E<v;E++)for(let L=0;L<N;L++){let B=L*2;if(S+=`
xR = xRCorner + ${E*y};
xC = xCCorner + ${B*b};
`,m===1){if(B<T&&(p%2===1?S+=`
2020-10-11 18:41:17 +02:00
xCOffset = xC + 1;
2020-11-25 14:30:53 +01:00
if(xR >= 0 && xR < ${s} && xCOffset >= 0 && xCOffset < ${c}) {
xTexelR${E}C${B} = getX(batch, xR, xCOffset, d1);
2020-10-11 18:41:17 +02:00
// Need to manually clear unused channels in case
// we're reading from recycled texture.
2020-11-25 14:30:53 +01:00
if(xCOffset + 1 >= ${c}) {
xTexelR${E}C${B}.zw = vec2(0.);
2020-10-11 18:41:17 +02:00
}
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
xCOffset = xC + 1 - 2;
2020-11-25 14:30:53 +01:00
if(xR >= 0 && xR < ${s} && xCOffset >= 0 && xCOffset < ${c}) {
2020-10-11 18:41:17 +02:00
vec4 previous = getX(batch, xR, xCOffset, d1);
// Need to manually clear unused channels in case
// we're reading from recycled texture.
2020-11-25 14:30:53 +01:00
if(xCOffset + 1 >= ${c}) {
2020-10-11 18:41:17 +02:00
previous.zw = vec2(0.);
}
2020-11-25 14:30:53 +01:00
xR${E}C${B} = vec4(previous.zw, xTexelR${E}C${B}.xy);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xR${E}C${B} = vec4(0, 0, xTexelR${E}C${B}.xy);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`:S+=`
if(xR >= 0 && xR < ${s} && xC >= 0 && xC < ${c}) {
xTexelR${E}C${B} = getX(batch, xR, xC, d1);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
xR${E}C${B} = xTexelR${E}C${B};
`,B+1<T)){let q=p%2===0?k(b):b;b%2===0&&p%2===1||b%2!==0&&p%2!==1?(S+=`
xCOffset = xC + ${p%2} + ${q};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if(xR >= 0 && xR < ${s} &&
xCOffset >= 0 && xCOffset < ${c}) {
xTexelR${E}C${B+2} = getX(batch, xR, xCOffset, d1);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`,b>1&&(S+=`
2020-10-11 18:41:17 +02:00
xCOffset -= 2;
2020-11-25 14:30:53 +01:00
if(xR >= 0 && xR < ${s} &&
xCOffset >= 0 && xCOffset < ${c}) {
xTexelR${E}C${B} = getX(batch, xR, xCOffset, d1);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`),S+=`
xR${E}C${B+1} = vec4(
xTexelR${E}C${B}.zw, xTexelR${E}C${B+2}.xy);
`):S+=`
xCOffset = xC + ${q};
if(xR >= 0 && xR < ${s} &&
xCOffset >= 0 && xCOffset < ${c}) {
xTexelR${E}C${B+2} = getX(batch, xR, xCOffset, d1);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
xR${E}C${B+1} = xTexelR${E}C${B+2};
`}}else B<T&&(S+=`
if(xR >= 0 && xR < ${s}) {
`,p%2===1?(S+=`
xCOffset = xC + 1 - ${m};
if(xCOffset >= 0 && xCOffset < ${c}) {
xTexelR${E}C${B} = getX(batch, xR, xCOffset, d1);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
if(xC + 1 >= 0 && xC + 1 < ${c}) {
xTexelR${E}C${B+2} = getX(batch, xR, xC + 1, d1);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B+2} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
xR${E}C${B} = vec4(
xTexelR${E}C${B}.zw, xTexelR${E}C${B+2}.zw);
`,B+1<T&&(S+=`
2020-10-11 18:41:17 +02:00
vec4 final = vec4(0.);
2020-11-25 14:30:53 +01:00
xCOffset = xC + 1 + ${m};
if(xCOffset >= 0 && xCOffset < ${c}) {
2020-10-11 18:41:17 +02:00
final = getX(batch, xR, xCOffset, d1);
}
2020-11-25 14:30:53 +01:00
xR${E}C${B+1} = vec4(xTexelR${E}C${B+2}.xy, final.xy);
`)):(S+=`
if(xC >= 0 && xC < ${c}) {
xTexelR${E}C${B} = getX(batch, xR, xC, d1);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
xCOffset = xC + ${m};
if(xCOffset >= 0 && xCOffset < ${c}) {
xTexelR${E}C${B+2} = getX(batch, xR, xCOffset, d1);
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
xTexelR${E}C${B+2} = vec4(0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
xR${E}C${B} = vec4(
xTexelR${E}C${B}.xy, xTexelR${E}C${B+2}.xy);
`,B+1<T&&(S+=`
xR${E}C${B+1} = vec4(
xTexelR${E}C${B}.zw, xTexelR${E}C${B+2}.zw);
`)),S+="}");B<T&&(S+=`
vec4 wTexelR${E}C${B} = getW(${E}, ${B}, d1, q);
wR${E}C${B} = vec4(wTexelR${E}C${B}.xz, wTexelR${E}C${B}.xz);
`,B+1<T&&(S+=`
vec4 wTexelR${E}C${B+1} = getW(${E}, ${B+1}, d1, q);
wR${E}C${B+1} =
vec4(wTexelR${E}C${B+1}.xz, wTexelR${E}C${B+1}.xz);`))}for(let E=0;E<v;E++)for(let L=0;L<T;L++)S+=`dotProd += xR${E}C${L} * wR${E}C${L};`;let D="",I="";r&&(o?D=`vec4 activation(vec4 a) {
2020-10-11 18:41:17 +02:00
vec4 b = getPreluActivationWeightsAtOutCoords();
2020-11-25 14:30:53 +01:00
${r}
}`:D=`vec4 activation(vec4 x) {
${r}
}`,I="result = activation(result);");let P=e?"result += getBiasAtOutCoords();":"";e&&this.variableNames.push("bias"),o&&this.variableNames.push("preluActivationWeights"),this.userCode=`
${D}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const ivec2 strides = ivec2(${f}, ${m});
const ivec2 pads = ivec2(${l}, ${p});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int batch = coords.x;
ivec2 xRCCorner = coords.yz * strides - pads;
int d2 = coords.w;
int d1 = d2;
int q = 0;
int xRCorner = xRCCorner.x;
int xCCorner = xRCCorner.y;
vec4 dotProd = vec4(0.);
2020-11-25 14:30:53 +01:00
${S}
2020-10-11 18:41:17 +02:00
vec4 result = dotProd;
2020-11-25 14:30:53 +01:00
${P}
${I}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class b7{constructor(t,e,r,o,s){this.variableNames=["Image","Boxes","BoxInd"],this.outputShape=[];let[c,l,p,f]=t,[m]=e,[y,b]=r;this.outputShape=[m,y,b,f];let v=o==="bilinear"?1:0,[T,N]=[`${l-1}.0`,`${p-1}.0`],[S,D,I]=y>1?[`${(l-1)/(y-1)}`,"(y2-y1) * height_ratio",`y1*${T} + float(y)*(height_scale)`]:["0.0","0.0",`0.5 * (y1+y2) * ${T}`],[P,E,L]=b>1?[`${(p-1)/(b-1)}`,"(x2-x1) * width_ratio",`x1*${N} + float(x)*(width_scale)`]:["0.0","0.0",`0.5 * (x1+x2) * ${N}`];this.userCode=`
const float height_ratio = float(${S});
const float width_ratio = float(${P});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int y = coords[1];
int x = coords[2];
int d = coords[3];
// get box vals
float y1 = getBoxes(b,0);
float x1 = getBoxes(b,1);
float y2 = getBoxes(b,2);
float x2 = getBoxes(b,3);
// get image in batch index
int bInd = round(getBoxInd(b));
2020-11-25 14:30:53 +01:00
if(bInd < 0 || bInd >= ${c}) {
2020-10-11 18:41:17 +02:00
return;
}
2020-11-25 14:30:53 +01:00
float height_scale = ${D};
2020-10-29 05:16:50 +01:00
float width_scale = ${E};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
float in_y = ${I};
if( in_y < 0.0 || in_y > ${T} ) {
setOutput(float(${s}));
2020-10-11 18:41:17 +02:00
return;
}
2020-11-25 14:30:53 +01:00
float in_x = ${L};
if( in_x < 0.0 || in_x > ${N} ) {
setOutput(float(${s}));
2020-10-11 18:41:17 +02:00
return;
}
vec2 sourceFracIndexCR = vec2(in_x,in_y);
2020-11-25 14:30:53 +01:00
if(${v} == 1) {
2020-10-11 18:41:17 +02:00
// Compute the four integer indices.
ivec2 sourceFloorCR = ivec2(sourceFracIndexCR);
ivec2 sourceCeilCR = ivec2(ceil(sourceFracIndexCR));
float topLeft = getImage(b, sourceFloorCR.y, sourceFloorCR.x, d);
float bottomLeft = getImage(b, sourceCeilCR.y, sourceFloorCR.x, d);
float topRight = getImage(b, sourceFloorCR.y, sourceCeilCR.x, d);
float bottomRight = getImage(b, sourceCeilCR.y, sourceCeilCR.x, d);
vec2 fracCR = sourceFracIndexCR - vec2(sourceFloorCR);
float top = topLeft + (topRight - topLeft) * fracCR.x;
float bottom = bottomLeft + (bottomRight - bottomLeft) * fracCR.x;
float newValue = top + (bottom - top) * fracCR.y;
setOutput(newValue);
} else {
// Compute the coordinators of nearest neighbor point.
ivec2 sourceNearestCR = ivec2(floor(
sourceFracIndexCR + vec2(0.5,0.5)));
float newValue = getImage(b, sourceNearestCR.y, sourceNearestCR.x, d);
setOutput(newValue);
}
}
2020-11-25 14:30:53 +01:00
`}}class WI{constructor(t,e,r){this.variableNames=["x"],this.outputShape=t;let o=t.length,s=e?"0.0":`getX(${VI(o,"coords")})`,c=t[t.length-1],l="",p="";e?(l=r?`end != ${c-1}`:"end != 0",p=r?"end + 1":"end - 1"):(l=r?`end + pow2 < ${c}`:"end >= pow2",p=r?"end + pow2":"end - pow2"),this.userCode=`
2020-10-11 18:41:17 +02:00
uniform float index;
void main() {
2020-11-25 14:30:53 +01:00
${Oe(o)} coords = getOutputCoords();
int end = ${GI(o,"coords")};
float val = ${s};
2020-10-11 18:41:17 +02:00
int pow2 = int(pow(2.0, index));
2020-11-25 14:30:53 +01:00
if (${l}) {
int idx = ${p};
${GI(o,"coords")} = idx;
val += getX(${VI(o,"coords")});
2020-10-11 18:41:17 +02:00
}
setOutput(val);
}
2020-11-25 14:30:53 +01:00
`}getCustomSetupFunc(t){return(e,r)=>{this.index==null&&(this.index=e.getUniformLocation(r,"index")),e.gl.uniform1f(this.index,t)}}}function VI(n,t){if(n===1)return`${t}`;if(n===2)return`${t}.x, ${t}.y`;if(n===3)return`${t}.x, ${t}.y, ${t}.z`;if(n===4)return`${t}.x, ${t}.y, ${t}.z, ${t}.w`;throw Error(`Cumulative sum for rank ${n} is not yet supported`)}function GI(n,t){if(n===1)return`${t}`;if(n===2)return`${t}.y`;if(n===3)return`${t}.z`;if(n===4)return`${t}.w`;throw Error(`Cumulative sum for rank ${n} is not yet supported`)}class x7{constructor(t){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.outPackingScheme=ch.DENSE;let e=uh(t),r=Zn();this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
ivec3 outCoordsFromFlatIndex(int index) {
2020-11-25 14:30:53 +01:00
${_a(["r","c","d"],t)}
2020-10-11 18:41:17 +02:00
return ivec3(r, c, d);
}
void main() {
ivec2 resTexRC = ivec2(resultUV.yx *
2020-11-25 14:30:53 +01:00
vec2(${e[0]}, ${e[1]}));
int index = 4 * (resTexRC.x * ${e[1]} + resTexRC.y);
2020-10-11 18:41:17 +02:00
vec4 result = vec4(0.);
for (int i=0; i<4; i++) {
int flatIndex = index + i;
ivec3 rc = outCoordsFromFlatIndex(flatIndex);
result[i] = getA(rc.x, rc.y, rc.z);
}
2020-11-25 14:30:53 +01:00
${r.output} = result;
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class w7{constructor(t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outPackingScheme=ch.DENSE;let e=uh(t),r=Zn();this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
ivec3 outCoordsFromFlatIndex(int index) {
2020-11-25 14:30:53 +01:00
${_a(["r","c","d"],t)}
2020-10-11 18:41:17 +02:00
return ivec3(r, c, d);
}
void main() {
ivec2 resTexRC = ivec2(resultUV.yx *
2020-11-25 14:30:53 +01:00
vec2(${e[0]}, ${e[1]}));
int index = 4 * (resTexRC.x * ${e[1]} + resTexRC.y);
2020-10-11 18:41:17 +02:00
vec4 result = vec4(0.);
for (int i=0; i<4; i++) {
int flatIndex = index + i;
ivec3 rc = outCoordsFromFlatIndex(flatIndex);
result[i] = getChannel(getA(rc.x, rc.y, rc.z), vec2(rc.y, rc.z));
}
2020-11-25 14:30:53 +01:00
${r.output} = result;
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class v7{constructor(t,e,r){this.variableNames=["x"],this.outputShape=[],this.outputShape=t,this.blockSize=e,this.dataFormat=r,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int h = ${this.getHeightCoordString()};
int w = ${this.getWidthCoordString()};
int d = ${this.getDepthCoordString()};
2020-11-25 14:30:53 +01:00
int in_h = h / ${e};
int offset_h = imod(h, ${e});
int in_w = w / ${e};
int offset_w = imod(w, ${e});
int offset_d = (offset_h * ${e} + offset_w) *
2020-10-11 18:41:17 +02:00
${this.getOutputDepthSize()};
int in_d = d + offset_d;
float result = ${this.getInputSamplingString()};
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}getHeightCoordString(){return this.dataFormat==="NHWC"?"coords[1]":"coords[2]"}getWidthCoordString(){return this.dataFormat==="NHWC"?"coords[2]":"coords[3]"}getDepthCoordString(){return this.dataFormat==="NHWC"?"coords[3]":"coords[1]"}getOutputDepthSize(){return this.dataFormat==="NHWC"?this.outputShape[3]:this.outputShape[1]}getInputSamplingString(){return this.dataFormat==="NHWC"?"getX(b, in_h, in_w, in_d)":"getX(b, in_d, in_h, in_w)"}}class T7{constructor(t){this.variableNames=["X"],this.outputShape=[t,t],this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec2 coords = getOutputCoords();
float val = coords[0] == coords[1] ? getX(coords[0]) : 0.0;
setOutput(val);
}
2020-11-25 14:30:53 +01:00
`}}class k7{constructor(t){this.variableNames=["A"],this.outTexUsage=Br.DOWNLOAD;let e=Zn();this.outputShape=t,this.userCode=`
${DI}
2020-10-11 18:41:17 +02:00
void main() {
float x = getAAtOutCoords();
2020-11-25 14:30:53 +01:00
${e.output} = encode_float(x);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class N7{constructor(t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!1,this.outTexUsage=Br.DOWNLOAD;let e=Zn();this.outputShape=t,this.userCode=`
${DI}
2020-10-11 18:41:17 +02:00
void main() {
ivec3 coords = getOutputCoords();
float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z));
2020-11-25 14:30:53 +01:00
${e.output} = encode_float(x);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class _7{constructor(t,e,r=!1){this.variableNames=["A"];let o=Zn(),[s,c]=e;this.outputShape=t;let l="result";r&&(l="floor(result * 255. + 0.5)"),this.userCode=`
${P1(t)}
2020-10-11 18:41:17 +02:00
void main() {
ivec3 coords = getOutputCoords();
int flatIndex = getFlatIndex(coords);
int offset = imod(flatIndex, 4);
flatIndex = idiv(flatIndex, 4, 1.);
2020-11-25 14:30:53 +01:00
int r = flatIndex / ${c};
int c = imod(flatIndex, ${c});
vec2 uv = (vec2(c, r) + halfCR) / vec2(${c}.0, ${s}.0);
vec4 values = ${o.texture2D}(A, uv);
2020-10-11 18:41:17 +02:00
float result;
if(offset == 0) {
result = values[0];
} else if(offset == 1) {
result = values[1];
} else if(offset == 2) {
result = values[2];
} else {
result = values[3];
}
2020-11-25 14:30:53 +01:00
${o.output} = vec4(${l}, 0., 0., 0.);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class C7{constructor(t,e,r=!1){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0;let o=Zn(),[s,c]=e;this.outputShape=t;let l="",p="result";r&&(p="floor(result * 255. + 0.5)");for(let f=0;f<=1;f++)for(let m=0;m<=1;m++){let y=f*2+m;l+=`
2020-10-11 18:41:17 +02:00
localCoords = coords;
2020-11-25 14:30:53 +01:00
if(localCoords[2] + ${m} < ${t[2]}) {
localCoords[2] += ${m};
if(localCoords[1] + ${f} < ${t[1]}) {
localCoords[1] += ${f};
2020-10-11 18:41:17 +02:00
flatIndex = getFlatIndex(localCoords);
offset = imod(flatIndex, 4);
flatIndex = idiv(flatIndex, 4, 1.);
2020-11-25 14:30:53 +01:00
r = flatIndex / ${c};
c = imod(flatIndex, ${c});
uv = (vec2(c, r) + halfCR) / vec2(${c}.0, ${s}.0);
values = ${o.texture2D}(A, uv);
2020-10-11 18:41:17 +02:00
if(offset == 0) {
2020-11-25 14:30:53 +01:00
result[${y}] = values[0];
2020-10-11 18:41:17 +02:00
} else if(offset == 1) {
2020-11-25 14:30:53 +01:00
result[${y}] = values[1];
2020-10-11 18:41:17 +02:00
} else if(offset == 2) {
2020-11-25 14:30:53 +01:00
result[${y}] = values[2];
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
result[${y}] = values[3];
2020-10-11 18:41:17 +02:00
}
}
}
`}this.userCode=`
2020-11-25 14:30:53 +01:00
${P1(t)}
2020-10-11 18:41:17 +02:00
void main() {
ivec3 coords = getOutputCoords();
vec4 result = vec4(0.);
int flatIndex, r, c, offset;
ivec3 localCoords;
vec2 uv;
vec4 values;
2020-11-25 14:30:53 +01:00
${l}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
${o.output} = ${p};
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class S7{constructor(t,e){this.outputShape=[],this.variableNames=["x"],this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
uniform float value;
void main() {
// Input can be obtained from uniform value.
setOutput(value);
}
2020-11-25 14:30:53 +01:00
`}getCustomSetupFunc(t){return(e,r)=>{this.valueLoc==null&&(this.valueLoc=e.getUniformLocationNoThrow(r,"value")),e.gl.uniform1f(this.valueLoc,t)}}}class $7{constructor(t,e,r){this.variableNames=["A","indices"];let o=t.slice();o[r]=e,this.outputShape=o,this.rank=o.length;let s=Oe(this.rank),c=I7(t,r);this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${s} resRC = getOutputCoords();
setOutput(getA(${c}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}function I7(n,t){let e=n.length;if(e>4)throw Error(`Gather for rank ${e} is not yet supported`);if(e===1)return"int(getIndices(resRC))";let r=["resRC.x","resRC.y","resRC.z","resRC.w"],o=[];for(let s=0;s<n.length;s++)s===t?o.push(`int(getIndices(${r[s]}))`):o.push(`${r[s]}`);return o.join()}class E7{constructor(t,e,r){this.sliceDim=t,this.strides=e,this.variableNames=["x","indices"],this.outputShape=r;let o=Oe(e.length),s=Oe(r.length),c=this.sliceDim>1?"strides[j]":"strides";this.userCode=`
${o} strides = ${o}(${this.strides});
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${s} coords = getOutputCoords();
2020-10-11 18:41:17 +02:00
int flattenIndex = 0;
for (int j = 0; j < ${this.sliceDim}; j++) {
int index = round(getIndices(coords[0], j));
2020-11-25 14:30:53 +01:00
flattenIndex += index * ${c};
2020-10-11 18:41:17 +02:00
}
setOutput(getX(flattenIndex, coords[1]));
}
2020-11-25 14:30:53 +01:00
`}}function D7(n){let t=Zn(),e=`${t.version}
2020-10-11 18:41:17 +02:00
precision highp float;
${t.attribute} vec3 clipSpacePos;
${t.attribute} vec2 uv;
${t.varyingVs} vec2 resultUV;
void main() {
gl_Position = vec4(clipSpacePos, 1);
resultUV = uv;
2020-11-25 14:30:53 +01:00
}`;return uX(n,e)}function A7(n){let t=new Float32Array([-1,1,0,0,1,-1,-1,0,0,0,1,1,0,1,1,1,-1,0,1,0]);return gX(n,t)}function F7(n){let t=new Uint16Array([0,1,2,2,1,3]);return yX(n,t)}function hh(n,t,e,r,o,s){xX(t,e);let c=bX(n),l=n.TEXTURE_2D;return Rt(n,()=>n.bindTexture(l,c)),Rt(n,()=>n.texParameteri(l,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE)),Rt(n,()=>n.texParameteri(l,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE)),Rt(n,()=>n.texParameteri(l,n.TEXTURE_MIN_FILTER,n.NEAREST)),Rt(n,()=>n.texParameteri(l,n.TEXTURE_MAG_FILTER,n.NEAREST)),Rt(n,()=>n.texImage2D(l,0,r,t,e,0,o,s,null)),Rt(n,()=>n.bindTexture(n.TEXTURE_2D,null)),c}function UI(n){return n.internalFormatFloat}function R7(n,t,e,r){let[o,s]=lh(t,e);return hh(n,o,s,UI(r),r.textureFormatFloat,n.FLOAT)}function qI(n){return n.internalFormatHalfFloat}function P7(n,t,e,r){let[o,s]=lh(t,e);return hh(n,o,s,qI(r),r.textureFormatFloat,r.textureTypeHalfFloat)}function HI(n){return n.downloadTextureFormat}function O7(n,t,e,r){let[o,s]=lh(t,e);return hh(n,o,s,HI(r),n.RGBA,n.UNSIGNED_BYTE)}function jI(n){return n.internalFormatPackedFloat}function L7(n,t,e,r){let[o,s]=fl(t,e);return hh(n,o,s,jI(r),n.RGBA,n.FLOAT)}function KI(n){return n.internalFormatPackedHalfFloat}function M7(n,t,e,r){let[o,s]=fl(t,e);return hh(n,o,s,KI(r),n.RGBA,r.textureTypeHalfFloat)}function B7(n,t,e){let r=0,o=3*4,s=3*4+2*4;Rt(n,()=>n.bindBuffer(n.ARRAY_BUFFER,e));let c=CI(n,t,"clipSpacePos",e,3,s,r);return c&&CI(n,t,"uv",e,2,s,o)}function z7(n,t,e,r,o,s){Rt(n,()=>n.bindTexture(n.TEXTURE_2D,t));let c,l,p;o instanceof Uint8Array?(c=new Uint8Array(e*r*4),l=n.UNSIGNED_BYTE,p=n.RGBA):(c=new Float32Array(e*r*4),l=n.FLOAT,p=s.internalFormatPackedFloat),c.set(o),Rt(n,()=>n.texImage2D(n.TEXTURE_2D,0,p,e,r,0,n.RGBA,l,c)),Rt(n,()=>n.bindTexture(n.TEXTURE_2D,null))}function W7(n,t,e){Rt(n,()=>n.bindTexture(n.TEXTURE_2D,t)),e.data instanceof Uint8Array?Rt(n,()=>n.texImage2D(n.TEXTURE_2D,0,n.RGBA,e.width,e.height,0,n.RGBA,n.UNSIGNED_BYTE,e.data)):Rt(n,()=>n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,e)),Rt(n,()=>n.bindTexture(n.TEXTURE_2D,null))}function V7(n,t,e,r){let o=n.createBuffer();Rt(n,()=>n.bindBuffer(n.PIXEL_PACK_BUFFER,o));let s=4,c=4,l=s*c*t*e;return Rt(n,()=>n.bufferData(n.PIXEL_PACK_BUFFER,l,n.STREAM_READ)),Rt(n,()=>n.readPixels(0,0,e,t,n.RGBA,n.FLOAT,0)),Rt(n,()=>n.bindBuffer(n.PIXEL_PACK_BUFFER,null)),o}function G7(n,t,e){let r=n,o=new Float32Array(e);return r.bindBuffer(r.PIXEL_PACK_BUFFER,t),r.getBufferSubData(r.PIXEL_PACK_BUFFER,0,o),r.bindBuffer(r.PIXEL_PACK_BUFFER,null),o}function U7(n,t,e,r){let[o,s]=lh(t,e),c=4,l=new Uint8Array(rX(t*e,c));return Rt(n,()=>n.readPixels(0,0,o,s,r.downloadTextureFormat,n.UNSIGNED_BYTE,l)),new Float32Array(l.buffer)}function q7(n,t,e,r,o,s,c,l){let p=n,f=new Float32Array(oX(s,c));return p.bindBuffer(p.PIXEL_PACK_BUFFER,t),p.getBufferSubData(p.PIXEL_PACK_BUFFER,0,f),p.bindBuffer(p.PIXEL_PACK_BUFFER,null),f}function H7(n,t,e){let r=new Float32Array(t*e*4);return Rt(n,()=>n.readPixels(0,0,e,t,n.RGBA,n.FLOAT,r)),r}class j7{constructor(t){this.outputTexture=null,this.program=null,this.disposed=!1,this.vertexAttrsAreBound=!1,this.itemsToPoll=[];let e=ct().getNumber("WEBGL_VERSION");t!=null?(this.gl=t,tX(e,t)):this.gl=Xo(e);let r="WEBGL_color_buffer_float",o="EXT_color_buffer_half_float";if(ct().getNumber("WEBGL_VERSION")===1){let s="OES_texture_float",c="OES_texture_half_float";if(this.textureFloatExtension=Xm(this.gl,s),ro(this.gl,c))this.textureHalfFloatExtension=Xm(this.gl,c);else if(ct().get("WEBGL_FORCE_F16_TEXTURES"))throw new Error("GL context does not support half float textures, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.");if(this.colorBufferFloatExtension=this.gl.getExtension(r),ro(this.gl,o))this.colorBufferHalfFloatExtension=Xm(this.gl,o);else if(ct().get("WEBGL_FORCE_F16_TEXTURES"))throw new Error("GL context does not support color renderable half floats, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.")}else if(r="EXT_color_buffer_float",ro(this.gl,r))this.colorBufferFloatExtension=this.gl.getExtension(r);else if(ro(
blockIndex = rc.y + ${B};
pos = rc.x + ${L};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if(blockIndex < ${t[1]} && pos < ${t[0]}) {
offsetY = int(blockIndex / (${f})) * ${l} - ${T};
d0 = offsetY + ${y} * (pos / ${N});
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if(d0 < ${e[I]} && d0 >= 0) {
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
offsetX = int(mod(float(blockIndex), ${f}.) * ${c}. - ${v}.);
d1 = offsetX + ${m} * (int(mod(float(pos), ${N}.) / ${s}.));
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if(d1 < ${e[P]} && d1 >= 0) {
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
ch = int(mod(float(pos), ${s}.));
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (${D}) {
2020-10-11 18:41:17 +02:00
innerDims = vec2(d1, ch);
2020-11-25 14:30:53 +01:00
result[${L*2+B}] = getChannel(
2020-10-11 18:41:17 +02:00
getA(d0, int(innerDims.x),
int(innerDims.y)), innerDims);
} else {
innerDims = vec2(d0, d1);
2020-11-25 14:30:53 +01:00
result[${L*2+B}] = getChannel(
2020-10-11 18:41:17 +02:00
getA(ch, int(innerDims.x),
int(innerDims.y)), innerDims);
}
}
}
}
`;this.userCode=`
void main() {
ivec2 rc = getOutputCoords();
vec4 result = vec4(0);
int blockIndex, pos, offsetY, d0, offsetX, d1, ch;
vec2 innerDims;
2020-10-29 05:16:50 +01:00
${E}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
${S.output} = result;
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class Q7{constructor(t,e,r,o,s){this.variableNames=["x"],this.outputShape=[];let c=e,l=t[3]-1;this.outputShape=t;let p,f=`float(${r}) + float(${o}) * sum`;s===.5?p=`inversesqrt(${f})`:s===1?p=`1.0/(${f})`:p=`exp(log(${f}) * float(-${s}));`,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int r = coords[1];
int c = coords[2];
int d = coords[3];
float x = getX(b, r, c, d);
float sum = 0.0;
2020-11-25 14:30:53 +01:00
for (int j = -${c}; j <= ${c}; j++) {
2020-10-11 18:41:17 +02:00
int idx = d + j;
2020-11-25 14:30:53 +01:00
if (idx >= 0 && idx <= ${l}) {
2020-10-11 18:41:17 +02:00
float z = getX(b, r, c, idx);
sum += z * z;
}
}
2020-11-25 14:30:53 +01:00
float val = x * ${p};
2020-10-11 18:41:17 +02:00
setOutput(val);
}
2020-11-25 14:30:53 +01:00
`}}class tJ{constructor(t,e,r,o,s){this.variableNames=["inputImage","outputImage","dy"],this.outputShape=[],this.outputShape=t,this.depth=t[3],this.depthRadius=e,this.bias=r,this.alpha=o,this.beta=s,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int r = coords[1];
int c = coords[2];
float result = 0.0;
for (int d = 0; d < ${this.depth}; ++d) {
2020-11-25 14:30:53 +01:00
int depthBegin = int(max(0.0, float(d - ${e})));
2020-10-11 18:41:17 +02:00
int depthEnd = int(min(float(${this.depth}),
2020-11-25 14:30:53 +01:00
float(d + ${e} + 1)));
2020-10-11 18:41:17 +02:00
const int MIN_DEPTH_BEGIN = 0;
const int MAX_DEPTH_END = ${this.depth};
float norm = 0.0;
for (int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k) {
if (k < depthBegin){
continue;
}
else if (k >= depthBegin && k < depthEnd) {
norm += getInputImage(b, r, c, k) * getInputImage(b, r, c, k);
}
else {
break;
}
}
2020-11-25 14:30:53 +01:00
norm = float(${o}) * norm + float(${r});
2020-10-11 18:41:17 +02:00
for(int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k){
if (k < depthBegin){
continue;
}
else if (k >= depthBegin && k < depthEnd){
2020-11-25 14:30:53 +01:00
float dyi = -2.0 * float(${o})
* float(${s})
2020-10-11 18:41:17 +02:00
* getInputImage(b ,r ,c, k) * getOutputImage(b, r, c, d)
/ norm;
if (k == d) {
2020-11-25 14:30:53 +01:00
dyi += pow(norm, -1.0 * ${s});
2020-10-11 18:41:17 +02:00
}
if (k == coords[3]) {
dyi *= getDy(b, r, c, d);
result += dyi;
}
}
else {
break;
}
}
}
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class eJ{constructor(t,e,r,o,s){this.variableNames=["x"],this.outputShape=[],this.packedInputs=!0,this.packedOutput=!0;let c=e,l=t[3]-1;this.outputShape=t;let p,f=`float(${r}) + float(${o}) * sum`;s===.5?p=`inversesqrt(${f})`:s===1?p=`1.0/(${f})`:p=`exp(log(${f}) * float(-${s}));`,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords.x;
int r = coords.y;
int c = coords.z;
int d = coords.w;
bool hasNextCol = d < ${this.outputShape[3]};
bool hasNextRow = c < ${this.outputShape[2]};
vec4 sum = vec4(0.);
vec4 xFragAtOutputCoords = getX(b, r, c, d);
vec4 xAtOutputCoords = vec4(
getChannel(xFragAtOutputCoords, vec2(c, d)),
hasNextCol ?
getChannel(xFragAtOutputCoords, vec2(c, d + 1)) : 0.0,
hasNextRow ?
getChannel(xFragAtOutputCoords , vec2(c + 1, d)) : 0.0,
(hasNextRow && hasNextCol) ?
getChannel(xFragAtOutputCoords, vec2(c + 1, d + 1)) : 0.0
);
2020-11-25 14:30:53 +01:00
int firstChannel = d - ${c};
2020-10-11 18:41:17 +02:00
vec2 cache = vec2(0.);
if(firstChannel >= 0){
vec4 firstChannelFrag = getX(b, r, c, firstChannel);
cache.x = getChannel(firstChannelFrag, vec2(c, firstChannel));
if(hasNextRow){
cache.y = getChannel(firstChannelFrag, vec2(c + 1, firstChannel));
}
}
ivec2 depth = ivec2(d, d + 1);
2020-11-25 14:30:53 +01:00
for (int j = - ${c}; j <= ${c}; j++) {
2020-10-11 18:41:17 +02:00
ivec2 idx = depth + j;
bvec2 aboveLowerBound = greaterThanEqual(idx, ivec2(0));
2020-11-25 14:30:53 +01:00
bvec2 belowUpperBound = lessThanEqual(idx, ivec2(${l}));
2020-10-11 18:41:17 +02:00
bool depthInRange = aboveLowerBound.x && belowUpperBound.x;
bool depthPlusOneInRange = aboveLowerBound.y && belowUpperBound.y;
if(depthInRange || depthPlusOneInRange){
vec4 z = vec4(0.);
vec4 xFragAtCurrentDepth;
z.xz = cache.xy;
if(depthPlusOneInRange && hasNextCol){
xFragAtCurrentDepth = idx.y != d ?
getX(b, r, c, idx.y) : xFragAtOutputCoords;
z.y = getChannel(xFragAtCurrentDepth, vec2(c, idx.y));
if(hasNextRow){
z.w = getChannel(xFragAtCurrentDepth, vec2(c + 1, idx.y));
}
}
cache.xy = z.yw;
sum += z * z;
}
}
2020-11-25 14:30:53 +01:00
vec4 result = xAtOutputCoords * ${p};
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class nJ{constructor(t){this.variableNames=["dy","maxPos"],this.outputShape=t.inShape;let e=t.strideHeight,r=t.strideWidth,o=t.dilationHeight,s=t.effectiveFilterHeight,c=t.effectiveFilterWidth,l=s-1-t.padInfo.top,p=c-1-t.padInfo.left,f=s*c-1;this.userCode=`
const ivec2 pads = ivec2(${l}, ${p});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
ivec2 dyRCCorner = coords.yz - pads;
int dyRCorner = dyRCCorner.x;
int dyCCorner = dyRCCorner.y;
// Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${s};
wR += ${o}) {
float dyR = float(dyRCorner + wR) / ${e}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 || fract(dyR) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${c}; wC++) {
float dyC = float(dyCCorner + wC) / ${r}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
float dyValue = getDy(b, idyR, idyC, d);
2020-11-25 14:30:53 +01:00
int maxPosValue = ${f} - int(getMaxPos(b, idyR, idyC, d));
2020-10-11 18:41:17 +02:00
// Get the current value, check it against the value from the
// position matrix.
2020-11-25 14:30:53 +01:00
int curPosValue = wR * ${c} + wC;
2020-10-11 18:41:17 +02:00
float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);
dotProd += dyValue * mask;
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class rJ{constructor(t){this.variableNames=["dy","maxPos"],this.outputShape=t.inShape;let e=t.strideDepth,r=t.strideHeight,o=t.strideWidth,s=t.dilationDepth,c=t.dilationHeight,l=t.dilationWidth,p=t.effectiveFilterDepth,f=t.effectiveFilterHeight,m=t.effectiveFilterWidth,y=p-1-t.padInfo.front,b=f-1-t.padInfo.top,v=m-1-t.padInfo.left,T=p*f*m-1;this.userCode=`
const ivec3 pads = ivec3(${y}, ${b}, ${v});
2020-10-11 18:41:17 +02:00
void main() {
ivec5 coords = getOutputCoords();
int batch = coords.x;
int ch = coords.u;
ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;
int dyDCorner = dyCorner.x;
int dyRCorner = dyCorner.y;
int dyCCorner = dyCorner.z;
// Convolve dy(?, ?, ?, ch) with pos mask(:, :, :, d) to get
// dx(xD, xR, xC, ch).
// ? = to be determined. : = across all values in that axis.
float dotProd = 0.0;
2020-11-25 14:30:53 +01:00
for (int wD = 0; wD < ${p};
wD += ${s}) {
float dyD = float(dyDCorner + wD) / ${e}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyD < 0.0 || dyD >= ${t.outDepth}.0 || fract(dyD) > 0.0) {
2020-10-11 18:41:17 +02:00
continue;
}
int idyD = int(dyD);
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${f};
wR += ${c}) {
float dyR = float(dyRCorner + wR) / ${r}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyR < 0.0 || dyR >= ${t.outHeight}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyR) > 0.0) {
continue;
}
int idyR = int(dyR);
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${m};
wC += ${l}) {
float dyC = float(dyCCorner + wC) / ${o}.0;
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if (dyC < 0.0 || dyC >= ${t.outWidth}.0 ||
2020-10-11 18:41:17 +02:00
fract(dyC) > 0.0) {
continue;
}
int idyC = int(dyC);
float dyValue = getDy(batch, idyD, idyR, idyC, ch);
2020-11-25 14:30:53 +01:00
int maxPosValue = ${T} -
2020-10-11 18:41:17 +02:00
int(getMaxPos(batch, idyD, idyR, idyC, ch));
// Get the current value, check it against the value from the
// position matrix.
int curPosValue =
2020-11-25 14:30:53 +01:00
wD * ${f} * ${m} +
wR * ${m} + wC;
2020-10-11 18:41:17 +02:00
float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);
dotProd += dyValue * mask;
}
}
}
setOutput(dotProd);
}
2020-11-25 14:30:53 +01:00
`}}class O1{constructor(t,e,r,o=!1,s=!1,c=!1,l=null,p=!1){this.variableNames=["matrixA","matrixB"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=r;let f=o?t[1]:t[2],m=Math.ceil(f/2),y=o?"i * 2, rc.y":"rc.y, i * 2",b=s?"rc.z, i * 2":"i * 2, rc.z",v=o?["a.xxyy","a.zzww"]:["a.xxzz","a.yyww"],T=s?["b.xzxz","b.ywyw"]:["b.xyxy","b.zwzw"],N="",S="";l&&(p?N=`vec4 activation(vec4 a) {
2020-10-11 18:41:17 +02:00
vec4 b = getPreluActivationWeightsAtOutCoords();
2020-11-25 14:30:53 +01:00
${l}
}`:N=`vec4 activation(vec4 x) {
${l}
}`,S="result = activation(result);");let D=c?"result += getBiasAtOutCoords();":"";c&&this.variableNames.push("bias"),p&&this.variableNames.push("preluActivationWeights");let I="rc.x",P="rc.x";t[0]<e[0]?I=`int(min(float(rc.x), ${t[0]-1}.))`:e[0]<t[0]&&(P=`int(min(float(rc.x), ${e[0]-1}.))`),this.userCode=`
${N}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const float sharedDimension = ${m}.0;
2020-10-11 18:41:17 +02:00
vec4 dot2x2ARowBCol(ivec3 rc) {
vec4 result = vec4(0);
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${m}; i++) {
int batchA = ${I};
int batchB = ${P};
vec4 a = getMatrixA(batchA, ${y});
vec4 b = getMatrixB(batchB, ${b});
2020-10-11 18:41:17 +02:00
// These swizzled products need to be separately added.
// See: https://github.com/tensorflow/tfjs/issues/1735
2020-11-25 14:30:53 +01:00
result += (${v[0]} * ${T[0]});
result += (${v[1]} * ${T[1]});
2020-10-11 18:41:17 +02:00
}
return result;
}
void main() {
ivec3 rc = getOutputCoords();
vec4 result = dot2x2ARowBCol(rc);
2020-11-25 14:30:53 +01:00
${D}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
${S}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class oJ{constructor(t,e,r){this.variableNames=["probs"],this.outputShape=[t,r],this.userCode=`
2020-10-11 18:41:17 +02:00
uniform float seed;
void main() {
ivec2 coords = getOutputCoords();
int batch = coords[0];
float r = random(seed);
float cdf = 0.0;
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${e-1}; i++) {
2020-10-11 18:41:17 +02:00
cdf += getProbs(batch, i);
if (r < cdf) {
setOutput(float(i));
return;
}
}
// If no other event happened, last event happened.
2020-11-25 14:30:53 +01:00
setOutput(float(${e-1}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}getCustomSetupFunc(t){return(e,r)=>{this.seedLoc==null&&(this.seedLoc=e.getUniformLocation(r,"seed")),e.gl.uniform1f(this.seedLoc,t)}}}class sJ{constructor(t,e,r,o){this.variableNames=["indices"],this.outputShape=[t,e],this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec2 coords = getOutputCoords();
int index = round(getIndices(coords.x));
2020-11-25 14:30:53 +01:00
setOutput(mix(float(${o}), float(${r}),
2020-10-11 18:41:17 +02:00
float(index == coords.y)));
}
2020-11-25 14:30:53 +01:00
`}}class iJ{constructor(t){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.outputShape=t;let e=t.length;if(e===0)this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
setOutput(vec4(getA(), 0., 0., 0.));
}
2020-11-25 14:30:53 +01:00
`;else{let r=Jn("rc",e),o=Oe(e),s=cJ(e,t,r),c=lJ(e,t[t.length-1],t[t.length-2],r),l=uJ(t,r);this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${o} rc = getOutputCoords();
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
if(${s}) {
2020-10-11 18:41:17 +02:00
setOutput(vec4(0));
} else {
2020-11-25 14:30:53 +01:00
${c}
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
setOutput(vec4(${l}));
2020-10-11 18:41:17 +02:00
}
}
2020-11-25 14:30:53 +01:00
`}}}function aJ(n,t){let e=[];for(let r=0;r<=1;r++)for(let o=0;o<=1;o++){let s=`${r===0?"r":"rp1"}, ${o===0?"c":"cp1"}`;for(let c=2;c<n;c++)s=`${t[t.length-1-c]},`+s;e.push(s)}return e}function cJ(n,t,e){if(n===1)return`rc > ${t[0]}`;let r="";for(let o=n-2;o<n;o++)r+=`${e[o]} >= ${t[o]}`,o<n-1&&(r+="||");return r}function lJ(n,t,e,r){if(n===1)return"";let o=r.slice(-2);return`
int r = ${o[0]};
int c = ${o[1]};
2020-10-11 18:41:17 +02:00
int rp1 = r + 1;
int cp1 = c + 1;
bool cEdge = cp1 >= ${t};
2020-11-25 14:30:53 +01:00
bool rEdge = rp1 >= ${e};
`}function uJ(n,t){let e=n.length,r=aJ(e,t);return e===1?`getA(rc),
rc + 1 >= ${n[0]} ? 0. : getA(rc + 1),
0, 0`:`getA(${r[0]}),
cEdge ? 0. : getA(${r[1]}),
rEdge ? 0. : getA(${r[2]}),
rEdge || cEdge ? 0. : getA(${r[3]})`}class pJ{constructor(t,e,r){this.variableNames=["x"],this.outputShape=e.map((f,m)=>f[0]+t[m]+f[1]);let o=t.length,s=Oe(o),c=e.map(f=>f[0]).join(","),l=e.map((f,m)=>f[0]+t[m]).join(","),p=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,o);if(o===1){this.userCode=`
int start = ${c};
int end = ${l};
2020-10-11 18:41:17 +02:00
void main() {
int outC = getOutputCoords();
if (outC < start || outC >= end) {
2020-11-25 14:30:53 +01:00
setOutput(float(${r}));
2020-10-11 18:41:17 +02:00
} else {
setOutput(getX(outC - start));
}
}
`;return}this.userCode=`
2020-11-25 14:30:53 +01:00
${s} start = ${s}(${c});
${s} end = ${s}(${l});
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${s} outC = getOutputCoords();
2020-10-11 18:41:17 +02:00
if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) {
2020-11-25 14:30:53 +01:00
setOutput(float(${r}));
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
${s} coords = outC - start;
setOutput(getX(${p}));
2020-10-11 18:41:17 +02:00
}
}
2020-11-25 14:30:53 +01:00
`}}class hJ{constructor(t,e,r){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e.map((N,S)=>N[0]+t[S]+N[1]);let o=t.length,s=Oe(o),c=e.map(N=>N[0]).join(","),l=e.map((N,S)=>N[0]+t[S]).join(","),p=Jn("rc",o),f=Jn("source",o),m=`${p[o-1]} < ${this.outputShape[o-1]}`,y=o===1?"source":`vec2(${f.slice(-2).join()})`,b=[`${s} rc = outputLoc;`,`${p[o-1]} += 1;
if(${m}) {
`,o===1?"":`}
2020-10-11 18:41:17 +02:00
rc = outputLoc;
2020-11-25 14:30:53 +01:00
${p[o-2]} += 1;
if(${p[o-2]} < ${this.outputShape[o-2]}) {`,o===1?"":` ${p[o-1]} += 1;
if(${m}) {`],v=o===1?"rc < start || rc >= end":"any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))",T="";for(let N=0,S=o===1?2:4;N<S;N++)T+=`
${b[N]}
if (${v}) {
result[${N}] = float(${r});
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
${s} source = rc - start;
result[${N}] = getChannel(getX(${f.join()}), ${y});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;T+=o===1?"} ":"}}",this.userCode=`
const ${s} start = ${s}(${c});
const ${s} end = ${s}(${l});
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${s} outputLoc = getOutputCoords();
2020-10-11 18:41:17 +02:00
vec4 result = vec4(0.);
2020-11-25 14:30:53 +01:00
${T}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}class fh{constructor(t,e,r,o=!1,s=!1){if(this.variableNames=["x"],e==="avg"&&r)throw new Error("Cannot compute positions for average pool.");let c=t.filterWidth,l=t.strideHeight,p=t.strideWidth,f=t.dilationHeight,m=t.dilationWidth,y=t.effectiveFilterHeight,b=t.effectiveFilterWidth,v=t.padInfo.top,T=t.padInfo.left;this.outputShape=t.outShape;let N=e==="avg",S=`((batch * ${t.inHeight} + xR) * ${t.inWidth} + xC) * ${t.inChannels} + d`,D=`(xR * ${t.inWidth} + xC) * ${t.inChannels} + d`,I="0.0";if(N||(I="-1.0 / 1e-20"),r){let H=">=";this.userCode=`
const ivec2 strides = ivec2(${l}, ${p});
const ivec2 pads = ivec2(${v}, ${T});
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int batch = coords[0];
int d = coords[3];
ivec2 xRCCorner = coords.yz * strides - pads;
int xRCorner = xRCCorner.x;
int xCCorner = xRCCorner.y;
// max/min x(?, ?, d) to get y(yR, yC, d).
// ? = to be determined
float minMaxValue = 0.0;
float minMaxValueFound = 0.0;
int minMaxPosition = 0;
float avgValue = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${y};
wR += ${f}) {
2020-10-11 18:41:17 +02:00
int xR = xRCorner + wR;
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${b};
wC += ${m}) {
2020-10-11 18:41:17 +02:00
int xC = xCCorner + wC;
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
float value = getX(batch, xR, xC, d);
// If a min / max value has already been found, use it. If not,
// use the current value.
float currMinMaxValue = mix(
value, minMaxValue, minMaxValueFound);
2020-11-25 14:30:53 +01:00
if (value ${H} currMinMaxValue) {
2020-10-11 18:41:17 +02:00
minMaxValue = value;
minMaxValueFound = 1.0;
2020-11-25 14:30:53 +01:00
minMaxPosition = ${o?s?S:D:`wR * ${b} + wC`};
2020-10-11 18:41:17 +02:00
}
}
}
setOutput(float(minMaxPosition));
}
2020-11-25 14:30:53 +01:00
`;return}let P="max",E=`${e}(${e}(${e}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;e==="avg"&&(E="avgValue / count");let L=Math.floor(c/4)*4,B=c%4,q=`
if (${N}) {
2020-10-11 18:41:17 +02:00
avgValue += dot(values, ones);
} else {
2020-11-25 14:30:53 +01:00
minMaxValue = ${P}(values, minMaxValue);
2020-10-11 18:41:17 +02:00
}
`;this.userCode=`
2020-11-25 14:30:53 +01:00
const ivec2 strides = ivec2(${l}, ${p});
const ivec2 pads = ivec2(${v}, ${T});
const float initializationValue = ${I};
2020-10-11 18:41:17 +02:00
const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);
float count = 0.0;
float getValue(int batch, int xR, int xC, int d) {
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
return initializationValue;
}
count += 1.0;
return getX(batch, xR, xC, d);
}
void main() {
ivec4 coords = getOutputCoords();
int batch = coords[0];
int d = coords[3];
ivec2 xRCCorner = coords.yz * strides - pads;
int xRCorner = xRCCorner.x;
int xCCorner = xRCCorner.y;
// max/min x(?, ?, d) to get y(yR, yC, d).
// ? = to be determined
2020-11-25 14:30:53 +01:00
vec4 minMaxValue = vec4(${I});
2020-10-11 18:41:17 +02:00
float avgValue = 0.0;
count = 0.0;
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${y};
wR += ${f}) {
2020-10-11 18:41:17 +02:00
int xR = xRCorner + wR;
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${L}; wC += 4) {
int xC = xCCorner + wC * ${m};
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xR, xC, d),
2020-11-25 14:30:53 +01:00
getValue(batch, xR, xC + ${m}, d),
getValue(batch, xR, xC + 2 * ${m}, d),
getValue(batch, xR, xC + 3 * ${m}, d)
2020-10-11 18:41:17 +02:00
);
2020-11-25 14:30:53 +01:00
${q}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
int xC = xCCorner + ${L};
if (${B===1}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xR, xC, d),
initializationValue,
initializationValue,
initializationValue
);
2020-11-25 14:30:53 +01:00
${q}
} else if (${B===2}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xR, xC, d),
2020-11-25 14:30:53 +01:00
getValue(batch, xR, xC + ${m}, d),
2020-10-11 18:41:17 +02:00
initializationValue,
initializationValue
);
2020-11-25 14:30:53 +01:00
${q}
} else if (${B===3}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xR, xC, d),
2020-11-25 14:30:53 +01:00
getValue(batch, xR, xC + ${m}, d),
getValue(batch, xR, xC + 2 * ${m}, d),
2020-10-11 18:41:17 +02:00
initializationValue
);
2020-11-25 14:30:53 +01:00
${q}
2020-10-11 18:41:17 +02:00
}
}
2020-10-29 05:16:50 +01:00
setOutput(${E});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class L1{constructor(t,e,r,o=!1,s=!1){if(this.variableNames=["x"],e==="avg"&&r)throw new Error("Cannot compute positions for average pool.");let c=t.filterWidth,l=t.strideDepth,p=t.strideHeight,f=t.strideWidth,m=t.dilationDepth,y=t.dilationHeight,b=t.dilationWidth,v=t.effectiveFilterDepth,T=t.effectiveFilterHeight,N=t.effectiveFilterWidth,S=t.padInfo.front,D=t.padInfo.top,I=t.padInfo.left;this.outputShape=t.outShape;let P=e==="avg",E="0.0";if(P||(E="-1.0 / 1e-20"),r){let J=">=";this.userCode=`
2020-10-11 18:41:17 +02:00
const ivec3 strides =
2020-11-25 14:30:53 +01:00
ivec3(${l}, ${p}, ${f});
const ivec3 pads = ivec3(${S}, ${D}, ${I});
2020-10-11 18:41:17 +02:00
void main() {
ivec5 coords = getOutputCoords();
int batch = coords.x;
int ch = coords.u;
ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;
int xDCorner = xCorner.x;
int xRCorner = xCorner.y;
int xCCorner = xCorner.z;
// max/min x(?, ?, ?, ch) to get y(yD, yR, yC, ch).
// ? = to be determined
float minMaxValue = 0.0;
float minMaxValueFound = 0.0;
int minMaxPosition = 0;
2020-11-25 14:30:53 +01:00
for (int wD = 0; wD < ${v};
wD += ${m}) {
2020-10-11 18:41:17 +02:00
int xD = xDCorner + wD;
2020-11-25 14:30:53 +01:00
if (xD < 0 || xD >= ${t.inDepth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${T};
wR += ${y}) {
2020-10-11 18:41:17 +02:00
int xR = xRCorner + wR;
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${N};
wC += ${b}) {
2020-10-11 18:41:17 +02:00
int xC = xCCorner + wC;
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
continue;
}
float value = getX(batch, xD, xR, xC, ch);
// If a min / max value has already been found, use it. If not,
// use the current value.
float currMinMaxValue = mix(
value, minMaxValue, minMaxValueFound);
2020-11-25 14:30:53 +01:00
if (value ${J} currMinMaxValue) {
2020-10-11 18:41:17 +02:00
minMaxValue = value;
minMaxValueFound = 1.0;
2020-11-25 14:30:53 +01:00
minMaxPosition = ${o?s?`(((batch * ${t.inDepth} + xD) * ${t.inHeight} + xR) * ${t.inWidth} + xC) * ${t.inChannels} + ch`:`((xD * ${t.inHeight} + xR) * ${t.inWidth} + xC) * ${t.inChannels} + ch`:`wD * ${T} * ${N} +
wR * ${N} + wC`};
2020-10-11 18:41:17 +02:00
}
}
}
}
setOutput(float(minMaxPosition));
}
2020-11-25 14:30:53 +01:00
`;return}let L="max",B=`${e}(${e}(${e}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;e==="avg"&&(B="avgValue / count");let q=Math.floor(c/4)*4,H=c%4,Z=`
if (${P}) {
2020-10-11 18:41:17 +02:00
avgValue += dot(values, ones);
} else {
2020-11-25 14:30:53 +01:00
minMaxValue = ${L}(values, minMaxValue);
2020-10-11 18:41:17 +02:00
}
`;this.userCode=`
const ivec3 strides =
2020-11-25 14:30:53 +01:00
ivec3(${l}, ${p}, ${f});
const ivec3 pads = ivec3(${S}, ${D}, ${I});
2020-10-29 05:16:50 +01:00
const float initializationValue = ${E};
2020-10-11 18:41:17 +02:00
const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);
float count = 0.0;
float getValue(int batch, int xD, int xR, int xC, int ch) {
2020-11-25 14:30:53 +01:00
if (xC < 0 || xC >= ${t.inWidth}) {
2020-10-11 18:41:17 +02:00
return initializationValue;
}
count += 1.0;
return getX(batch, xD, xR, xC, ch);
}
void main() {
ivec5 coords = getOutputCoords();
int batch = coords.x;
int ch = coords.u;
ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;
int xDCorner = xCorner.x;
int xRCorner = xCorner.y;
int xCCorner = xCorner.z;
// max/min x(?, ?, ?, d) to get y(yD, yR, yC, ch).
// ? = to be determined
2020-10-29 05:16:50 +01:00
vec4 minMaxValue = vec4(${E});
2020-10-11 18:41:17 +02:00
float avgValue = 0.0;
count = 0.0;
2020-11-25 14:30:53 +01:00
for (int wD = 0; wD < ${v};
wD += ${m}) {
2020-10-11 18:41:17 +02:00
int xD = xDCorner + wD;
2020-11-25 14:30:53 +01:00
if (xD < 0 || xD >= ${t.inDepth}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wR = 0; wR < ${T};
wR += ${y}) {
2020-10-11 18:41:17 +02:00
int xR = xRCorner + wR;
2020-11-25 14:30:53 +01:00
if (xR < 0 || xR >= ${t.inHeight}) {
2020-10-11 18:41:17 +02:00
continue;
}
2020-11-25 14:30:53 +01:00
for (int wC = 0; wC < ${q}; wC += 4) {
int xC = xCCorner + wC * ${b};
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xD, xR, xC, ch),
2020-11-25 14:30:53 +01:00
getValue(batch, xD, xR, xC + ${b}, ch),
getValue(batch, xD, xR, xC + 2 * ${b}, ch),
getValue(batch, xD, xR, xC + 3 * ${b}, ch)
2020-10-11 18:41:17 +02:00
);
2020-11-25 14:30:53 +01:00
${Z}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
int xC = xCCorner + ${q};
if (${H===1}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xD, xR, xC, ch),
initializationValue,
initializationValue,
initializationValue
);
2020-11-25 14:30:53 +01:00
${Z}
} else if (${H===2}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xD, xR, xC, ch),
2020-11-25 14:30:53 +01:00
getValue(batch, xD, xR, xC + ${b}, ch),
2020-10-11 18:41:17 +02:00
initializationValue,
initializationValue
);
2020-11-25 14:30:53 +01:00
${Z}
} else if (${H===3}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, xD, xR, xC, ch),
2020-11-25 14:30:53 +01:00
getValue(batch, xD, xR, xC + ${b}, ch),
getValue(batch, xD, xR, xC + 2 * ${b}, ch),
2020-10-11 18:41:17 +02:00
initializationValue
);
2020-11-25 14:30:53 +01:00
${Z}
2020-10-11 18:41:17 +02:00
}
}
2020-11-25 14:30:53 +01:00
setOutput(${B});
2020-10-11 18:41:17 +02:00
}
}
2020-11-25 14:30:53 +01:00
`}}class YI{constructor(t,e){this.variableNames=["x"];let{windowSize:r,batchSize:o,inSize:s,outSize:c}=t;this.outputShape=[o,c];let l="0.0",p="";e==="prod"?l="1.0":e==="min"?(l="1.0 / 1e-20",p="min"):e==="max"&&(l="-1.0 / 1e-20",p="max");let f=`${e}(${e}(${e}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;e==="sum"?f="sumValue":e==="prod"?f="prodValue":e==="all"?f="allValue":e==="any"&&(f="anyValue");let m=Math.floor(r/4)*4,y=r%4,b=`
if (${e==="sum"}) {
2020-10-11 18:41:17 +02:00
sumValue += dot(values, ones);
2020-11-25 14:30:53 +01:00
} else if (${e==="prod"}) {
2020-10-11 18:41:17 +02:00
vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]);
prodValue *= tmp[0] * tmp[1];
} else {
2020-11-25 14:30:53 +01:00
minMaxValue = ${p}(values, minMaxValue);
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`,v="vec4";e==="all"?(l="1.0",b=`
2020-10-11 18:41:17 +02:00
bool reducedAllValue = all(values);
float floatedReducedAllValue = float(reducedAllValue);
allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0);
2020-11-25 14:30:53 +01:00
`,v="bvec4"):e==="any"&&(l="0.0",b=`
2020-10-11 18:41:17 +02:00
bool reducedAnyValue = any(values);
float floatedReducedAnyValue = float(reducedAnyValue);
anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0);
2020-11-25 14:30:53 +01:00
`,v="bvec4");let T="";s%r>0&&(T=`
if (inIdx < 0 || inIdx >= ${s}) {
2020-10-11 18:41:17 +02:00
return initializationValue;
}
`),this.userCode=`
2020-11-25 14:30:53 +01:00
const float initializationValue = ${l};
2020-10-11 18:41:17 +02:00
const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);
float getValue(int batch, int inIdx) {
2020-11-25 14:30:53 +01:00
${T}
2020-10-11 18:41:17 +02:00
return getX(batch, inIdx);
}
void main() {
ivec2 coords = getOutputCoords();
int batch = coords[0];
int outIdx = coords[1];
2020-11-25 14:30:53 +01:00
int inOffset = outIdx * ${r};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
vec4 minMaxValue = vec4(${l});
2020-10-11 18:41:17 +02:00
float prodValue = 1.0;
float sumValue = 0.0;
float allValue = 1.0;
float anyValue = 0.0;
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${m}; i += 4) {
2020-10-11 18:41:17 +02:00
int inIdx = inOffset + i;
2020-11-25 14:30:53 +01:00
${v} values = ${v}(
2020-10-11 18:41:17 +02:00
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
getValue(batch, inIdx + 2),
getValue(batch, inIdx + 3)
);
2020-11-25 14:30:53 +01:00
${b}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
int inIdx = inOffset + ${m};
if (${y===1}) {
${v} values = ${v}(
2020-10-11 18:41:17 +02:00
getValue(batch, inIdx),
initializationValue,
initializationValue,
initializationValue
);
2020-11-25 14:30:53 +01:00
${b}
} else if (${y===2}) {
${v} values = ${v}(
2020-10-11 18:41:17 +02:00
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
initializationValue,
initializationValue
);
2020-11-25 14:30:53 +01:00
${b}
} else if (${y===3}) {
${v} values = ${v}(
2020-10-11 18:41:17 +02:00
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
getValue(batch, inIdx + 2),
initializationValue
);
2020-11-25 14:30:53 +01:00
${b}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
setOutput(${f});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class JI{constructor(t,e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t;let r="";for(let o=0;o<4;o++){let s="thisRC = rc;";o%2===1&&(s+="thisRC.z += 1;"),o>1&&(s+="thisRC.y += 1;"),r+=`
${s}
${o>0?"if(thisRC.y < rows && thisRC.z < cols){":""}
2020-10-11 18:41:17 +02:00
int flatIndex = getFlatIndex(thisRC);
ivec3 inputRC = inputCoordsFromReshapedOutCoords(flatIndex);
vec2 inputRCInnerDims = vec2(float(inputRC.y),float(inputRC.z));
2020-11-25 14:30:53 +01:00
result[${o}] =
2020-10-11 18:41:17 +02:00
getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims);
2020-11-25 14:30:53 +01:00
${o>0?"}":""}
2020-10-11 18:41:17 +02:00
`}this.userCode=`
2020-11-25 14:30:53 +01:00
${fJ(e)}
${P1(t)}
2020-10-11 18:41:17 +02:00
void main() {
ivec3 rc = getOutputCoords();
vec4 result = vec4(0.);
ivec3 thisRC;
2020-11-25 14:30:53 +01:00
int rows = ${t[1]};
int cols = ${t[2]};
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
${r}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}function fJ(n){let t=_a(["r","c","d"],n);return`
2020-10-11 18:41:17 +02:00
ivec3 inputCoordsFromReshapedOutCoords(int index) {
${t}
return ivec3(r, c, d);
}
2020-11-25 14:30:53 +01:00
`}class dJ{constructor(t,e,r){this.variableNames=["dy"],this.outputShape=[],this.outputShape=e.shape;let[,o,s]=e.shape,[,c,l]=t.shape,p=[r&&c>1?o-1:o,r&&l>1?s-1:s],f=[r&&c>1?c-1:c,r&&l>1?l-1:l],m=p[0]/f[0],y=p[1]/f[1],b=1/m,v=1/y,T=Math.ceil(b)*2+2,N=Math.ceil(v)*2+2;this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
int r = coords[1];
int c = coords[2];
float accumulator = 0.0;
2020-11-25 14:30:53 +01:00
const float heightScale = float(${m});
const float widthScale = float(${y});
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const float invHeightScale = float(${b});
const float invWidthScale = float(${v});
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const int winHeight = int(${T});
const int winWidth = int(${N});
2020-10-11 18:41:17 +02:00
// Compute bounds for where in dy we will look
float startRLerp = floor(float(r) * invHeightScale);
int startDyR = int(startRLerp - float(winHeight / 2));
float startCLerp = floor(float(c) * invWidthScale);
int startDyC = int(startCLerp - float(winWidth / 2));
// Loop over dy
for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {
int dyR = dyROffset + startDyR;
// Guard against the window exceeding the bounds of dy
2020-11-25 14:30:53 +01:00
if (dyR < 0 || dyR >= ${c}) {
2020-10-11 18:41:17 +02:00
continue;
}
for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {
int dyC = dyCOffset + startDyC;
// Guard against the window exceeding the bounds of dy
2020-11-25 14:30:53 +01:00
if (dyC < 0 || dyC >= ${l}) {
2020-10-11 18:41:17 +02:00
continue;
}
float dxR = float(dyR) * heightScale;
int topDxRIndex = int(floor(dxR));
2020-11-25 14:30:53 +01:00
int bottomDxRIndex = int(min(ceil(dxR), ${o-1}.0));
2020-10-11 18:41:17 +02:00
float dxRLerp = dxR - float(topDxRIndex);
float inverseDxRLerp = 1.0 - dxRLerp;
float dxC = float(dyC) * widthScale;
int leftDxCIndex = int(floor(dxC));
2020-11-25 14:30:53 +01:00
int rightDxCIndex = int(min(ceil(dxC), ${s-1}.0));
2020-10-11 18:41:17 +02:00
float dxCLerp = dxC - float(leftDxCIndex);
float inverseDxCLerp = 1.0 - dxCLerp;
if (r == topDxRIndex && c == leftDxCIndex) {
// topLeft
accumulator +=
getDy(b, dyR, dyC, d) * inverseDxRLerp * inverseDxCLerp;
}
if (r == topDxRIndex && c == rightDxCIndex) {
// topRight
accumulator += getDy(b, dyR, dyC, d) * inverseDxRLerp * dxCLerp;
}
if (r == bottomDxRIndex && c == leftDxCIndex) {
// bottomLeft
accumulator += getDy(b, dyR, dyC, d) * dxRLerp * inverseDxCLerp;
}
if (r == bottomDxRIndex && c == rightDxCIndex) {
// bottomRight
accumulator += getDy(b, dyR, dyC, d) * dxRLerp * dxCLerp;
}
}
}
// End loop over dy
setOutput(accumulator);
}
2020-11-25 14:30:53 +01:00
`}}class mJ{constructor(t,e,r,o){this.variableNames=["A"],this.outputShape=[];let[s,c,l,p]=t;this.outputShape=[s,e,r,p];let f=[o&&e>1?c-1:c,o&&r>1?l-1:l],m=[o&&e>1?e-1:e,o&&r>1?r-1:r];this.userCode=`
2020-10-11 18:41:17 +02:00
const vec2 effectiveInputOverOutputRatioRC = vec2(
2020-11-25 14:30:53 +01:00
${f[0]/m[0]},
${f[1]/m[1]});
const vec2 inputShapeRC = vec2(${c}.0, ${l}.0);
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
ivec2 yRC = coords.yz;
// Fractional source index.
vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;
// Compute the four integer indices.
ivec2 sourceFloorRC = ivec2(sourceFracIndexRC);
ivec2 sourceCeilRC = ivec2(
min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));
float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d);
float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d);
float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d);
float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d);
vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);
float top = topLeft + (topRight - topLeft) * fracRC.y;
float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;
float newValue = top + (bottom - top) * fracRC.x;
setOutput(newValue);
}
2020-11-25 14:30:53 +01:00
`}}class gJ{constructor(t,e,r,o){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[];let[s,c,l,p]=t;this.outputShape=[s,e,r,p];let f=[o&&e>1?c-1:c,o&&r>1?l-1:l],m=[o&&e>1?e-1:e,o&&r>1?r-1:r];this.userCode=`
2020-10-11 18:41:17 +02:00
const vec3 effectiveInputOverOutputRatioRC = vec3(
2020-11-25 14:30:53 +01:00
${f[0]/m[0]},
${f[1]/m[1]},
${f[1]/m[1]});
const vec3 inputShapeRC = vec3(${c}.0, ${l}.0,
${l}.0);
2020-10-11 18:41:17 +02:00
float getAValue(int b, int r, int c, int d) {
return getChannel(getA(b, r, c, d), vec2(c, d));
}
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
// Calculate values for next column in yRC.z.
ivec3 yRC = coords.yzz + ivec3(0, 0, 1);
// Fractional source index.
vec3 sourceFracIndexRC = vec3(yRC) * effectiveInputOverOutputRatioRC;
// Compute the four integer indices.
ivec3 sourceFloorRC = ivec3(sourceFracIndexRC);
ivec3 sourceCeilRC = ivec3(
min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));
// Should we calculate next column and row elements in 2x2 packed cell.
2020-11-25 14:30:53 +01:00
bool hasNextCol = d < ${p-1};
bool hasNextRow = coords.z < ${r-1};
2020-10-11 18:41:17 +02:00
// In parallel, construct four corners for all four components in
// packed 2x2 cell.
vec4 topLeft = vec4(
getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d),
hasNextCol ? getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d + 1)
: 0.0,
hasNextRow ? getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d)
: 0.0,
(hasNextRow && hasNextCol) ?
getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d + 1) : 0.0);
vec4 bottomLeft = vec4(
getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d),
hasNextCol ? getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d + 1)
: 0.0,
hasNextRow ? getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d)
: 0.0,
(hasNextRow && hasNextCol) ?
getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d + 1) : 0.0);
vec4 topRight = vec4(
getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d),
hasNextCol ? getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d + 1)
: 0.0,
hasNextRow ? getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d)
: 0.0,
(hasNextRow && hasNextCol) ?
getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d + 1) : 0.0);
vec4 bottomRight = vec4(
getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d),
hasNextCol ? getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d + 1)
: 0.0,
hasNextRow ? getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d)
: 0.0,
(hasNextRow && hasNextCol) ?
getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d + 1) : 0.0);
vec3 fracRC = sourceFracIndexRC - vec3(sourceFloorRC);
vec4 top = mix(topLeft, topRight, fracRC.yyzz);
vec4 bottom = mix(bottomLeft, bottomRight, fracRC.yyzz);
vec4 newValue = mix(top, bottom, fracRC.x);
setOutput(newValue);
}
2020-11-25 14:30:53 +01:00
`}}class yJ{constructor(t,e,r){this.variableNames=["dy"],this.outputShape=[],this.outputShape=e.shape;let[,o,s]=e.shape,[,c,l]=t.shape,p=[r&&c>1?o-1:o,r&&l>1?s-1:s],f=[r&&c>1?c-1:c,r&&l>1?l-1:l],m=p[0]/f[0],y=p[1]/f[1],b=1/m,v=1/y,T=Math.ceil(b)*2+2,N=Math.ceil(v)*2+2;this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
int r = coords[1];
int c = coords[2];
float accumulator = 0.0;
2020-11-25 14:30:53 +01:00
const float heightScale = float(${m});
const float widthScale = float(${y});
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const float invHeightScale = float(${b});
const float invWidthScale = float(${v});
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
const int winHeight = int(${T});
const int winWidth = int(${N});
2020-10-11 18:41:17 +02:00
// Compute bounds for where in dy we will look
float startRLerp = floor(float(r) * invHeightScale);
int startDyR = int(floor(startRLerp - float(winHeight / 2)));
float startCLerp = floor(float(c) * invWidthScale);
int startDyC = int(floor(startCLerp - float(winWidth / 2)));
// Loop over dy
for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {
int dyR = dyROffset + startDyR;
// Guard against the window exceeding the bounds of dy
2020-11-25 14:30:53 +01:00
if (dyR < 0 || dyR >= ${c}) {
2020-10-11 18:41:17 +02:00
continue;
}
for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {
int dyC = dyCOffset + startDyC;
// Guard against the window exceeding the bounds of dy
2020-11-25 14:30:53 +01:00
if (dyC < 0 || dyC >= ${l}) {
2020-10-11 18:41:17 +02:00
continue;
}
float sourceFracRow =
2020-11-25 14:30:53 +01:00
float(${p[0]}) *
(float(dyR) / float(${f[0]}));
2020-10-11 18:41:17 +02:00
float sourceFracCol =
2020-11-25 14:30:53 +01:00
float(${p[1]}) *
(float(dyC) / float(${f[1]}));
2020-10-11 18:41:17 +02:00
int sourceNearestRow = int(min(
2020-11-25 14:30:53 +01:00
float(int(${o}) - 1),
${r} ? float(round(sourceFracRow)) :
2020-10-11 18:41:17 +02:00
float(floor(sourceFracRow))));
int sourceNearestCol = int(min(
2020-11-25 14:30:53 +01:00
float(int(${s}) - 1),
${r} ? float(round(sourceFracCol)) :
2020-10-11 18:41:17 +02:00
float(floor(sourceFracCol))));
if (r == sourceNearestRow && c == sourceNearestCol) {
accumulator += getDy(b, dyR, dyC, d);
}
}
}
// End loop over dy
setOutput(accumulator);
}
2020-11-25 14:30:53 +01:00
`}}class bJ{constructor(t,e,r,o){this.variableNames=["A"],this.outputShape=[];let[s,c,l,p]=t;this.outputShape=[s,e,r,p];let f=[o&&e>1?c-1:c,o&&r>1?l-1:l],m=[o&&e>1?e-1:e,o&&r>1?r-1:r],y=o?"0.5":"0.0";this.userCode=`
2020-10-11 18:41:17 +02:00
const vec2 effectiveInputOverOutputRatioRC = vec2(
2020-11-25 14:30:53 +01:00
${f[0]/m[0]},
${f[1]/m[1]});
const vec2 inputShapeRC = vec2(${c}.0, ${l}.0);
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
ivec2 yRC = coords.yz;
// Fractional source index.
vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;
// Compute the coordinators of nearest neighbor point.
ivec2 sourceNearestRC = ivec2(
2020-11-25 14:30:53 +01:00
min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${y})));
2020-10-11 18:41:17 +02:00
float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d);
setOutput(newValue);
}
2020-11-25 14:30:53 +01:00
`}}class xJ{constructor(t,e){this.variableNames=["x"];let r=t.length;if(r>4)throw new Error(`WebGL backend: Reverse of rank-${r} tensor is not yet supported`);if(this.outputShape=t,r===1){this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
int coord = getOutputCoords();
2020-11-25 14:30:53 +01:00
setOutput(getX(${t[0]} - coord - 1));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`;return}let o=l=>e.indexOf(l)!==-1&&t[l]!==1?`${t[l]} - coords[${l}] - 1`:`coords[${l}]`,s=t.map((l,p)=>o(p)).join(","),c=Oe(r);this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${c} coords = getOutputCoords();
setOutput(getX(${s}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class wJ{constructor(t,e){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0;let r=t.length;if(r>4)throw new Error(`WebGL backend: Reverse of rank-${r} tensor is not yet supported`);this.outputShape=t;let o=Jn("rc",r),s=`${o[r-1]} + 1 < ${this.outputShape[r-1]}`,c=`${o[r-2]} + 1 < ${this.outputShape[r-2]}`,l=Oe(r);r===1?this.userCode=`
2020-10-11 18:41:17 +02:00
void main(){
int rc = getOutputCoords();
vec4 result = vec4(0.);
2020-11-25 14:30:53 +01:00
result.r = getChannel(getX(${t[0]} - rc - 1),
${t[0]} - rc - 1);
if(${s}){
result.g = getChannel(getX(${t[0]} - (rc + 1) - 1),
${t[0]} - (rc + 1) - 1);
2020-10-11 18:41:17 +02:00
}
setOutput(result);
}
`:this.userCode=`
void main() {
2020-11-25 14:30:53 +01:00
${l} rc = getOutputCoords();
2020-10-11 18:41:17 +02:00
vec4 result = vec4(0.);
2020-11-25 14:30:53 +01:00
result.r = ${p(o.slice())};
if(${s}){
result.g = ${f(o.slice())};
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
if(${c}) {
result.b = ${m(o.slice())};
if(${s}) {
result.a = ${y(o.slice())};
2020-10-11 18:41:17 +02:00
}
}
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`;function p(T){return b(T)}function f(T){return T[r-1]="("+T[r-1]+" + 1)",b(T)}function m(T){return T[r-2]="("+T[r-2]+" + 1)",b(T)}function y(T){return T[r-1]="("+T[r-1]+" + 1)",T[r-2]="("+T[r-2]+" + 1)",b(T)}function b(T){let N=t.map((I,P)=>v(P,T)),S=N.join(","),D=N.slice(-2).join(",");return`getChannel(getX(${S}), vec2(${D}))`}function v(T,N){return e.indexOf(T)!==-1&&t[T]!==1?`${t[T]} - ${N[T]} - 1`:`${N[T]}`}}}class ZI{constructor(t,e,r,o,s,c,l=!0){this.variableNames=["updates","indices","defaultValue"],this.outputShape=c;let p=Oe(s.length),f=Oe(c.length),m="";r===1?m="i":r===2&&(m="i, j");let y=`getIndices(${m})`,b="";o===1?b="i":o===2&&(b="i, coords[1]");let v=`getUpdates(${b})`,T=e>1?"strides[j]":"strides";this.userCode=`
${p} strides = ${p}(${s});
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${f} coords = getOutputCoords();
2020-10-11 18:41:17 +02:00
float sum = 0.0;
bool found = false;
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${t}; i++) {
2020-10-11 18:41:17 +02:00
int flattenedIndex = 0;
2020-11-25 14:30:53 +01:00
for (int j = 0; j < ${e}; j++) {
int index = round(${y});
flattenedIndex += index * ${T};
2020-10-11 18:41:17 +02:00
}
if (flattenedIndex == coords[0]) {
2020-11-25 14:30:53 +01:00
sum += ${v};
2020-10-11 18:41:17 +02:00
found = true;
}
}
setOutput(mix(getDefaultValue(), sum, float(found)));
}
2020-11-25 14:30:53 +01:00
`}}class vJ{constructor(t,e){this.variableNames=["x","segmentIds"];let r=t.windowSize,o=t.batchSize,s=t.inSize,c=t.numSegments,l=c*Math.ceil(s/r);this.outputShape=[o,l];let p="0.0",f="sumValue",m=Math.floor(r/4)*4,y=r%4,b=`
2020-10-11 18:41:17 +02:00
sumValue += dot(values, segFilter);
2020-11-25 14:30:53 +01:00
`,v="";s%r>0&&(v=`
if (inIdx < 0 || inIdx >= ${s}) {
2020-10-11 18:41:17 +02:00
return initializationValue;
}
2020-11-25 14:30:53 +01:00
`);let T="";s%r>0&&(T=`
if (inIdx < 0 || inIdx >= ${s}) {
2020-10-11 18:41:17 +02:00
return -1.0;
}
`),this.userCode=`
2020-11-25 14:30:53 +01:00
const float initializationValue = ${p};
2020-10-11 18:41:17 +02:00
float getValue(int batch, int inIdx) {
2020-11-25 14:30:53 +01:00
${v}
2020-10-11 18:41:17 +02:00
return getX(batch, inIdx);
}
float getSegmentIdAtIndex(int inIdx) {
2020-11-25 14:30:53 +01:00
${T}
2020-10-11 18:41:17 +02:00
return getSegmentIds(inIdx);
}
void main() {
ivec2 coords = getOutputCoords();
int batch = coords[0];
int outIdx = coords[1];
int inOffset = int(floor(float(outIdx) / float(
2020-11-25 14:30:53 +01:00
${c})) * float(${r}));
int currentSeg = int(mod(float(outIdx), float(${c})));
2020-10-11 18:41:17 +02:00
float sumValue = 0.0;
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${m}; i += 4) {
2020-10-11 18:41:17 +02:00
int inIdx = inOffset + i;
vec4 values = vec4(
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
getValue(batch, inIdx + 2),
getValue(batch, inIdx + 3)
);
vec4 segFilter = vec4(
int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,
int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,
int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,
int(getSegmentIdAtIndex(inIdx + 3)) == currentSeg ? 1 : 0
);
2020-11-25 14:30:53 +01:00
${b}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
int inIdx = inOffset + ${m};
if (${y===1}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, inIdx),
initializationValue,
initializationValue,
initializationValue
);
int inIdxSeg = int(getSegmentIdAtIndex(inIdx));
vec4 segFilter = vec4(
int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,
0,
0,
0
);
2020-11-25 14:30:53 +01:00
${b}
} else if (${y===2}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
initializationValue,
initializationValue
);
vec4 segFilter = vec4(
int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,
int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,
0,
0
);
2020-11-25 14:30:53 +01:00
${b}
} else if (${y===3}) {
2020-10-11 18:41:17 +02:00
vec4 values = vec4(
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
getValue(batch, inIdx + 2),
initializationValue
);
vec4 segFilter = vec4(
int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,
int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,
int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,
0
);
2020-11-25 14:30:53 +01:00
${b}
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
setOutput(${f});
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class TJ{constructor(t,e,r){this.variableNames=["c","a","b"],this.outputShape=e;let o,s;if(r>4)throw Error(`Where for rank ${r} is not yet supported`);if(r===1)s="resRC",o="resRC";else{let l=["resRC.x","resRC.y","resRC.z","resRC.w"],p=[],f=[];for(let m=0;m<e.length;m++)f.push(`${l[m]}`),m<t&&p.push(`${l[m]}`);o=p.join(),s=f.join()}let c=Oe(r);this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${c} resRC = getOutputCoords();
float cVal = getC(${o});
2020-10-11 18:41:17 +02:00
if (cVal >= 1.0) {
2020-11-25 14:30:53 +01:00
setOutput(getA(${s}));
2020-10-11 18:41:17 +02:00
} else {
2020-11-25 14:30:53 +01:00
setOutput(getB(${s}));
2020-10-11 18:41:17 +02:00
}
}
2020-11-25 14:30:53 +01:00
`}}class kJ{constructor(t){this.variableNames=["source"],this.outputShape=t,this.rank=t.length;let e=Oe(this.rank),r=`uniform int start[${this.rank}];`,o=NJ(this.rank),s,c=t.map((l,p)=>`sourceLoc.${M1[p]} = start[${p}] + coords.${M1[p]};`);s=`
${e} sourceLoc;
${e} coords = getOutputCoords();
${c.join(`
2020-10-11 18:41:17 +02:00
`)}
`,this.userCode=`
2020-11-25 14:30:53 +01:00
${r}
void main() {
${s}
setOutput(getSource(${o}));
}
`}getCustomSetupFunc(t){if(t.length!==this.rank)throw Error(`The rank (${this.rank}) of the program must match the length of start (${t.length})`);return(e,r)=>{if(this.startLoc==null&&(this.startLoc=e.getUniformLocationNoThrow(r,"start"),this.startLoc==null))return;e.gl.uniform1iv(this.startLoc,t)}}}let M1=["x","y","z","w","u","v"];function NJ(n){if(n===1)return"sourceLoc";if(n<=6)return M1.slice(0,n).map(t=>"sourceLoc."+t).join(",");throw Error(`Slicing for rank ${n} is not yet supported`)}class _J{constructor(t){this.variableNames=["source"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t,this.rank=t.length;let e=Oe(this.rank),r=Jn("coords",this.rank),o=Jn("sourceLoc",this.rank),s=this.rank===1?"sourceLoc":`vec2(${o.slice(-2).join()})`,c=`getChannel(getSource(${o.join()}), ${s})`,l=`
result.x = ${c};
if (++${r[this.rank-1]} < ${t[this.rank-1]}) {
++${o[this.rank-1]};
result.y = ${c};
--${o[this.rank-1]};
}
`,p=this.rank===1?"":`
--${r[this.rank-1]};
if (++${r[this.rank-2]} < ${t[this.rank-2]}) {
++${o[this.rank-2]};
result.z = ${c};
if (++${r[this.rank-1]} < ${t[this.rank-1]}) {
++${o[this.rank-1]};
result.w = ${c};
}
}
`,f=this.rank<=4?`sourceLoc = coords +
${e}(${t.map((m,y)=>`start[${y}]`).join()});`:t.map((m,y)=>`${o[y]} = ${r[y]} + start[${y}];`).join(`
2020-10-11 18:41:17 +02:00
`);this.userCode=`
uniform int start[${this.rank}];
void main() {
2020-11-25 14:30:53 +01:00
${e} coords = getOutputCoords();
${e} sourceLoc;
${f}
2020-10-11 18:41:17 +02:00
vec4 result = vec4(0.);
2020-11-25 14:30:53 +01:00
${l}
${p}
2020-10-11 18:41:17 +02:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}getCustomSetupFunc(t){if(t.length!==this.rank)throw Error(`The rank (${this.rank}) of the program must match the length of start (${t.length})`);return(e,r)=>{if(this.startLoc==null&&(this.startLoc=e.getUniformLocationNoThrow(r,"start"),this.startLoc==null))return;e.gl.uniform1iv(this.startLoc,t)}}}class CJ{constructor(t,e,r){this.variableNames=["x"],this.outputShape=r;let o=r.length,s=Oe(r.length),c=Oe(r.length),l="";if(o===1)l="coords * strides + begin";else{let p=0;l=r.map((f,m)=>(p++,r.length===1?`coords * strides[${m}] + begin[${m}]`:`coords[${p-1}] * strides[${m}] + begin[${m}]`)).join(",")}this.userCode=`
${s} begin = ${s}(${t});
${s} strides = ${s}(${e});
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${c} coords = getOutputCoords();
setOutput(getX(${l}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}class SJ{constructor(t){this.gpgpu=t,this.numUsedTextures=0,this.numFreeTextures=0,this._numBytesAllocated=0,this._numBytesFree=0,this.freeTextures={},this.logEnabled=!1,this.usedTextures={}}acquireTexture(t,e,r){let o=tE(e,r),s=eE(t,o,r);s in this.freeTextures||(this.freeTextures[s]=[]),s in this.usedTextures||(this.usedTextures[s]=[]);let c=QI(t,o,this.gpgpu.gl,this.gpgpu.textureConfig,r);if(this.freeTextures[s].length>0){this.numFreeTextures--,this.numUsedTextures++,this._numBytesFree-=c,this.log();let p=this.freeTextures[s].shift();return this.usedTextures[s].push(p),p}let l;return o===Ln.PACKED_2X2_FLOAT32?l=this.gpgpu.createPackedMatrixTexture(t[0],t[1]):o===Ln.PACKED_2X2_FLOAT16?l=this.gpgpu.createFloat16PackedMatrixTexture(t[0],t[1]):o===Ln.UNPACKED_FLOAT32?l=this.gpgpu.createFloat32MatrixTexture(t[0],t[1]):o===Ln.UNPACKED_FLOAT16?l=this.gpgpu.createFloat16MatrixTexture(t[0],t[1]):o===Ln.PACKED_4X1_UNSIGNED_BYTE&&(l=this.gpgpu.createUnsignedBytesMatrixTexture(t[0],t[1])),this.usedTextures[s].push(l),this.numUsedTextures++,this._numBytesAllocated+=c,this.log(),l}releaseTexture(t,e,r,o){if(this.freeTextures==null)return;let s=tE(r,o),c=eE(e,s,o);c in this.freeTextures||(this.freeTextures[c]=[]);let l=QI(e,s,this.gpgpu.gl,this.gpgpu.textureConfig,o),p=ct().get("WEBGL_DELETE_TEXTURE_THRESHOLD");p!==-1&&this._numBytesAllocated>p?(this.gpgpu.deleteMatrixTexture(t),this._numBytesAllocated-=l):(this.freeTextures[c].push(t),this.numFreeTextures++,this._numBytesFree+=l),this.numUsedTextures--;let f=this.usedTextures[c],m=f.indexOf(t);if(m<0)throw new Error("Cannot release a texture that was never provided by this texture manager");f.splice(m,1),this.log()}log(){if(!this.logEnabled)return;let t=this.numFreeTextures+this.numUsedTextures;console.log("Free/Used",`${this.numFreeTextures} / ${this.numUsedTextures}`,`(${t})`);let e=this._numBytesFree/this._numBytesAllocated;console.log(`Bytes allocated: ${this._numBytesAllocated}`),console.log(`Bytes unused: ${this._numBytesFree} (${Math.round(100*e)}%)`)}get numBytesAllocated(){return this._numBytesAllocated}get numBytesFree(){return this._numBytesFree}getNumUsedTextures(){return this.numUsedTextures}getNumFreeTextures(){return this.numFreeTextures}dispose(){if(this.freeTextures==null)return;for(let t in this.freeTextures)this.freeTextures[t].forEach(e=>{this.gpgpu.deleteMatrixTexture(e)});for(let t in this.usedTextures)this.usedTextures[t].forEach(e=>{this.gpgpu.deleteMatrixTexture(e)});this.freeTextures=null,this.usedTextures=null,this.numUsedTextures=0,this.numFreeTextures=0,this._numBytesAllocated=0,this._numBytesFree=0}}function $J(n,t){let e=n;if(t===e.R32F)return 4;if(t===e.R16F)return 2;if(t===e.RGBA32F)return 16;if(t===n.RGBA)return 16;if(t===e.RGBA16F)return 8;throw new Error(`Unknown internal format ${t}`)}function QI(n,t,e,r,o){let s=IJ(t,r),c;if(o){let[p,f]=fl(n[0],n[1]);c=p*f}else{let[p,f]=lh(n[0],n[1]);c=p*f}let l=$J(e,s);return c*l}function IJ(n,t){switch(n){case Ln.PACKED_2X2_FLOAT32:return jI(t);case Ln.PACKED_2X2_FLOAT16:return KI(t);case Ln.UNPACKED_FLOAT32:return UI(t);case Ln.UNPACKED_FLOAT16:return qI(t);case Ln.PACKED_4X1_UNSIGNED_BYTE:return HI(t);default:throw new Error(`Unknown physical texture type ${n}`)}}function EJ(n){return ct().getBool("WEBGL_RENDER_FLOAT32_ENABLED")?n?Ln.PACKED_2X2_FLOAT32:Ln.UNPACKED_FLOAT32:n?Ln.PACKED_2X2_FLOAT16:Ln.UNPACKED_FLOAT16}function tE(n,t){if(n===Br.UPLOAD)return Ln.PACKED_2X2_FLOAT32;if(n===Br.RENDER||n==null)return EJ(t);if(n===Br.DOWNLOAD||n===Br.PIXELS)return Ln.PACKED_4X1_UNSIGNED_BYTE;throw new Error(`Unknown logical texture type ${n}`)}function eE(n,t,e){return`${n[0]}_${n[1]}_${t}_${e}`}class DJ{constructor(t,e){this.variableNames=["A"];let r=new Array(t.length);for(let c=0;c<r.length;c++)r[c]=t[c]*e[c];this.outputShape=r,this.rank=r.length;let o=Oe(this.rank),s=AJ(t);this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${o} resRC = getOutputCoords();
setOutput(getA(${s}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}function AJ(n){let t=n.length;if(t>5)throw Error(`Tile for rank ${t} is not yet supported`);if(t===1)return`imod(resRC, ${n[0]})`;let e=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u"],r=[];for(let o=0;o<n.length;o++)r.push(`imod(${e[o]}, ${n[o]})`);return r.join()}class ue{constructor(t,e){this.variableNames=["A"],this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
float unaryOperation(float x) {
2020-11-25 14:30:53 +01:00
${e}
2020-10-11 18:41:17 +02:00
}
void main() {
float x = getAAtOutCoords();
float y = unaryOperation(x);
setOutput(y);
}
2020-11-25 14:30:53 +01:00
`}}let $s="if (isnan(x)) return x;",FJ="return x;",nE="return abs(x);",rE=$s+`
2020-10-11 18:41:17 +02:00
return (x < 0.0) ? 0.0 : x;
2020-11-25 14:30:53 +01:00
`,oE=$s+`
2020-10-11 18:41:17 +02:00
return (x < 0.0) ? 0.0 : min(6.0, x);
2020-11-25 14:30:53 +01:00
`,sE="return (x >= 0.0) ? x : (exp(x) - 1.0);",RJ=`
2020-10-11 18:41:17 +02:00
// Stable and Attracting Fixed Point (0, 1) for Normalized Weights.
// see: https://arxiv.org/abs/1706.02515
2020-11-25 14:30:53 +01:00
float scaleAlpha = ${om};
float scale = ${sm};
2020-10-11 18:41:17 +02:00
return (x >= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);
2020-11-25 14:30:53 +01:00
`;function PJ(n=0){return $s+`
return x > 0.0 ? 1.0 : float(${n});
`}let iE="return -x;",aE="return ceil(x);",cE="return floor(x);",OJ=`
2020-10-11 18:41:17 +02:00
if (isnan(x)) { return 0.0; }
return sign(x);
2020-11-25 14:30:53 +01:00
`,LJ="return float(isnan(x));",MJ="return float(isinf(x));",BJ="return float(!isnan(x) && !isinf(x));",zJ=`
2020-10-11 18:41:17 +02:00
// OpenGL ES does not support round function.
// The algorithm is based on banker's rounding.
float base = floor(x);
if ((x - base) < 0.5) {
return floor(x);
} else if ((x - base) > 0.5) {
return ceil(x);
} else {
if (mod(base, 2.0) == 0.0) {
return base;
} else {
return base + 1.0;
}
}
2020-11-25 14:30:53 +01:00
`,lE="return exp(x);",uE="return exp(x) - 1.0;",WJ=`if (x < 0.0) return NAN;
return log(x);`,VJ="return log(1.0 + x);",GJ="return sqrt(x);",UJ="return inversesqrt(x);",qJ="return 1.0 / (1.0 + exp(-1.0 * x));",HJ=`
2020-10-11 18:41:17 +02:00
float epsilon = 1.1920928955078125e-7;
float threshold = log(epsilon) + 2.0;
bool too_large = x > -threshold;
bool too_small = x < threshold;
float result;
float exp_x = exp(x);
if (too_large){
result = x;
}
else if (too_small){
result = exp_x;
}
else{
result = log(exp_x + 1.0);
}
return result;
2020-11-25 14:30:53 +01:00
`,jJ=$s+`
2020-10-11 18:41:17 +02:00
if (abs(x) > 1.) {
return NAN;
}
return asin(x);
2020-11-25 14:30:53 +01:00
`,KJ=$s+`
2020-10-11 18:41:17 +02:00
if (abs(x) > 1.) {
return NAN;
}
return acos(x);
2020-11-25 14:30:53 +01:00
`,XJ=$s+`
2020-10-11 18:41:17 +02:00
return atan(x);
2020-11-25 14:30:53 +01:00
`,YJ=`
2020-10-11 18:41:17 +02:00
float e2x = exp(x);
return (e2x - 1.0 / e2x) / 2.0;
2020-11-25 14:30:53 +01:00
`,JJ=`
2020-10-11 18:41:17 +02:00
float e2x = exp(-x);
return (e2x + 1.0 / e2x) / 2.0;
2020-11-25 14:30:53 +01:00
`,ZJ=`
2020-10-11 18:41:17 +02:00
float e2x = exp(-2.0 * abs(x));
return sign(x) * (1.0 - e2x) / (1.0 + e2x);
2020-11-25 14:30:53 +01:00
`,QJ=$s+"return log(x + sqrt(x * x + 1.0));",tZ=$s+`
2020-10-11 18:41:17 +02:00
if (x < 1.0) return NAN;
2020-11-25 14:30:53 +01:00
return log(x + sqrt(x * x - 1.0));`,eZ=$s+`
2020-10-11 18:41:17 +02:00
if ((x < -1.0) || (x > 1.0)) return NAN;
2020-11-25 14:30:53 +01:00
return (log(1.0 + x) - log(1.0 - x)) / 2.0;`,nZ=`
2020-10-11 18:41:17 +02:00
// Error function is calculated approximately with elementary function.
// See "Handbook of Mathematical Functions with Formulas,
// Graphs, and Mathematical Tables", Abramowitz and Stegun.
2020-11-25 14:30:53 +01:00
float p = ${fv};
float a1 = ${dv};
float a2 = ${mv};
float a3 = ${gv};
float a4 = ${yv};
float a5 = ${bv};
2020-10-11 18:41:17 +02:00
float sign = sign(x);
x = abs(x);
float t = 1.0 / (1.0 + p * x);
return sign * (1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x));
2020-11-25 14:30:53 +01:00
`,rZ="return 1.0 / x;",oZ="return float(!(x >= 1.0));",rg="return x;";let sZ="return x;",iZ=`
2020-10-11 18:41:17 +02:00
vec4 result = log(x);
vec4 isNaN = vec4(lessThan(x, vec4(0.0)));
result.r = isNaN.r == 1.0 ? NAN : result.r;
result.g = isNaN.g == 1.0 ? NAN : result.g;
result.b = isNaN.b == 1.0 ? NAN : result.b;
result.a = isNaN.a == 1.0 ? NAN : result.a;
return result;
2020-11-25 14:30:53 +01:00
`,pE=`
2020-10-11 18:41:17 +02:00
vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));
bvec4 isNaN = isnan(x);
result.r = isNaN.r ? x.r : result.r;
result.g = isNaN.g ? x.g : result.g;
result.b = isNaN.b ? x.b : result.b;
result.a = isNaN.a ? x.a : result.a;
return result;
2020-11-25 14:30:53 +01:00
`,hE=`
2020-10-11 18:41:17 +02:00
vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0)));
bvec4 isNaN = isnan(x);
result.r = isNaN.r ? x.r : result.r;
result.g = isNaN.g ? x.g : result.g;
result.b = isNaN.b ? x.b : result.b;
result.a = isNaN.a ? x.a : result.a;
return result;
2020-11-25 14:30:53 +01:00
`,fE=`
2020-10-11 18:41:17 +02:00
vec4 result;
result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);
result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);
result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);
result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);
return result;
2020-11-25 14:30:53 +01:00
`;class dh{constructor(t,e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
vec4 unaryOperation(vec4 x) {
2020-11-25 14:30:53 +01:00
${e}
2020-10-11 18:41:17 +02:00
}
void main() {
vec4 x = getAAtOutCoords();
vec4 y = unaryOperation(x);
setOutput(y);
}
2020-11-25 14:30:53 +01:00
`}}class aZ{constructor(t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!1,this.outputShape=t;let e=t.length,r=Jn("rc",e),o=Oe(e),s=YX(e,r),c=r.slice(-2),l=e<=1?"rc":`vec2(${c.join(",")})`;this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${o} rc = getOutputCoords();
vec4 packedInput = getA(${s});
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
setOutput(getChannel(packedInput, ${l}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}let{segment_util:dE}=vv,cZ=Tv,lZ=kv,uZ=Nv,pZ=jd,hZ=1e-7,fZ=1e-4,og={};function dZ(n){return n in og||(og[n]={}),og[n]}function sg(n,t=!1){if(n==="linear")return t?sZ:FJ;if(n==="relu")return t?pE:rE;if(n==="elu")return t?fE:sE;if(n==="relu6")return t?hE:oE;if(n==="prelu")return t?LI:OI;throw new Error(`Activation ${n} has not been implemented for the WebGL backend.`)}let mZ=128,gZ=600;function yZ(){return ct().global.screen==null?1024:ct().global.screen.height*ct().global.screen.width*window.devicePixelRatio*gZ/1024/1024}let mE=1e3;class bZ extends d{constructor(t){super();if(this.pendingRead=new WeakMap,this.pendingDisposal=new WeakSet,this.dataRefCount=new WeakMap,this.numBytesInGPU=0,this.uploadWaitMs=0,this.downloadWaitMs=0,this.warnedAboutMemory=!1,this.warnedAboutCPUBackend=!1,this.pendingDeletes=0,this.disposed=!1,!ct().getBool("HAS_WEBGL"))throw new Error("WebGL is not supported on this device");if(t==null){let e=Xo(ct().getNumber("WEBGL_VERSION"));this.binaryCache=dZ(ct().getNumber("WEBGL_VERSION")),this.gpgpu=new j7(e),this.canvas=e.canvas,this.gpgpuCreatedLocally=!0}else this.gpgpu=t,this.binaryCache={},this.gpgpuCreatedLocally=!1,this.canvas=t.gl.canvas;this.textureManager=new SJ(this.gpgpu),this.numMBBeforeWarning=yZ(),this.texData=new h(this,ds())}numDataIds(){return this.texData.numDataIds()+(this.cpuBackend?this.cpuBackend.numDataIds():0)-this.pendingDeletes}write(t,e,r){if((ct().getBool("WEBGL_CHECK_NUMERICAL_PROBLEMS")||ct().getBool("DEBUG"))&&this.checkNumericalProblems(t),r==="complex64"&&t!=null)throw new Error("Cannot write to a complex64 dtype. Please use tf.complex(real, imag).");let o={};return this.texData.set(o,{shape:e,dtype:r,values:t,usage:Br.UPLOAD,refCount:1,complexParentRefCount:0}),o}incRef(t){let e=this.texData.get(t);e.refCount++}decRef(t){if(this.texData.has(t)){let e=this.texData.get(t);e.refCount--}}move(t,e,r,o){if(ct().getBool("DEBUG")&&this.checkNumericalProblems(e),o==="complex64")throw new Error("Cannot write to a complex64 dtype. Please use tf.complex(real, imag).");this.texData.set(t,{shape:r,dtype:o,values:e,usage:Br.UPLOAD,refCount:1,complexParentRefCount:0})}disposeIntermediateTensorInfo(t){let e=t.dataId;if(this.texData.has(e)){let r=this.texData.get(e);r.refCount--,r.refCount<1&&this.disposeData(e)}}readSync(t){let e=this.texData.get(t),{values:r,dtype:o,complexTensorInfos:s,slice:c,shape:l,isPacked:p}=e;if(c!=null){let b;p?b=new dh(l,rg):b=new ue(l,rg);let v=this.runWebGLProgram(b,[{dataId:t,shape:l,dtype:o}],o),T=this.readSync(v.dataId);return this.disposeIntermediateTensorInfo(v),T}if(r!=null)return this.convertAndCacheOnCPU(t);if(o==="string")return r;let f=this.activeTimers!=null,m;f&&(m=sr());let y;if(o==="complex64"){let b=this.readSync(s.real.dataId),v=this.readSync(s.imag.dataId);y=ws(b,v)}else y=this.getValuesFromTexture(t);return f&&(this.downloadWaitMs+=sr()-m),this.convertAndCacheOnCPU(t,y)}async read(t){if(this.pendingRead.has(t)){let T=this.pendingRead.get(t);return new Promise(N=>T.push(N))}let e=this.texData.get(t),{values:r,shape:o,slice:s,dtype:c,complexTensorInfos:l,isPacked:p}=e;if(s!=null){let T;p?T=new dh(o,rg):T=new ue(o,rg);let N=this.runWebGLProgram(T,[{dataId:t,shape:o,dtype:c}],c),S=this.read(N.dataId);return this.disposeIntermediateTensorInfo(N),S}if(r!=null)return this.convertAndCacheOnCPU(t);if(!ct().getBool("WEBGL_DOWNLOAD_FLOAT_ENABLED")&&ct().getNumber("WEBGL_VERSION")===2)throw new Error("tensor.data() with WEBGL_DOWNLOAD_FLOAT_ENABLED=false and WEBGL_VERSION=2 not yet supported.");let f=null,m;if(c!=="complex64"&&ct().get("WEBGL_BUFFER_SUPPORTED")){m=this.decode(t);let T=this.texData.get(m.dataId);f=this.gpgpu.createBufferFromTexture(T.texture,...uh(o))}this.pendingRead.set(t,[]),c!=="complex64"&&await this.gpgpu.createAndWaitForFence();let y;if(c==="complex64"){let T=await Promise.all([this.read(l.real.dataId),this.read(l.imag.dataId)]),N=T[0],S=T[1];y=ws(N,S)}else if(f==null)y=this.getValuesFromTexture(t);else{let T=G(o);y=this.gpgpu.downloadFloat32MatrixFromBuffer(f,T)}m!=null&&this.disposeIntermediateTensorInfo(m);let b=this
2020-10-11 18:41:17 +02:00
if (isnan(a)) return a;
if (isnan(b)) return b;
2020-11-25 14:30:53 +01:00
`,_Z=`
2020-10-11 18:41:17 +02:00
result.r = isNaN.r > 0. ? NAN : result.r;
result.g = isNaN.g > 0. ? NAN : result.g;
result.b = isNaN.b > 0. ? NAN : result.b;
result.a = isNaN.a > 0. ? NAN : result.a;
2020-11-25 14:30:53 +01:00
`;function ig(n){return({inputs:t,backend:e})=>{let{x:r}=t,o=e,s=new ue(r.shape,n);return o.runWebGLProgram(s,[r],r.dtype)}}function vl({opSnippet:n,packedOpSnippet:t,checkOutOfBounds:e=!1,supportsComplex:r=!1,cpuKernelImpl:o,dtype:s}){return({inputs:c,backend:l})=>{let{a:p,b:f}=c,m=l;if(r&&p.dtype==="complex64"){let T=m.texData.get(p.dataId),N=m.texData.get(f.dataId),[S,D]=[[T.complexTensorInfos.real,N.complexTensorInfos.real],[T.complexTensorInfos.imag,N.complexTensorInfos.imag]].map(P=>{let[E,L]=P,B={dataId:E.dataId,dtype:E.dtype,shape:p.shape},q={dataId:L.dataId,dtype:L.dtype,shape:f.shape},H=new Hn(n,p.shape,f.shape);return m.runWebGLProgram(H,[B,q],Kn(E.dtype,L.dtype))}),I=wl({inputs:{real:S,imag:D},backend:m});return m.disposeIntermediateTensorInfo(S),m.disposeIntermediateTensorInfo(D),I}let y=s||Kn(p.dtype,f.dtype);if(m.shouldExecuteOnCPU([p,f])&&o!=null){let T=m.texData.get(p.dataId),N=m.texData.get(f.dataId),[S,D]=o(p.shape,f.shape,T.values,N.values,y),I=m.makeTensorInfo(D,y),P=m.texData.get(I.dataId);return P.values=S,I}let b=ct().getBool("WEBGL_PACK_BINARY_OPERATIONS")&&t!=null,v;return b?v=new Ss(t,p.shape,f.shape,e):v=new Hn(n,p.shape,f.shape),m.runWebGLProgram(v,[p,f],y)}}let yE="return a + b;",CZ=vl({opSnippet:yE,packedOpSnippet:yE,supportsComplex:!0,cpuKernelImpl:PX}),SZ={kernelName:Zi,backendName:"webgl",kernelFunc:CZ};let $Z=NZ+`
2020-10-11 18:41:17 +02:00
return atan(a, b);
2020-11-25 14:30:53 +01:00
`,IZ=`
2020-10-11 18:41:17 +02:00
vec4 result = atan(a, b);
vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));
2020-11-25 14:30:53 +01:00
`+_Z+`
2020-10-11 18:41:17 +02:00
return result;
2020-11-25 14:30:53 +01:00
`,EZ=vl({opSnippet:$Z,packedOpSnippet:IZ}),DZ={kernelName:Nf,backendName:"webgl",kernelFunc:EZ};function AZ(n){let{inputs:t,backend:e,attrs:r}=n,{x:o}=t;ph(o,"avgPool");let{filterSize:s,strides:c,pad:l,dimRoundingMode:p}=r,f=1;_(fn(c,f),()=>`Error in avgPool: Either strides or dilations must be 1. Got strides ${c} and dilations '${f}'`);let m=Xn(o.shape,s,c,f,l,p);if(m.filterWidth===1&&m.filterHeight===1&&lt(m.inShape,m.outShape))return Is({inputs:{x:o},backend:e});let y=new fh(m,"avg",!1);return e.runWebGLProgram(y,[o],"float32")}let FZ={kernelName:fu,backendName:"webgl",kernelFunc:AZ};function RZ(n){let{inputs:t,backend:e,attrs:r}=n,{dy:o,input:s}=t,c=s;ph([o,s],"avgPoolBackprop");let{filterSize:l,strides:p,pad:f}=r,m=Xn(c.shape,l,p,1,f),y=new RY(m);return e.runWebGLProgram(y,[o],c.dtype)}let PZ={kernelName:_f,backendName:"webgl",kernelFunc:RZ};class OZ{constructor(t,e,r,o,s,c){this.outputShape=[],this.variableNames=["x","mean","variance"],le(t,e),le(t,r);let l="0.0";o!=null&&(le(t,o),this.variableNames.push("offset"),l="getOffsetAtOutCoords()");let p="1.0";s!=null&&(le(t,s),this.variableNames.push("scale"),p="getScaleAtOutCoords()"),this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
float x = getXAtOutCoords();
float mean = getMeanAtOutCoords();
float variance = getVarianceAtOutCoords();
2020-11-25 14:30:53 +01:00
float offset = ${l};
float scale = ${p};
float inv = scale * inversesqrt(variance + float(${c}));
2020-10-11 18:41:17 +02:00
setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1)));
}
2020-11-25 14:30:53 +01:00
`}}class LZ{constructor(t,e,r,o,s,c){this.packedInputs=!0,this.packedOutput=!0,this.variableNames=["x","mean","variance"],le(t,e),le(t,r);let l="vec4(0.0)";o!=null&&(le(t,o),this.variableNames.push("offset"),l="getOffsetAtOutCoords()");let p="vec4(1.0)";s!=null&&(le(t,s),this.variableNames.push("scale"),p="getScaleAtOutCoords()"),this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
vec4 offset = ${l};
vec4 scale = ${p};
2020-10-11 18:41:17 +02:00
vec4 x = getXAtOutCoords();
vec4 mean = getMeanAtOutCoords();
vec4 variance = getVarianceAtOutCoords();
2020-11-25 14:30:53 +01:00
vec4 inv = scale * inversesqrt(variance + vec4(${c}));
2020-10-11 18:41:17 +02:00
setOutput((x - mean) * inv + offset);
}
2020-11-25 14:30:53 +01:00
`}}let MZ=({inputs:n,backend:t,attrs:e})=>{let{x:r,mean:o,variance:s,offset:c,scale:l}=n;_(o.shape.length===s.shape.length,()=>"Batch normalization gradient requires mean and variance to have equal ranks."),_(c==null||o.shape.length===c.shape.length,()=>"Batch normalization gradient requires mean and offset to have equal ranks."),_(l==null||o.shape.length===l.shape.length,()=>"Batch normalization gradient requires mean and scale to have equal ranks.");let{varianceEpsilon:p}=e;p==null&&(p=.001);let f=[r,o,s],m=null;c!=null&&(m=c.shape,f.push(c));let y=null;l!=null&&(y=l.shape,f.push(l));let b=ct().getBool("WEBGL_PACK_NORMALIZATION")?new LZ(r.shape,o.shape,s.shape,m,y,p):new OZ(r.shape,o.shape,s.shape,m,y,p),v=t.runWebGLProgram(b,f,f[0].dtype);return v},BZ={kernelName:ku,backendName:"webgl",kernelFunc:MZ};let zZ="return float(a != b);",bE=vl({opSnippet:zZ,dtype:"bool"}),WZ={kernelName:Fu,backendName:"webgl",kernelFunc:bE};function B1(n){let{inputs:t,backend:e}=n,{input:r}=t,o=e.texData.get(r.dataId);return Is({inputs:{x:o.complexTensorInfos.real},backend:e})}let VZ={kernelName:Hf,backendName:"webgl",kernelFunc:B1};let GZ="return float(int(x));";function UZ(n,t){let e=new ue(n.shape,GZ),r=t.runWebGLProgram(e,[n],"int32");return{dataId:r.dataId,shape:r.shape,dtype:r.dtype}}function z1(n){let{inputs:t,backend:e,attrs:r}=n,{x:o}=t,{dtype:s}=r;if(s==="complex64"){if(o.dtype==="complex64")return Is({inputs:{x:o},backend:e});let c=xe(o.shape),l=z1({inputs:{x:o},backend:e,attrs:{dtype:"float32"}}),p=wl({inputs:{real:l,imag:c},backend:e});return c.dispose(),e.disposeIntermediateTensorInfo(l),p}if(o.dtype==="complex64"){let c=B1({inputs:{input:o},backend:e}),l=z1({inputs:{x:c},backend:e,attrs:{dtype:s}});return e.disposeIntermediateTensorInfo(c),l}if(!gc(o.dtype,s)){let c=Is({inputs:{x:o},backend:e});return{dataId:c.dataId,shape:c.shape,dtype:s}}if(s==="int32")return UZ(o,e);if(s==="bool"){let c=e.makeTensorInfo([],"bool",Ce("bool",1)),l={a:o,b:c},p=bE({inputs:l,backend:e});return e.disposeIntermediateTensorInfo(c),p}throw new Error(`Error in Cast: failed to cast ${o.dtype} to ${s}`)}let qZ={kernelName:xc,backendName:"webgl",kernelFunc:z1};class HZ{constructor(t){this.outputShape=[],this.outputShape=ms(t,1),this.variableNames=t.map((c,l)=>`T${l}`);let e=new Array(t.length-1);e[0]=t[0][1];for(let c=1;c<e.length;c++)e[c]=e[c-1]+t[c][1];let r=[`if (yC < ${e[0]}) setOutput(getT0(yR, yC));`];for(let c=1;c<e.length;c++){let l=e[c-1];r.push(`else if (yC < ${e[c]}) setOutput(getT${c}(yR, yC-${l}));`)}let o=e.length,s=e[e.length-1];r.push(`else setOutput(getT${o}(yR, yC-${s}));`),this.userCode=`
2020-10-29 05:16:50 +01:00
void main() {
ivec2 coords = getOutputCoords();
int yR = coords.x;
int yC = coords.y;
2020-11-25 14:30:53 +01:00
${r.join(`
2020-10-29 05:16:50 +01:00
`)}
}
2020-11-25 14:30:53 +01:00
`}}class jZ{constructor(t,e){this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[],this.outputShape=ms(t,e);let r=this.outputShape,o=r.length,s=Oe(o),c=Jn("coords",o),l=["x","y","z","w","u","v"].slice(0,o);this.variableNames=t.map((N,S)=>`T${S}`);let p=new Array(t.length-1);p[0]=t[0][e];for(let N=1;N<p.length;N++)p[N]=p[N-1]+t[N][e];let f=l[e],m=l.slice(-2),y=l.join(),b=`if (${f} < ${p[0]}) {
2020-10-29 05:16:50 +01:00
return getChannel(
2020-11-25 14:30:53 +01:00
getT0(${y}), vec2(${m.join()}));
}`;for(let N=1;N<p.length;N++){let S=p[N-1];b+=`
if (${f} < ${p[N]} && ${f} >= ${p[N-1]}) {
2020-10-29 05:16:50 +01:00
return getChannel(
2020-11-25 14:30:53 +01:00
getT${N}(${ag(l,f,S)}),
vec2(${ag(m,f,S)}));
}`}let v=p.length,T=p[p.length-1];b+=`
2020-10-29 05:16:50 +01:00
return getChannel(
2020-11-25 14:30:53 +01:00
getT${v}(${ag(l,f,T)}),
vec2(${ag(m,f,T)}));`,this.userCode=`
float getValue(${l.map(N=>"int "+N)}) {
${b}
2020-10-29 05:16:50 +01:00
}
void main() {
2020-11-25 14:30:53 +01:00
${s} coords = getOutputCoords();
vec4 result = vec4(getValue(${c}), 0., 0., 0.);
2020-10-29 05:16:50 +01:00
2020-11-25 14:30:53 +01:00
${c[o-1]} = ${c[o-1]} + 1;
if (${c[o-1]} < ${r[o-1]}) {
result.g = getValue(${c});
2020-10-29 05:16:50 +01:00
}
2020-11-25 14:30:53 +01:00
${c[o-2]} = ${c[o-2]} + 1;
if (${c[o-2]} < ${r[o-2]}) {
result.a = getValue(${c});
2020-10-29 05:16:50 +01:00
}
2020-11-25 14:30:53 +01:00
${c[o-1]} = ${c[o-1]} - 1;
if (${c[o-2]} < ${r[o-2]} &&
${c[o-1]} < ${r[o-1]}) {
result.b = getValue(${c});
2020-10-29 05:16:50 +01:00
}
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}function ag(n,t,e){let r=n.indexOf(t),o=n.map((s,c)=>c===r?`${s} - ${e}`:s);return o.join()}function xE(n){let{inputs:t,backend:e}=n,{input:r}=t,o=e.texData.get(r.dataId);return Is({inputs:{x:o.complexTensorInfos.imag},backend:e})}let KZ={kernelName:Mf,backendName:"webgl",kernelFunc:xE};function XZ(n,t,e){let r=[dl(n.shape),...ml(n.shape)],o={dtype:n.dtype,shape:r,dataId:n.dataId},s=[dl(t),...ml(t)],c=new JI(s,r),l=!0,p=e.runWebGLProgram(c,[o],n.dtype,null,l);return{dataId:p.dataId,shape:t,dtype:p.dtype}}function Es(n){let{inputs:t,backend:e,attrs:r}=n,{x:o}=t,{shape:s}=r,c=e,l=G(o.shape),p=Ue(s,l),f=G(p);_(l===f,()=>`The new shape (${p}) has ${f} elements and the old shape (${o.shape}) has ${l} elements. The new shape and old shape must have the same number of elements.`);let m=c.texData.get(o.dataId);return m.isPacked&&!Zm(o.shape,p)&&!(m.texture!==null&&Zm(m.shape,p))?XZ(o,p,c):(c.incRef(o.dataId),{dataId:o.dataId,shape:p,dtype:o.dtype})}let YZ={kernelName:Ou,backendName:"webgl",kernelFunc:Es};function Tl(n,t,e){let r=n[0].dtype;if(r==="complex64"){let f=n.map(T=>B1({inputs:{input:T},backend:e})),m=n.map(T=>xE({inputs:{input:T},backend:e})),y=Tl(f,t,e),b=Tl(m,t,e),v=wl({inputs:{real:y,imag:b},backend:e});return f.forEach(T=>e.disposeIntermediateTensorInfo(T)),m.forEach(T=>e.disposeIntermediateTensorInfo(T)),e.disposeIntermediateTensorInfo(y),e.disposeIntermediateTensorInfo(b),v}if(n.length>ct().getNumber("WEBGL_MAX_TEXTURES_IN_SHADER")){let f=Math.floor(n.length/2),m=Tl(n.slice(0,f),t,e),y=Tl(n.slice(f),t,e),b=Tl([m,y],t,e);return e.disposeIntermediateTensorInfo(m),e.disposeIntermediateTensorInfo(y),b}if(ct().getBool("WEBGL_PACK_ARRAY_OPERATIONS")&&n[0].shape.length>1){let f=new jZ(n.map(m=>m.shape),t);return e.runWebGLProgram(f,n,r)}let o=ms(n.map(f=>f.shape),t),s=n.map(f=>Es({inputs:{x:f},attrs:{shape:[-1,G(f.shape.slice(t))]},backend:e})),c=new HZ(s.map(f=>f.shape)),l=e.runWebGLProgram(c,s,r);s.forEach(f=>e.disposeIntermediateTensorInfo(f));let p=Es({inputs:{x:l},attrs:{shape:o},backend:e});return e.disposeIntermediateTensorInfo(l),p}function JZ(n){let{inputs:t,backend:e,attrs:r}=n,{axis:o}=r,s=Vt(o,t[0].shape)[0],c=ms(t.map(f=>f.shape),s);if(G(c)===0)return e.makeTensorInfo(c,t[0].dtype,[]);let l=t.filter(f=>G(f.shape)>0);if(l.length===1)return l[0];let p=l.map(f=>f.shape);return Nd(p,s),Tl(l,s,e)}let ZZ={kernelName:gu,backendName:"webgl",kernelFunc:JZ};let QZ=gE+`
2020-10-11 18:41:17 +02:00
return cos(x);
2020-11-25 14:30:53 +01:00
`,t9=ig(QZ),e9={kernelName:wc,backendName:"webgl",kernelFunc:t9};let n9=`
2020-10-11 18:41:17 +02:00
if (a == b) {
return 1.0;
};
2020-11-25 14:30:53 +01:00
return a / b;`,r9=`
2020-10-11 18:41:17 +02:00
// vec4 one = vec4(equal(a, b));
// return one + (vec4(1.0) - one) * a / b;
vec4 result = a / b;
if(a.x == b.x) {
result.x = 1.;
}
if(a.y == b.y) {
result.y = 1.;
}
if(a.z == b.z) {
result.z = 1.;
}
if(a.w == b.w) {
result.w = 1.;
}
return result;
2020-11-25 14:30:53 +01:00
`,o9=vl({opSnippet:n9,packedOpSnippet:r9,checkOutOfBounds:!0}),s9={kernelName:vc,backendName:"webgl",kernelFunc:o9};class wE{constructor(t,e,r){this.variableNames=["real","imag"];let o=e[1];this.outputShape=e;let s=r?`2.0 * ${Math.PI}`:`-2.0 * ${Math.PI}`,c=r?`${o}.0`:"1.0",l;if(t==="real")l="return real * expR - imag * expI;";else if(t==="imag")l="return real * expI + imag * expR;";else throw new Error(`FFT component must be either "real" or "imag", got ${t}.`);this.userCode=`
const float exponentMultiplier = ${s};
2020-10-29 05:16:50 +01:00
float unaryOpComplex(float real, float expR, float imag, float expI) {
2020-11-25 14:30:53 +01:00
${l}
2020-10-29 05:16:50 +01:00
}
float mulMatDFT(int batch, int index) {
2020-11-25 14:30:53 +01:00
float indexRatio = float(index) / float(${o});
2020-10-29 05:16:50 +01:00
float exponentMultiplierTimesIndexRatio =
exponentMultiplier * indexRatio;
float result = 0.0;
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${o}; i++) {
2020-10-29 05:16:50 +01:00
// x = (-2|2 * PI / N) * index * i;
float x = exponentMultiplierTimesIndexRatio * float(i);
float expR = cos(x);
float expI = sin(x);
float real = getReal(batch, i);
float imag = getImag(batch, i);
result +=
2020-11-25 14:30:53 +01:00
unaryOpComplex(real, expR, imag, expI) / ${c};
2020-10-29 05:16:50 +01:00
}
return result;
}
void main() {
ivec2 coords = getOutputCoords();
setOutput(mulMatDFT(coords[0], coords[1]));
}
2020-11-25 14:30:53 +01:00
`}}function vE(n,t,e){let r=e.texData.get(n.dataId),o=G(n.shape),s=n.shape[n.shape.length-1],c=o/s,l=Es({inputs:{x:n},backend:e,attrs:{shape:[c,s]}}),p=l.shape,f=new wE("real",p,t),m=new wE("imag",p,t),y=[{dataId:r.complexTensorInfos.real.dataId,dtype:r.complexTensorInfos.real.dtype,shape:p},{dataId:r.complexTensorInfos.imag.dataId,dtype:r.complexTensorInfos.imag.dtype,shape:p}],b=e.runWebGLProgram(f,y,"float32"),v=e.runWebGLProgram(m,y,"float32"),T=wl({inputs:{real:b,imag:v},backend:e});e.disposeIntermediateTensorInfo(b),e.disposeIntermediateTensorInfo(v);let N=Es({inputs:{x:T},backend:e,attrs:{shape:n.shape}});return e.disposeIntermediateTensorInfo(N),N}function i9(n){let{inputs:t,backend:e}=n,{input:r}=t;return vE(r,!1,e)}let a9={kernelName:Pf,backendName:"webgl",kernelFunc:i9};class c9{constructor(t){this.variableNames=["Image"],this.outputShape=[];let e=t[2];this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec4 coords = getOutputCoords();
int x = coords[2];
2020-11-25 14:30:53 +01:00
int coordX = ${e} - x;
2020-10-11 18:41:17 +02:00
float outputValue;
2020-11-25 14:30:53 +01:00
if(coordX >= 0 && coordX < ${e}) {
2020-10-11 18:41:17 +02:00
outputValue = getImage(coords[0], coords[1], coordX, coords[3]);
} else {
outputValue = getImage(coords[0], coords[1], coords[2], coords[3]);
}
setOutput(outputValue);
}
2020-11-25 14:30:53 +01:00
`}}let l9={kernelName:Of,backendName:"webgl",kernelFunc:({inputs:n,backend:t})=>{let{image:e}=n,r=t,o=new c9(e.shape),s=r.runWebGLProgram(o,[e],e.dtype);return s}};class u9{constructor(t){this.variableNames=["A"];let e=Zn(),[r,o]=t;this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec3 coords = getOutputCoords();
int texR = coords[0];
int texC = coords[1];
int depth = coords[2];
2020-11-25 14:30:53 +01:00
vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${o}.0, ${r}.0);
2020-10-11 18:41:17 +02:00
2020-11-25 14:30:53 +01:00
vec4 values = ${e.texture2D}(A, uv);
2020-10-11 18:41:17 +02:00
float value;
if (depth == 0) {
value = values.r;
} else if (depth == 1) {
value = values.g;
} else if (depth == 2) {
value = values.b;
} else if (depth == 3) {
value = values.a;
}
setOutput(floor(value * 255.0 + 0.5));
}
2020-11-25 14:30:53 +01:00
`}}class p9{constructor(t){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0;let e=Zn(),[r,o]=t;this.outputShape=t,this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
ivec3 coords = getOutputCoords();
int texR = coords[0];
int texC = coords[1];
int depth = coords[2];
vec4 result = vec4(0.);
for(int row=0; row<=1; row++) {
for(int col=0; col<=1; col++) {
texC = coords[1] + row;
depth = coords[2] + col;
vec2 uv = (vec2(texC, texR) + halfCR) /
2020-11-25 14:30:53 +01:00
vec2(${o}.0, ${r}.0);
vec4 values = ${e.texture2D}(A, uv);
2020-10-11 18:41:17 +02:00
float value;
if (depth == 0) {
value = values.r;
} else if (depth == 1) {
value = values.g;
} else if (depth == 2) {
value = values.b;
} else if (depth == 3) {
value = values.a;
}
result[row * 2 + col] = floor(value * 255.0 + 0.5);
}
}
2020-11-25 14:30:53 +01:00
${e.output} = result;
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}let h9={kernelName:Jf,backendName:"webgl",kernelFunc:f9},kl;function f9(n){let{inputs:t,backend:e,attrs:r}=n,{pixels:o}=t,{numChannels:s}=r,c=typeof HTMLVideoElement!="undefined"&&o instanceof HTMLVideoElement,l=typeof HTMLImageElement!="undefined"&&o instanceof HTMLImageElement,[p,f]=c?[o.videoWidth,o.videoHeight]:[o.width,o.height],m=[f,p],y=[f,p,s];(l||c)&&(kl==null&&(kl=document.createElement("canvas").getContext("2d")),kl.canvas.width=p,kl.canvas.height=f,kl.drawImage(o,0,0,p,f),o=kl.canvas);let b=e.makeTensorInfo(m,"int32");e.texData.get(b.dataId).usage=Br.PIXELS,e.gpgpu.uploadPixelDataToTexture(e.getTexture(b.dataId),o);let v=ct().getBool("WEBGL_PACK")?new p9(y):new u9(y),T=e.runWebGLProgram(v,[b],"int32");return e.disposeData(b.dataId),T}function d9(n){let{inputs:t,backend:e}=n,{input:r}=t;return vE(r,!0,e)}let m9={kernelName:Lf,backendName:"webgl",kernelFunc:d9};class TE{constructor(t,e){this.variableNames=["x"];let{windowSize:r,batchSize:o,inSize:s,outSize:c}=t;this.outputShape=[o,c];let l=Math.floor(r/4)*4,p=r%4,f="sumValue += dot(values, ones);";if(e!=null){let y=1/e;f=`sumValue += dot(values * ${gt(y)?y.toPrecision(2):y}, ones);`}let m="";s%r>0&&(m=`
if (inIdx < 0 || inIdx >= ${s}) {
2020-10-29 05:16:50 +01:00
return 0.0;
}
`),this.userCode=`
const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);
float getValue(int batch, int inIdx) {
2020-11-25 14:30:53 +01:00
${m}
2020-10-29 05:16:50 +01:00
return getX(batch, inIdx);
}
void main() {
ivec2 coords = getOutputCoords();
int batch = coords[0];
int outIdx = coords[1];
2020-11-25 14:30:53 +01:00
int inOffset = outIdx * ${r};
2020-10-29 05:16:50 +01:00
float sumValue = 0.0;
2020-11-25 14:30:53 +01:00
for (int i = 0; i < ${l}; i += 4) {
2020-10-29 05:16:50 +01:00
int inIdx = inOffset + i;
vec4 values = vec4(
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
getValue(batch, inIdx + 2),
getValue(batch, inIdx + 3)
);
2020-11-25 14:30:53 +01:00
${f}
2020-10-29 05:16:50 +01:00
}
2020-11-25 14:30:53 +01:00
int inIdx = inOffset + ${l};
if (${p===1}) {
2020-10-29 05:16:50 +01:00
vec4 values = vec4(getValue(batch, inIdx), 0.0, 0.0, 0.0);
2020-11-25 14:30:53 +01:00
${f}
} else if (${p===2}) {
2020-10-29 05:16:50 +01:00
vec4 values = vec4(
getValue(batch, inIdx),
getValue(batch, inIdx + 1), 0.0, 0.0);
2020-11-25 14:30:53 +01:00
${f}
} else if (${p===3}) {
2020-10-29 05:16:50 +01:00
vec4 values = vec4(
getValue(batch, inIdx),
getValue(batch, inIdx + 1),
getValue(batch, inIdx + 2), 0.0);
2020-11-25 14:30:53 +01:00
${f}
2020-10-29 05:16:50 +01:00
}
setOutput(sumValue);
}
2020-11-25 14:30:53 +01:00
`}}function g9(n){let t=[];for(;t.length===0||t[t.length-1].outSize!==1;){let e=t.length?t[t.length-1].outSize:n[1],r=pp(e);t.push({inSize:e,windowSize:r,outSize:Math.ceil(e/r)})}return t}function kE(n,t,e,r){let o=g9(n.shape),s=n;for(let c=0;c<o.length;c++){let{inSize:l,windowSize:p,outSize:f}=o[c],m,y;e==="mean"?m=c===0?new TE({windowSize:p,inSize:l,batchSize:n.shape[0],outSize:f},l):new TE({windowSize:p,inSize:l,batchSize:n.shape[0],outSize:f}):m=new YI({windowSize:p,inSize:l,batchSize:n.shape[0],outSize:f},e),y=s,s=r.runWebGLProgram(m,[s],t),y.dataId!==n.dataId&&r.disposeIntermediateTensorInfo(y)}return s}function y9(n,t,e,r){let o=G(t),s=G(n.shape),c=s/o,l=Es({inputs:{x:n},attrs:{shape:[c,o]},backend:r}),p=kE(l,n.dtype,"max",r),f=Es({inputs:{x:p},attrs:{shape:e},backend:r});return r.disposeIntermediateTensorInfo(l),r.disposeIntermediateTensorInfo(p),f}class b9{constructor(t,e){this.variableNames=["A"];let r=new Array(t.length);for(let c=0;c<r.length;c++)r[c]=t[e[c]];this.outputShape=r,this.rank=r.length;let o=Oe(this.rank),s=x9(e);this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${o} resRC = getOutputCoords();
setOutput(getA(${s}));
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
`}}function x9(n){let t=n.length;if(t>6)throw Error(`Transpose for rank ${t} is not yet supported`);let e=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u","resRC.v"],r=new Array(t);for(let o=0;o<n.length;o++)r[n[o]]=e[o];return r.join()}class w9{constructor(t,e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0;let r=new Array(t.length);for(let m=0;m<r.length;m++)r[m]=t[e[m]];if(this.outputShape=r,this.rank=r.length,this.rank>6)throw Error(`Packed transpose for rank ${this.rank} is not yet supported.`);let o=Oe(this.rank),s=EI("rc",this.rank),c=new Array(this.rank);for(let m=0;m<e.length;m++)c[e[m]]=s[m];let l=`vec2(${c.slice(-2).join()})`,p=`++${s[this.rank-1]} < ${r[this.rank-1]}`,f=`getChannel(getA(${c.join()}), ${l})`;this.userCode=`
2020-10-11 18:41:17 +02:00
void main() {
2020-11-25 14:30:53 +01:00
${o} rc = getOutputCoords();
2020-10-11 18:41:17 +02:00
vec4 result = vec4(0.);
2020-11-25 14:30:53 +01:00
result[0] = ${f};
if(${p}) {
result[1] = ${f};
2020-10-11 18:41:17 +02:00
}
2020-11-25 14:30:53 +01:00
--${s[this.rank-1]};
if(++${s[this.rank-2]} < ${r[this.rank-2]}) {
result[2] = ${f};
if(${p}) {
result[3] = ${f};
2020-10-11 18:41:17 +02:00
}
}
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}function W1(n,t,e){let r=ct().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new w9(n.shape,t):new b9(n.shape,t);return e.runWebGLProgram(r,[n],n.dtype)}let v9={kernelName:Eu,backendName:"webgl",kernelFunc:({inputs:n,attrs:t,backend:e})=>{let{x:r}=n,{reductionIndices:o,keepDims:s}=t,c=e,l=r.shape.length,p=Vt(o,r.shape),f=p,m=ar(f,l),y=m!=null,b=c.shouldExecuteOnCPU([r]),v=r;if(y){if(b){let I=c.texData.get(v.dataId),P=I.values,E=new Array(l);for(let q=0;q<E.length;q++)E[q]=r.shape[m[q]];let L=R1(P,r.shape,r.dtype,m,E);v=c.makeTensorInfo(E,r.dtype);let B=c.texData.get(v.dataId);B.values=L}else v=W1(r,m,c);f=xr(f.length,l)}ir("max",f,l);let[T,N]=Rn(v.shape,f),S=T;s&&(S=Pn(T,p));let D;if(b){let I=c.texData.get(v.dataId),P=I.values,E=WX(P,G(N),S,r.dtype);D=c.makeTensorInfo(S,r.dtype);let L=c.texData.get(D.dataId);L.values=E}else D=y9(v,N,S,c);return y&&c.disposeIntermediateTensorInfo(v),D}};function T9(n){let{inputs:t,backend:e,attrs:r}=n,{x:o}=t;ph(o,"maxPool");let{filterSize:s,strides:c,pad:l,dimRoundingMode:p}=r,f=1;_(fn(c,f),()=>`Error in maxPool: Either strides or dilations must be 1. Got strides ${c} and dilations '${f}'`);let m=Xn(o.shape,s,c,f,l,p);if(m.filterWidth===1&&m.filterHeight===1&&lt(m.inShape,m.outShape))return Is({inputs:{x:o},backend:e});let y=new fh(m,"max",!1);return e.runWebGLProgram(y,[o],o.dtype)}let k9={kernelName:Du,backendName:"webgl",kernelFunc:T9};function N9(n){let{inputs:t,backend:e,attrs:r}=n,{dy:o,input:s,output:c}=t,l=s;ph([s,c],"maxPoolBackprop");let{filterSize:p,strides:f,pad:m,dimRoundingMode:y}=r,b=Xn(l.shape,p,f,1,m,y),v=!0,T=new fh(b,"max",v),N=e.runWebGLProgram(T,[l],l.dtype),S=new nJ(b),D=e.runWebGLProgram(S,[o,N],l.dtype);return e.disposeIntermediateTensorInfo(N),D}let _9={kernelName:zf,backendName:"webgl",kernelFunc:N9};function C9(n,t,e,r){let o=new fh(e,"max",!1),s=r.runWebGLProgram(o,[n],"float32");o=new fh(e,"max",!0,!0,t);let c=r.runWebGLProgram(o,[n],"float32");return[s,c]}let S9={kernelName:Wf,backendName:"webgl",kernelFunc:({inputs:n,attrs:t,backend:e})=>{let{x:r}=n,{filterSize:o,strides:s,pad:c,includeBatchInIndex:l}=t,p=e;_(r.shape.length===4,()=>`Error in maxPool: input must be rank 4 but got rank ${r.shape.length}.`);let f=[1,1];_(fn(s,f),()=>`Error in maxPool: Either strides or dilations must be 1. Got strides ${s} and dilations '${f}'`);let m=Xn(r.shape,o,s,f,c),[y,b]=C9(r,l,m,p);return[y,b]}};function $9(n,t,e,r){let o=G(t),s=G(n.shape),c=s/o,l=Es({inputs:{x:n},attrs:{shape:[c,o]},backend:r}),p=kE(l,"float32","mean",r),f=Es({inputs:{x:p},attrs:{shape:e},backend:r});return r.disposeIntermediateTensorInfo(l),r.disposeIntermediateTensorInfo(p),f}let I9={kernelName:kx,backendName:"webgl",kernelFunc:({inputs:n,attrs:t,backend:e})=>{let{x:r}=n,{keepDims:o,axis:s}=t,c=e,l=r.shape.length,p=Vt(s,r.shape),f=p,m=ar(f,l),y=m!=null,b=c.shouldExecuteOnCPU([r]),v=[],T=r;if(y){if(b){let P=c.texData.get(T.dataId),E=P.values,L=new Array(l);for(let H=0;H<L.length;H++)L[H]=r.shape[m[H]];let B=R1(E,r.shape,r.dtype,m,L);T=c.makeTensorInfo(L,r.dtype);let q=c.texData.get(T.dataId);q.values=B}else T=W1(r,m,c);v.push(T),f=xr(f.length,l)}ir("sum",f,l);let[N,S]=Rn(T.shape,f),D=N;o&&(D=Pn(N,p));let I=$9(T,S,D,c);for(let P of v)c.disposeIntermediateTensorInfo(P);return I}};class E9{constructor(t,e,r){this.variableNames=["x"],this.outputShape=e.map((m,y)=>m[0]+t[y]+m[1]);let o=t.length,s=Oe(o),c=e.map(m=>m[0]).join(","),l=e.map((m,y)=>m[0]+t[y]).join(","),p=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,o),f=r==="reflect"?0:1;if(o===1){this.userCode=`
int start = ${c};
int end = ${l};
2020-10-29 05:16:50 +01:00
void main() {
int outC = getOutputCoords();
if (outC < start) {
2020-11-25 14:30:53 +01:00
outC = start * 2 - outC - ${f};
2020-10-29 05:16:50 +01:00
} else if(outC >= end) {
2020-11-25 14:30:53 +01:00
outC = (end - 1) * 2 - outC + ${f};
2020-10-29 05:16:50 +01:00
}
setOutput(getX(outC - start));
}
`;return}this.userCode=`
2020-11-25 14:30:53 +01:00
${s} start = ${s}(${c});
${s} end = ${s}(${l});
2020-10-29 05:16:50 +01:00
void main() {
2020-11-25 14:30:53 +01:00
${s} outC = getOutputCoords();
for (int i = 0; i < ${o}; i++) {
2020-10-29 05:16:50 +01:00
if (outC[i] < start[i]) {
2020-11-25 14:30:53 +01:00
outC[i] = start[i] * 2 - outC[i] - ${f};
2020-10-29 05:16:50 +01:00
} else if(outC[i] >= end[i]) {
2020-11-25 14:30:53 +01:00
outC[i] = (end[i] - 1) * 2 - outC[i] + ${f};
2020-10-29 05:16:50 +01:00
}
}
2020-11-25 14:30:53 +01:00
${s} coords = outC - start;
setOutput(getX(${p}));
2020-10-29 05:16:50 +01:00
}
2020-11-25 14:30:53 +01:00
`}}class D9{constructor(t,e,r){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e.map((T,N)=>T[0]+t[N]+T[1]);let o=t.length,s=Oe(o),c=e.map(T=>T[0]).join(","),l=e.map((T,N)=>T[0]+t[N]).join(","),p=Jn("rc",o),f=Jn("source",o),m=`${p[o-1]} < ${this.outputShape[o-1]}`,y=o===1?"source":`vec2(${f.slice(-2).join()})`,b=r==="reflect"?0:1,v="";if(o===1){let T=`
${s} source = rc;
2020-10-29 05:16:50 +01:00
if (source < start) {
2020-11-25 14:30:53 +01:00
source = start * 2 - source - ${b};
2020-10-29 05:16:50 +01:00
} else if (source >= end) {
2020-11-25 14:30:53 +01:00
source = (end - 1) * 2 - source + ${b};
2020-10-29 05:16:50 +01:00
}
source -= start;
2020-11-25 14:30:53 +01:00
`;v=`
${s} rc = outputLoc;
${T}
result[0] = getChannel(getX(${f.join()}), ${y});
${p[o-1]} += 1;
if(${m}) {
${T}
result[1] = getChannel(getX(${f.join()}), ${y});
}
`}else{let T=`
${s} source = rc;
${s} lt = ${s}(lessThan(source, start));
${s} gte = ${s}(greaterThanEqual(source, end));
${s} orig = 1 - (lt + gte);
2020-10-29 05:16:50 +01:00
source = orig * source +
2020-11-25 14:30:53 +01:00
lt * (start * 2 - source - ${b}) +
gte * ((end - 1) * 2 - source + ${b});
2020-10-29 05:16:50 +01:00
source -= start;
2020-11-25 14:30:53 +01:00
`;v=`
${s} rc = outputLoc;
${T}
result[0] = getChannel(getX(${f.join()}), ${y});
${p[o-1]} += 1;
if(${m}) {
${T}
result[1] = getChannel(getX(${f.join()}), ${y});
2020-10-29 05:16:50 +01:00
}
rc = outputLoc;
2020-11-25 14:30:53 +01:00
${p[o-2]} += 1;
if(${p[o-2]} < ${this.outputShape[o-2]}) {
${T}
result[2] = getChannel(getX(${f.join()}), ${y});
${p[o-1]} += 1;
if(${m}) {
${T}
result[3] = getChannel(getX(${f.join()}), ${y});
2020-10-29 05:16:50 +01:00
}
}
`}this.userCode=`
2020-11-25 14:30:53 +01:00
const ${s} start = ${s}(${c});
const ${s} end = ${s}(${l});
2020-10-29 05:16:50 +01:00
void main() {
2020-11-25 14:30:53 +01:00
${s} outputLoc = getOutputCoords();
2020-10-29 05:16:50 +01:00
vec4 result = vec4(0.);
2020-11-25 14:30:53 +01:00
${v}
2020-10-29 05:16:50 +01:00
setOutput(result);
}
2020-11-25 14:30:53 +01:00
`}}let A9=({inputs:n,backend:t,attrs:e})=>{let{x:r}=n,{paddings:o,mode:s}=e,c=ct().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new D9(r.shape,o,s):new E9(r.shape,o,s),l=t.runWebGLProgram(c,[r],r.dtype);return l},F9={kernelName:Au,backendName:"webgl",kernelFunc:A9};let NE={REAL:"return areal * breal - aimag * bimag;",IMAG:"return areal * bimag + aimag * breal;"};class _E{constructor(t,e,r){this.variableNames=["AReal","AImag","BReal","BImag"],this.outputShape=le(e,r),this.userCode=`
2020-10-29 05:16:50 +01:00
float binaryOpComplex(
float areal, float aimag, float breal, float bimag) {
2020-11-25 14:30:53 +01:00
${t}
2020-10-29 05:16:50 +01:00
}
void main() {
float areal = getARealAtOutCoords();
float aimag = getAImagAtOutCoords();
float breal = getBRealAtOutCoords();
float bimag = getBImagAtOutCoords();
setOutput(binaryOpComplex(areal, aimag, breal, bimag));
}
2020-11-25 14:30:53 +01:00
`}}let CE="return a * b;";function R9(n){let{inputs:t,backend:e}=n,{a:r,b:o}=t,s=Kn(r.dtype,o.dtype);if(r.dtype==="complex64"){let l=e.texData.get(r.dataId),p=e.texData.get(o.dataId),f=new _E(NE.REAL,r.shape,o.shape),m=new _E(NE.IMAG,r.shape,o.shape),y=[{dataId:l.complexTensorInfos.real.dataId,dtype:l.complexTensorInfos.real.dtype,shape:r.shape},{dataId:l.complexTensorInfos.imag.dataId,dtype:l.complexTensorInfos.imag.dtype,shape:r.shape},{dataId:p.complexTensorInfos.real.dataId,dtype:p.complexTensorInfos.real.dtype,shape:o.shape},{dataId:p.complexTensorInfos.imag.dataId,dtype:p.complexTensorInfos.imag.dtype,shape:o.shape}],b=e.runWebGLProgram(f,y,"float32"),v=e.runWebGLProgram(m,y,"float32"),T=wl({inputs:{real:b,imag:v},backend:e});return e.disposeIntermediateTensorInfo(b),e.disposeIntermediateTensorInfo(v),T}if(e.shouldExecuteOnCPU([r,o])){let l=e.texData.get(r.dataId),p=e.texData.get(o.dataId),[f,m]=VX(r.shape,o.shape,l.values,p.values,s),y=e.makeTensorInfo(m,s),b=e.texData.get(y.dataId);return b.values=f,y}let c;return ct().getBool("WEBGL_PACK_BINARY_OPERATIONS")?c=new Ss(CE,r.shape,o.shape):c=new Hn(CE,r.shape,o.shape),e.runWebGLProgram(c,[r,o],s)}let P9={kernelName:Tc,backendName:"webgl",kernelFunc:R9};let O9={kernelName:$x,backendName:"webgl",kernelFunc:({inputs:n,backend:t,attrs:e})=>{Yc("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");let{boxes:r,scores:o}=n,{maxOutputSize:s,iouThreshold:c,scoreThreshold:l}=e,p=t,f=p.readSync(r.dataId),m=p.readSync(o.dataId),y=s,b=c,v=l;return tm(f,m,y,b,v)}};let L9=em,M9={kernelName:Vf,backendName:"webgl",kernelFunc:({inputs:n,backend:t,attrs:e})=>{Yc("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");let{boxes:r,scores:o}=n,{maxOutputSize:s,iouThreshold:c,scoreThreshold:l,padToMaxOutputSize:p}=e,f=t,m=f.readSync(r.dataId),y=f.readSync(o.dataId),{selectedIndices:b,validOutputs:v}=L9(m,y,s,c,l,p);return[b,v]}};let B9=nm,z9={kernelName:Gf,backendName:"webgl",kernelFunc:({inputs:n,backend:t,attrs:e})=>{Yc("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");let{boxes:r,scores:o}=n,{maxOutputSize:s,iouThreshold:c,scoreThreshold:l,softNmsSigma:p}=e,f=t,m=f.readSync(r.dataId),y=f.readSync(o.dataId),b=s,v=c,T=l,N=p,{selectedIndices:S,selectedScores:D}=B9(m,y,b,v,T,N);return[S,D]}};class W9{constructor(t,e,r,o){this.variableNames=["Image"],this.outputShape=[];let s=t[1],c=t[2],l=Math.sin(e).toFixed(3),p=Math.cos(e).toFixed(3);this.outputShape=t;let[f,m]=uv(o,s,c),y=f.toFixed(3),b=m.toFixed(3),v="";typeof r=="number"?v=`float outputValue = ${r.toFixed(2)};`:v=`
vec3 fill = vec3(${r.join(",")});
2020-10-11 18:41:17 +02:00
float outputValue = fill[coords[3]];`,this.userCode=`
void main() {
ivec4 coords = getOutputCoords();
int x = coords[2];
int y = coords[1];
2020-11-25 14:30:53 +01:00
float coordXFloat = (float(x) - ${y}) * ${p} - (float(y) - ${b}) * ${l};
float coordYFloat = (float(x) - ${y}) * ${l} + (float(y) - ${b}) * ${p};
int coordX = int(round(coordXFloat + ${y}));
int coordY = int(round(coordYFloat + ${b}));
${v}
if(coordX >= 0 && coordX < ${c} && coordY >= 0 && coordY < ${s}) {
2020-10-11 18:41:17 +02:00
outputValue = getImage(coords[0], coordY, coordX, coords[3]);
}
setOutput(outputValue);
}
2020-11-25 14:30:53 +01:00
`}}let V9={kernelName:Zf,backendName:"webgl",kernelFunc:({inputs:n,attrs:t,backend:e})=>{let{image:r}=n,{radians:o,fillValue:s,center:c}=t,l=e,p=new W9(r.shape,o,s,c),f=l.runWebGLProgram(p,[r],r.dtype);return f}};let G9=gE+`
2020-10-11 18:41:17 +02:00
return sin(x);
2020-11-25 14:30:53 +01:00
`,U9=ig(G9),q9={kernelName:kc,backendName:"webgl",kernelFunc:U9};let H9="return x * x;",j9=ig(H9),K9={kernelName:Xf,backendName:"webgl",kernelFunc:j9};let SE="return (a - b) * (a - b);",X9=vl({opSnippet:SE,packedOpSnippet:SE}),Y9={kernelName:Nc,backendName:"webgl",kernelFunc:X9};let $E="return a - b;",J9=vl({opSnippet:$E,packedOpSnippet:$E,supportsComplex:!0,cpuKernelImpl:qX}),Z9={kernelName:_c,backendName:"webgl",kernelFunc:J9};let Q9="return tan(x);",tQ=ig(Q9),eQ={kernelName:Cc,backendName:"webgl",kernelFunc:tQ};let nQ={kernelName:ju,backendName:"webgl",kernelFunc:({inputs:n,attrs:t,backend:e})=>{let{x:r}=n,{perm:o}=t,s=e,c=r.shape.length,l=new Array(c);for(let f=0;f<l.length;f++)l[f]=r.shape[o[f]];let p;if(s.shouldExecuteOnCPU([r])){let f=s.texData.get(r.dataId),m=f.values,y=R1(m,r.shape,r.dtype,o,l);p=s.makeTensorInfo(l,r.dtype);let b=s.texData.get(p.dataId);b.values=y}else p=W1(r,o,s);return p}};function rQ(n){let{inputs:t,attrs:e,backend:r}=n,{axis:o}=e,{x:s}=t;ph(s,"unique"),console.warn("WARNING: ","UI might be locked temporarily as data is being downloaded");let c=r.readSync(s.dataId),{outputValues:l,outputShape:p,indices:f}=HX(c,o,s.shape,s.dtype);return[r.makeTensorInfo(p,s.dtype,l),r.makeTensorInfo([f.length],"int32",f)]}let oQ={kernelName:Yf,backendName:"webgl",kernelFunc:rQ};let sQ=[SZ,DZ,FZ,PZ,BZ,qZ,kZ,ZZ,e9,s9,a9,l9,h9,TZ,m9,KZ,v9,k9,_9,S9,I9,F9,P9,O9,M9,z9,WZ,VZ,YZ,V9,q9,K9,Z9,Y9,eQ,nQ,oQ];for(let n of sQ)rd(n);let iQ="2.7.0";let aQ={"tfjs-core":k_,"tfjs-backend-cpu":kK,"tfjs-backend-webgl":wZ,"tfjs-data":Y$,"tfjs-layers":Dm,"tfjs-converter":E$,tfjs:iQ};i.Abs=kf,i.Acos=au,i.Acosh=cu,i.AdadeltaOptimizer=Np,i.AdagradOptimizer=_p,i.AdamOptimizer=Cp,i.AdamaxOptimizer=Sp,i.Add=Zi,i.AddN=rx,i.All=uN,i.Any=pN,i.ArgMax=ox,i.ArgMin=sx,i.Asin=lu,i.Asinh=uu,i.Atan=pu,i.Atan2=Nf,i.Atanh=hu,i.AvgPool=fu,i.AvgPool3D=ix,i.AvgPool3DBackprop=hN,i.AvgPoolBackprop=_f,i.BatchMatMul=Cf,i.BatchToSpaceND=ax,i.BroadcastTo=cx,i.Callback=m$,i.CallbackList=lS,i.Cast=xc,i.Ceil=du,i.ClipByValue=mu,i.Complex=Sf,i.Concat=gu,i.Conv2D=$f,i.Conv2DBackpropFilter=lx,i.Conv2DBackpropInput=If,i.Conv3D=Ef,i.Conv3DBackpropFilterV2=ux,i.Conv3DBackpropInputV2=px,i.Cos=wc,i.Cosh=yu,i.CropAndResize=fN,i.Cumsum=hx,i.CustomCallback=pS,i.DataStorage=h,i.DepthToSpace=dN,i.DepthwiseConv2dNative=Df,i.DepthwiseConv2dNativeBackpropFilter=fx,i.DepthwiseConv2dNativeBackpropInput=dx,i.Diag=mN,i.Dilation2D=Af,i.Dilation2DBackpropFilter=Rf,i.Dilation2DBackpropInput=Ff,i.Div=vc,i.EarlyStopping=y$,i.Elu=bu,i.EluGrad=gN,i.Environment=aN,i.Equal=yN,i.Erf=xu,i.Exp=wu,i.Expm1=vu,i.FFT=Pf,i.Fill=mx,i.FlipLeftRight=Of,i.Floor=Tu,i.FloorDiv=gx,i.FromPixels=Jf,i.FusedBatchNorm=ku,i.FusedConv2D=td,i.FusedDepthwiseConv2D=ed,i.GatherNd=bN,i.GatherV2=yx,i.GraphModel=I$,i.Greater=xN,i.GreaterEqual=bx,i.History=uS,i.IFFT=Lf,i.Identity=Nu,i.Imag=Mf,i.InputSpec=In,i.IsFinite=_u,i.IsInf=Cu,i.IsNan=Su,i.KernelBackend=d,i.LRN=wx,i.LRNBackprop=_N,i.LayerVariable=xo,i.LayersModel=ks,i.Less=wN,i.LessEqual=vN,i.LinSpace=TN,i.Log=$u,i.Log1p=Iu,i.LogSoftmax=xx,i.LogicalAnd=kN,i.LogicalNot=Bf,i.LogicalOr=NN,i.Max=Eu,i.MaxPool=Du,i.MaxPool3D=Tx,i.MaxPool3DBackprop=CN,i.MaxPoolBackprop=zf,i.MaxPoolWithArgmax=Wf,i.Maximum=vx,i.Mean=kx,i.Min=Nx,i.Minimum=_x,i.MirrorPad=Au,i.Mod=Cx,i.MomentumOptimizer=$p,i.Multiply=Tc,i.Negate=Sx,i.NonMaxSuppressionV3=$x,i.NonMaxSuppressionV4=Vf,i.NonMaxSuppressionV5=Gf,i.NotEqual=Fu,i.OP_SCOPE_SUFFIX=KN,i.OneHot=Ex,i.OnesLike=Ix,i.Optimizer=xs,i.PadV2=Uf,i.Pool=BP,i.Pow=Dx,i.Prelu=qf,i.Prod=SN,i.RMSPropOptimizer=Ip,i.RNN=No,i.Range=$N,i.Real=Hf,i.Reciprocal=Ru,i.Relu=Pu,i.Relu6=Lu,i.Reshape=Ou,i.ResizeBilinear=Fx,i.ResizeBilinearGrad=EN,i.ResizeNearestNeighbor=Ax,i.ResizeNearestNeighborGrad=IN,i.Reverse=Rx,i.RotateWithOffset=Zf,i.Round=Mu,i.Rsqrt=Bu,i.SGDOptimizer=Xc,i.ScatterNd=DN,i.SelectV2=Px,i.Selu=zu,i.Sequential=Ta,i.Sigmoid=Gu,i.Sign=Vu,i.Sin=kc,i.Sinh=Wu,i.Slice=jf,i.Softmax=Mx,i.Softplus=Uu,i.SpaceToBatchND=Kf,i.SparseToDense=AN,i.SplitV=Lx,i.Sqrt=qu,i.Square=Xf,i.SquaredDifference=Nc,i.Step=Ku,i.StridedSlice=FN,i.Sub=_c,i.Sum=Ox,i.SymbolicTensor=w
`)),k.join(`
`)}function MQ(i,a,u,h){let d=an(a),g=h[h.length-1],x=new Array(g).fill(0),w=a.length,k=u==="complex64"?Nh(i):i;if(w>1)for(let C=0;C<d/g;C++){let $=C*g;for(let F=0;F<g;F++)x[F]=Math.max(x[F],kh(k[$+F],0,u).length)}return x}function kh(i,a,u){let h;return Array.isArray(i)?h=`${parseFloat(i[0].toFixed(gT))} + ${parseFloat(i[1].toFixed(gT))}j`:xh(i)?h=`'${i}'`:u==="bool"?h=Z2(i):h=parseFloat(i.toFixed(gT)).toString(),Fl(h,a)}function Z2(i){return i===0?"false":"true"}function ub(i,a,u,h,d,g=!0){let x=u==="complex64"?2:1,w=a[0],k=a.length;if(k===0){if(u==="complex64"){let tt=Nh(i);return[kh(tt[0],0,u)]}return u==="bool"?[Z2(i[0])]:[i[0].toString()]}if(k===1){if(w>Y2){let G=Th*x,mt=Array.from(i.slice(0,G)),lt=Array.from(i.slice((w-Th)*x,w*x));return u==="complex64"&&(mt=Nh(mt),lt=Nh(lt)),["["+mt.map((gt,_t)=>kh(gt,d[_t],u)).join(", ")+", ..., "+lt.map((gt,_t)=>kh(gt,d[w-Th+_t],u)).join(", ")+"]"]}let tt=u==="complex64"?Nh(i):Array.from(i);return["["+tt.map((G,mt)=>kh(G,d[mt],u)).join(", ")+"]"]}let C=a.slice(1),$=h.slice(1),F=h[0]*x,_=[];if(w>Y2){for(let tt=0;tt<Th;tt++){let G=tt*F,mt=G+F;_.push(...ub(i.slice(G,mt),C,u,$,d,!1))}_.push("...");for(let tt=w-Th;tt<w;tt++){let G=tt*F,mt=G+F;_.push(...ub(i.slice(G,mt),C,u,$,d,tt===w-1))}}else for(let tt=0;tt<w;tt++){let G=tt*F,mt=G+F;_.push(...ub(i.slice(G,mt),C,u,$,d,tt===w-1))}let W=k===2?",":"";_[0]="["+_[0]+W;for(let tt=1;tt<_.length-1;tt++)_[tt]=" "+_[tt]+W;let et=`,
`;for(let tt=2;tt<k;tt++)et+=`
`;return _[_.length-1]=" "+_[_.length-1]+"]"+(g?"":et),_}function Nh(i){let a=[];for(let u=0;u<i.length;u+=2)a.push([i[u],i[u+1]]);return a}var yT=class{constructor(a,u,h){if(this.dtype=u,this.shape=a.slice(),this.size=an(a),h!=null){let d=h.length;U(d===this.size,()=>`Length of values '${d}' does not match the size inferred by the shape '${this.size}'.`)}if(u==="complex64")throw new Error("complex64 dtype TensorBuffers are not supported. Please create a TensorBuffer for the real and imaginary parts separately and call tf.complex(real, imag).");this.values=h||zE(u,this.size),this.strides=vh(a)}set(a,...u){u.length===0&&(u=[0]),U(u.length===this.rank,()=>`The number of provided coordinates (${u.length}) must match the rank (${this.rank})`);let h=this.locToIndex(u);this.values[h]=a}get(...a){a.length===0&&(a=[0]);let u=0;for(let d of a){if(d<0||d>=this.shape[u]){let g=`Requested out of range element at ${a}. Buffer shape=${this.shape}`;throw new Error(g)}u++}let h=a[a.length-1];for(let d=0;d<a.length-1;++d)h+=this.strides[d]*a[d];return this.values[h]}locToIndex(a){if(this.rank===0)return 0;if(this.rank===1)return a[0];let u=a[a.length-1];for(let h=0;h<a.length-1;++h)u+=this.strides[h]*a[h];return u}indexToLoc(a){if(this.rank===0)return[];if(this.rank===1)return[a];let u=new Array(this.shape.length);for(let h=0;h<u.length-1;++h)u[h]=Math.floor(a/this.strides[h]),a-=u[h]*this.strides[h];return u[u.length-1]=a,u}get rank(){return this.shape.length}toTensor(){return es().makeTensor(this.values,this.shape,this.dtype)}},es=null,Ol=null,BQ=null;function Q2(i){es=i}function tD(i){Ol=i}function eD(i){BQ=i}var z=class{constructor(a,u,h,d){this.kept=!1,this.isDisposedInternal=!1,this.shape=a.slice(),this.dtype=u||"float32",this.size=an(a),this.strides=vh(a),this.dataId=h,this.id=d,this.rankType=this.rank<5?this.rank.toString():"higher"}get rank(){return this.shape.length}async buffer(){let a=await this.data();return Ol.buffer(this.shape,this.dtype,a)}bufferSync(){return Ol.buffer(this.shape,this.dtype,this.dataSync())}async array(){let a=await this.data();return oT(this.shape,a)}arraySync(){return oT(this.shape,this.dataSync())}async data(){this.throwIfDisposed();let a=es().read(this.dataId);if(this.dtype==="string"){let u=await a;try{return u.map(h=>dT(h))}catch(h){throw new Error("Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().")}}return a}dataSync(){this.throwIfDisposed();let a=es().readSync(this.dataId);if(this.dtype==="string")try{return a.map(u=>dT(u))}catch(u){throw new Error("Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().")}return a}async bytes(){this.throwIfDisposed();let a=await es().read(this.dataId);return this.dtype==="string"?a:new Uint8Array(a.buffer)}dispose(){if(this.isDisposed)return;es().disposeTensor(this),this.isDisposedInternal=!0}get isDisposed(){return this.isDisposedInternal}throwIfDisposed(){if(this.isDisposed)throw new Error("Tensor is disposed.")}print(a=!1){return Ol.print(this,a)}clone(){return this.throwIfDisposed(),Ol.clone(this)}toString(a=!1){let u=this.dataSync();return J2(u,this.shape,this.dtype,a)}cast(a){return this.throwIfDisposed(),Ol.cast(this,a)}variable(a=!0,u,h){return this.throwIfDisposed(),es().makeVariable(this,a,u,h)}};Object.defineProperty(z,Symbol.hasInstance,{value:i=>!!i&&i.data!=null&&i.dataSync!=null&&i.throwIfDisposed!=null});var _h=class extends z{constructor(a,u,h,d){super(a.shape,a.dtype,a.dataId,d);this.trainable=u,this.name=h}assign(a){if(a.dtype!==this.dtype)throw new Error(`dtype of the new value (${a.dtype}) and previous value (${this.dtype}) must match`);if(!Os(a.shape,this.shape))throw new Error(`shape of the new value (${a.shape}) and previous value (${this.shape}) must match`);es().disposeTensor(this),this.dataId=a.dataId,es().incRef(this,null)}dispose(){es().disposeVariable(this),this.isDisposedInternal=!0}};Object.defineProperty(_h,Symbol.hasInstance,{value:i=>i instanceof z&&i.assign!=null&&i.assign instanceof Function});var nD;(function(i){i.R0="R0",i.R1="R1",i.R2="R2"
with dtype ${x.dtype}. `)});let h=(x,w)=>{let k=Zt(a,u[0].shape)[0],C=DD(u.map(_=>_.shape),k);if(an(C)===0)return NT([],C);if(u=u.filter(_=>_.size>0),u.length===1)return u[0];let $=u.map(_=>_.shape);ED($,k);let F=x.concat(u,k);return w(u),F},d=u,g={axis:a};return V.runKernelFunc(h,d,null,Ug,g)}var mn=O({concat_:ztt});function Wtt(i){let a=R(i,"x","sigmoid"),u={x:a};return V.runKernelFunc((h,d)=>{let g=h.sigmoid(a);return d([g]),g},u,null,qy)}var za=O({sigmoid_:Wtt});function Vtt(i,a,u){let h=R(i,"x","slice");if(h.rank===0)throw new Error("Slicing scalar is not possible");let d=(w,k)=>{let[C,$]=mb(h,a,u);return vD(h,C,$),k([h]),w.slice(h,C,$)},g={x:h},x={begin:a,size:u};return V.runKernelFunc(d,g,null,Wy,x)}var ve=O({slice_:Vtt});function Gtt(i){let a=R(i,"x","tanh"),u={x:a};return V.runKernelFunc((h,d)=>{let g=h.tanh(a);return d([g]),g},u,null,eb)}var KT=O({tanh_:Gtt});function Utt(i,a,u){let h=R(i,"x","batchToSpaceND"),d=a.reduce((k,C)=>k*C);U(h.rank>=1+a.length,()=>`input rank is ${h.rank} but should be > than blockShape.length ${a.length}`),U(u.length===a.length,()=>`crops.length is ${u.length} but should be equal to blockShape.length ${a.length}`),U(h.shape[0]%d===0,()=>`input tensor batch is ${h.shape[0]} but is not divisible by the product of the elements of blockShape ${a.join(" * ")} === ${d}`);let g=k=>k.batchToSpaceND(h,a,u),x={x:h},w={blockShape:a,crops:u};return V.runKernelFunc(g,x,null,zg,w)}var Wa=O({batchToSpaceND_:Utt});function AD(i){let a;return i.rank===0||i.rank===1?a=K(i,[1,1,1,i.size]):i.rank===2?a=K(i,[1,1,i.shape[0],i.shape[1]]):i.rank===3?a=K(i,[1,i.shape[0],i.shape[1],i.shape[2]]):a=i,a}function qtt(i,a,u,h,d,g){g==null&&(g=.001);let x=R(i,"x","batchNorm"),w=R(a,"mean","batchNorm"),k=R(u,"variance","batchNorm"),C;d!=null&&(C=R(d,"scale","batchNorm"));let $;h!=null&&($=R(h,"offset","batchNorm")),U(w.rank===k.rank,()=>"Batch normalization gradient requires mean and variance to have equal ranks."),U($==null||w.rank===$.rank,()=>"Batch normalization gradient requires mean and offset to have equal ranks."),U(C==null||w.rank===C.rank,()=>"Batch normalization gradient requires mean and scale to have equal ranks.");let F=AD(x),_=(G,mt)=>(mt([F,w,k,C]),G.batchNorm(F,bb(w),bb(k),bb($),bb(C),g)),W={x:F,scale:C,offset:$,mean:w,variance:k},et={varianceEpsilon:g},tt=V.runKernelFunc(_,W,null,sy,et);return K(tt,x.shape)}function bb(i){return i==null?null:i.rank===0?K(i,[i.size]):i.rank===1?i:i.rank===2?K(i,[1,1,i.shape[0],i.shape[1]]):i.rank===3?K(i,[1,i.shape[0],i.shape[1],i.shape[2]]):i}var XT=O({batchNorm_:qtt});function Htt(i,a){let u=R(i,"broadcastTo","x"),h=u.shape;if(a.some($=>!($>0)||$%1!==0))throw new Error(`broadcastTo(): Invalid broadcast shape [${a}].`);if(a.length<u.rank)throw new Error(`broadcastTo(): shape.length=${a.length} < input.rank=${u.rank}.`);if(a.length>u.rank){let $=u.shape.slice();for(;$.length<a.length;)$.unshift(1);u=K(u,$)}let d=u.shape,g=Array.from(a);for(let $=a.length-1;$>=0;$--)if(d[$]===a[$])g[$]=1;else if(u.shape[$]!==1)throw new Error(`broadcastTo(): [${h}] cannot be broadcast to [${a}].`);let x=g.map(($,F)=>$>1?F:-1).filter($=>$>=0);if(x.length===0)return Do(u);let w=$=>$.tile(u,g),k={x:u},C={shape:a,inputShape:d};return V.runKernelFunc(w,k,null,Wg,C)}var Vl=O({broadcastTo_:Htt});function jtt(i){let a=R(i,"x","ceil"),u={x:a};return V.runKernelFunc(h=>h.ceil(a),u,null,Vg)}var YT=O({ceil_:jtt});function Ktt(i,a,u){let h=R(i,"x","clipByValue");U(a<=u,()=>`Error in clip: min (${a}) must be less than or equal to max (${u}).`);let d={x:h},g={clipValueMin:a,clipValueMax:u};return V.runKernelFunc((x,w)=>{let k=x.clip(h,a,u);return w([h]),k},d,null,Gg,g)}var JT=O({clipByValue_:Ktt});function Xtt(i,a,u,h,d="NHWC",g=[1,1],x){let w=R(i,"x","conv2d"),k=R(a,"filter","conv2d"),C=w,$=!1;w.rank===3&&($=!0,C=K(w,[1,w.shape[0],w.shape[1],w.shape[2]])),U(C.rank===4,()=>`Error in conv2d: input must be rank 4, but got rank ${C.rank}.`),U(k.rank===4,()=>`Error in conv2d: filter must be rank 4, but got rank ${k.rank}.`),x!=null&&U(ke(h),()=>`Error in conv2d: pad must be an integer when
${d} and ${a} for depthToSpace with input shape
${h.shape}`),U(g*a>=0,()=>`Negative dimension size caused by overflow when multiplying
${g} and ${a} for depthToSpace with input shape
${h.shape}`),U(x%(a*a)===0,()=>`Dimension size must be evenly divisible by ${a*a} but is ${x} for depthToSpace with input shape ${h.shape}`);let w=$=>$.depthToSpace(h,a,u),k={x:h},C={blockSize:a,dataFormat:u};return V.runKernelFunc(w,k,null,a2,C)}var tk=O({depthToSpace_:ret});function oet(i,a,u,h,d="NHWC",g=[1,1],x){let w=R(i,"x","depthwiseConv2d"),k=R(a,"filter","depthwiseConv2d"),C=w,$=!1;w.rank===3&&($=!0,C=K(w,[1,w.shape[0],w.shape[1],w.shape[2]])),U(C.rank===4,()=>`Error in depthwiseConv2d: input must be rank 4, but got rank ${C.rank}.`),U(k.rank===4,()=>`Error in depthwiseConv2d: filter must be rank 4, but got rank ${k.rank}.`),U(C.shape[3]===k.shape[2],()=>`Error in depthwiseConv2d: number of input channels (${C.shape[3]}) must match the inChannels dimension in filter ${k.shape[2]}.`),x!=null&&U(ke(h),()=>`Error in depthwiseConv2d: pad must be an integer when using, dimRoundingMode ${x} but got pad ${h}.`);let F=(tt,G)=>{g==null&&(g=[1,1]),U(Vn(u,g),()=>`Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${u} and dilations '${g}'`);let mt=Gr(C.shape,k.shape,u,g,h,x,!0),lt=tt.depthwiseConv2D(C,k,mt);return G([C,k]),lt},_={x:C,filter:k},W={strides:u,pad:h,dataFormat:d,dilations:g,dimRoundingMode:x},et=V.runKernelFunc(F,_,null,Yg,W);return $?K(et,[et.shape[1],et.shape[2],et.shape[3]]):et}var Ga=O({depthwiseConv2d_:oet});function set(i,a,u,h,d=[1,1],g="NHWC"){let x=R(i,"x","dilation2d"),w=R(a,"filter","dilation2d");U(x.rank===3||x.rank===4,()=>`Error in dilation2d: input must be rank 3 or 4, but got rank ${x.rank}.`),U(w.rank===3,()=>`Error in dilation2d: filter must be rank 3, but got rank ${w.rank}.`),U(g==="NHWC",()=>`Error in dilation2d: Only NHWC is currently supported, but got dataFormat of ${g}`);let k=x,C=!1;x.rank===3&&(k=K(x,[1,x.shape[0],x.shape[1],x.shape[2]]),C=!0);let $={x:k,filter:w},F={strides:u,pad:h,dilations:d},_=V.runKernel(Jg,$,F);return C?K(_,[_.shape[1],_.shape[2],_.shape[3]]):_}var ek=O({dilation2d_:set});function Be(i,a){let u=[];for(let h=0;h<a.length;h++){let d=i[i.length-h-1],g=a.length-h-1,x=a[g];(d==null||d===1&&x>1)&&u.unshift(g)}return u}function ne(i,a){let u=[],h=Math.max(i.length,a.length);for(let d=0;d<h;d++){let g=i[i.length-d-1];g==null&&(g=1);let x=a[a.length-d-1];if(x==null&&(x=1),g===1)u.unshift(x);else if(x===1)u.unshift(g);else if(g!==x){let w=`Operands could not be broadcast together with shapes ${i} and ${a}.`;throw Error(w)}else u.unshift(g)}return u}function iet(i,a){let u=R(i,"a","equal"),h=R(a,"b","equal");[u,h]=he(u,h),ne(u.shape,h.shape);let d=x=>x.equal(u,h),g={a:u,b:h};return V.runKernelFunc(d,g,null,f2)}var Gs=O({equal_:iet});function aet(i,a,u){let h=R(a,"a","where"),d=R(u,"b","where"),g=R(i,"condition","where","bool"),x=ne(h.shape,d.shape),w=Vl(h,x),k=Vl(d,x);g.rank===1&&U(g.shape[0]===h.shape[0],()=>"The first dimension of `a` must match the size of `condition`."),g.rank!==1&&ae(g.shape,k.shape,"Error in where: ");let C=(F,_)=>{let W=F.select(g,w,k);return _([g]),W},$={condition:g,t:w,e:k};return V.runKernelFunc(C,$,null,By)}var _n=O({where_:aet});function cet(i){let a=R(i,"x","zerosLike"),u={x:a};return V.runKernelFunc(h=>h.zerosLike(a),u,null,ib)}var jt=O({zerosLike_:cet});function uet(i,a){let u=R(i,"a","div"),h=R(a,"b","div");[u,h]=he(u,h);let d=Wt(u,h),g=jt(d),x=Gs(h,g);return _n(x,g,d)}var nk=O({divNoNan_:uet});function pet(i,a){let u=R(i,"t1","dot"),h=R(a,"t2","dot");U((u.rank===1||u.rank===2)&&(h.rank===1||h.rank===2),()=>`Error in dot: inputs must all be rank 1 or 2, but got ranks ${u.rank} and ${h.rank}.`);let d=u.rank===1?u.size:u.shape[1],g=h.rank===1?h.size:h.shape[0];if(U(d===g,()=>`Error in dot: inner dimensions of inputs must match, but got ${d} and ${g}.`),u.rank===1&&h.rank===1){let x=K(u,[1,-1]),w=K(h,[-1,1]),k=Ge(x,w);return K(k,[])}else if(u.rank===1&&h.rank===2){let x=K(u,[1,-1]),w=K(h,[h.shape[0],h.shape[1]]),k=Ge(x,w);return K(k,[k.size])}else if(u.rank===2&&h.rank===1){let x=K(h,[-1,1]),w=Ge(u,x);return K(w,[w.size])}else{let x=K(h,[h.shape[0],h.shape[1]]),w=Ge(u,x);return w}}var rk=O({dot_:pet});functi
rank ${g.rank}.`),U(ke(a),()=>`Error in localResponseNormalization: depthRadius must be an integer but got depthRadius ${a}.`);let x=g,w=!1;g.rank===3&&(w=!0,x=K(g,[1,g.shape[0],g.shape[1],g.shape[2]]));let k=(_,W)=>{let et=_.localResponseNormalization4D(x,a,u,h,d);return W([x,et]),et},C={x},$={depthRadius:a,bias:u,alpha:h,beta:d},F=V.runKernelFunc(k,C,null,my,$);return w?K(F,[F.shape[1],F.shape[2],F.shape[3]]):F}var fk=O({localResponseNormalization_:Aet});function Fet(i){let a=R(i,"x","log"),u={x:a};return V.runKernelFunc((h,d)=>{let g=h.log(a);return d([a]),g},u,null,hy)}var io=O({log_:Fet});function Ret(i){let a=R(i,"x","log1p"),u={x:a};return V.runKernelFunc((h,d)=>{let g=h.log1p(a);return d([a]),g},u,null,fy)}var Rh=O({log1p_:Ret});function Gl(i){return V.customGrad(i)}function Pet(i){let a=R(i,"x","neg"),u={x:a};return V.runKernelFunc(h=>h.neg(a),u,null,Ny)}var me=O({neg_:Pet});function Oet(i){let a=R(i,"x","softplus"),u={x:a};return V.runKernelFunc((h,d)=>{let g=h.softplus(a);return d([a]),g},u,null,Hy)}var Ph=O({softplus_:Oet});function Let(i){let a=R(i,"x","logSigmoid"),u=Gl(h=>{let d=me(Ph(me(h))),g=x=>{let w=at(x,za(me(h)));return w};return{value:d,gradFunc:g}});return u(a)}var dk=O({logSigmoid_:Let});function Met(i,a=null,u=!1){let h=R(i,"x","max"),d=(w,k)=>{let C=Zt(a,h.shape),$=C,F=Nn($,h.rank),_=h;F!=null&&(_=Ie(h,F),$=Wn($.length,_.rank));let W=w.max(_,$);F!=null&&_.dispose();let et=W;if(u){let tt=dn(et.shape,Zt(a,h.shape));et=K(et,tt),W.dispose()}return k([h,et]),et},g={x:h},x={reductionIndices:a,keepDims:u};return V.runKernelFunc(d,g,null,gy,x)}var Ao=O({max_:Met});function Bet(i,a){let u=R(i,"a","sub"),h=R(a,"b","sub");[u,h]=he(u,h);let d=(x,w)=>{let k=x.subtract(u,h);return w([u,h]),k},g={a:u,b:h};return V.runKernelFunc(d,g,null,Qy)}var Pt=O({sub_:Bet});function zet(i,a=null,u=!1){let h=R(i,"x","sum");h.dtype==="bool"&&(h=wt(h,"int32"));let d=(w,k)=>{k([h]);let C=Zt(a,h.shape),$=Nn(C,h.rank),F=C,_=h;$!=null&&(_=Ie(h,$),F=Wn(F.length,h.rank));let W=w.sum(_,F);if(u){let et=dn(W.shape,C);W=K(W,et)}return W},g={x:h},x={axis:a,keepDims:u};return V.runKernelFunc(d,g,null,Ky,x)}var Ft=O({sum_:zet});function Wet(i,a=-1){let u=R(i,"logits","logSoftmax");if(a===-1&&(a=u.rank-1),a!==u.rank-1)throw Error(`Log Softmax along a non-last dimension is not yet supported. Logits was rank ${u.rank} and axis was ${a}`);let h=(x,w)=>{let k=!0,C=Ao(i,a,!0),$=Pt(i,C),F=Pt(wt($,"float32"),io(Ft(Cn($),a,k)));return w([F]),F},d={logits:u},g={axis:a};return V.runKernelFunc(h,d,null,dy,g)}var mk=O({logSoftmax_:Wet});function Vet(i,a=null,u=!1){let h=R(i,"x","logSumExp"),d=Zt(a,h.shape),g=Ao(h,d,!0),x=Pt(h,g),w=Cn(x),k=Ft(w,d),C=io(k),$=Ne(K(g,C.shape),C);if(u){let F=dn($.shape,d);return K($,F)}return $}var Oh=O({logSumExp_:Vet});function Get(i,a){let u=R(i,"a","logicalAnd","bool"),h=R(a,"b","logicalAnd","bool");ne(u.shape,h.shape);let d={a:u,b:h};return V.runKernelFunc(g=>g.logicalAnd(u,h),d,null,T2)}var ao=O({logicalAnd_:Get});function Uet(i){let a=R(i,"x","logicalNot","bool"),u={x:a};return V.runKernelFunc(h=>h.logicalNot(a),u,null,k2)}var Ha=O({logicalNot_:Uet});function qet(i,a){let u=R(i,"a","logicalOr","bool"),h=R(a,"b","logicalOr","bool");ne(u.shape,h.shape);let d={a:u,b:h};return V.runKernelFunc(g=>g.logicalOr(u,h),d,null,N2)}var Lh=O({logicalOr_:qet});function Het(i,a){let u=R(i,"a","logicalXor","bool"),h=R(a,"b","logicalXor","bool");return ne(u.shape,h.shape),ao(Lh(i,a),Ha(ao(i,a)))}var gk=O({logicalXor_:Het});function jet(i,a,u,h,d){let g=R(i,"x","maxPool"),x=1,w=g,k=!1;g.rank===3&&(k=!0,w=K(g,[1,g.shape[0],g.shape[1],g.shape[2]])),U(w.rank===4,()=>`Error in maxPool: input must be rank 4 but got rank ${w.rank}.`),U(Vn(u,x),()=>`Error in maxPool: Either strides or dilations must be 1. Got strides ${u} and dilations '${x}'`),d!=null&&U(ke(h),()=>`Error in maxPool: pad must be an integer when using, dimRoundingMode ${d} but got pad ${h}.`);let C=(W,et)=>{let tt=os(w.shape,a,u,1,h,d),G;return tt.filterWidth===1&&tt.filterHeight===1&&Os(tt.inShape,tt.outShape)?G=w.clone():G=W.maxPool(w,tt),et([w,G]),G},$={x:
2020-10-11 18:41:17 +02:00
/**
* @license
* Copyright 2017 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2018 Google LLC
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* =============================================================================
*/
/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2019 Google LLC
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* =============================================================================
*/
/**
* @license
* Copyright 2019 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
/**
* @license
* Copyright 2019 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google LLC
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/** @license See the LICENSE file. */
//# sourceMappingURL=face-api.js.map