From be99f76ce9b705b8af56b6bbbac51be85a8f9d97 Mon Sep 17 00:00:00 2001 From: veehz Date: Fri, 3 Oct 2025 23:20:18 +0800 Subject: [PATCH 001/128] yarn initialize --- .editorconfig | 8 ++++++++ .gitignore | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 9 +++++++++ yarn.lock | 12 ++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..025dd8c8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f3474e56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,53 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +/node_modules + +# testing +/coverage + +# production +/build +src/styles/*.css +/.env + +# deployment +terraform* + +# sourceror bundle +/public/externalLibs/sourceror + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local +.idea/ + +npm-debug.log* +.eslintcache +yarn-error.log + +# emacs backup files + +*~ + +# yarn files + +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# Swap the comments on the following lines if you wish to use zero-installs +# In that case, don't forget to run `yarn config set enableGlobalCache false`! +# Documentation here: https://yarnpkg.com/features/caching#zero-installs + +#!.yarn/cache +.pnp.* + +# We use .node-version +/.tool-versions \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..94a3065d --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "type": "module", + "name": "torch", + "packageManager": "yarn@4.10.3", + "version": "0.1.0", + "description": "machine-learning libraries for Source Academy", + "repository": "git@github.com/source-academy/torch.git", + "license": "Apache-2.0" +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..96714d87 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,12 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"torch@workspace:.": + version: 0.0.0-use.local + resolution: "torch@workspace:." + languageName: unknown + linkType: soft From 2bd89561426a1597bf1cc04dbf06149f7015d131 Mon Sep 17 00:00:00 2001 From: veehz Date: Tue, 7 Oct 2025 22:51:00 +0800 Subject: [PATCH 002/128] Initialise code structure --- .yarn/sdks/integrations.yml | 5 + .yarn/sdks/typescript/bin/tsc | 32 + .yarn/sdks/typescript/bin/tsserver | 32 + .yarn/sdks/typescript/lib/tsc.js | 32 + .yarn/sdks/typescript/lib/tsserver.js | 248 + .yarn/sdks/typescript/lib/tsserverlibrary.js | 248 + .yarn/sdks/typescript/lib/typescript.js | 32 + .yarn/sdks/typescript/package.json | 10 + README.md | 41 + examples/basic_backpropagation.js | 9 + examples/browser/index.html | 32 + jest.config.js | 15 + package.json | 39 +- public/gpu-browser.min.js | 28 + src/broadcasting.ts | 56 + src/gpu.ts | 21 + src/index.ts | 16 + src/operations/basic.ts | 415 ++ src/operations/function_base.ts | 23 + src/operations/registry.ts | 16 + src/tensor.ts | 157 + src/tensor_base.ts | 1 + src/utils.ts | 7 + test/backward.test.ts | 59 + test/broadcast.test.ts | 21 + test/tensor.test.ts | 68 + tsconfig.json | 18 + vite.config.browser.ts | 39 + vite.config.node.ts | 19 + yarn.lock | 5960 ++++++++++++++++++ 30 files changed, 7698 insertions(+), 1 deletion(-) create mode 100644 .yarn/sdks/integrations.yml create mode 100755 .yarn/sdks/typescript/bin/tsc create mode 100755 .yarn/sdks/typescript/bin/tsserver create mode 100644 .yarn/sdks/typescript/lib/tsc.js create mode 100644 .yarn/sdks/typescript/lib/tsserver.js create mode 100644 .yarn/sdks/typescript/lib/tsserverlibrary.js create mode 100644 .yarn/sdks/typescript/lib/typescript.js create mode 100644 .yarn/sdks/typescript/package.json create mode 100644 examples/basic_backpropagation.js create mode 100644 examples/browser/index.html create mode 100644 jest.config.js create mode 100644 public/gpu-browser.min.js create mode 100644 src/broadcasting.ts create mode 100644 src/gpu.ts create mode 100644 src/index.ts create mode 100644 src/operations/basic.ts create mode 100644 src/operations/function_base.ts create mode 100644 src/operations/registry.ts create mode 100644 src/tensor.ts create mode 100644 src/tensor_base.ts create mode 100644 src/utils.ts create mode 100644 test/backward.test.ts create mode 100644 test/broadcast.test.ts create mode 100644 test/tensor.test.ts create mode 100644 tsconfig.json create mode 100644 vite.config.browser.ts create mode 100644 vite.config.node.ts diff --git a/.yarn/sdks/integrations.yml b/.yarn/sdks/integrations.yml new file mode 100644 index 00000000..aa9d0d0a --- /dev/null +++ b/.yarn/sdks/integrations.yml @@ -0,0 +1,5 @@ +# This file is automatically generated by @yarnpkg/sdks. +# Manual changes might be lost! + +integrations: + - vscode diff --git a/.yarn/sdks/typescript/bin/tsc b/.yarn/sdks/typescript/bin/tsc new file mode 100755 index 00000000..867a7bdf --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsc @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsc + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript/bin/tsc your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsc`)); diff --git a/.yarn/sdks/typescript/bin/tsserver b/.yarn/sdks/typescript/bin/tsserver new file mode 100755 index 00000000..3fc5aa31 --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsserver @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsserver + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript/bin/tsserver your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`)); diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js new file mode 100644 index 00000000..da411bdb --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsc.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsc.js + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript/lib/tsc.js your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript/lib/tsc.js`)); diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js new file mode 100644 index 00000000..6249c467 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserver.js @@ -0,0 +1,248 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserver.js + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +const moduleWrapper = exports => { + return wrapWithUserWrapper(moduleWrapperFn(exports)); +}; + +const moduleWrapperFn = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } else { + str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } + } + + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); +// In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. +// Ref https://github.com/microsoft/TypeScript/pull/55326 +if (major > 5 || (major === 5 && minor >= 5)) { + moduleWrapper(absRequire(`typescript`)); +} + +// Defer to the real typescript/lib/tsserver.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`)); diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js new file mode 100644 index 00000000..0e50e0a2 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -0,0 +1,248 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserverlibrary.js + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +const moduleWrapper = exports => { + return wrapWithUserWrapper(moduleWrapperFn(exports)); +}; + +const moduleWrapperFn = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } else { + str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } + } + + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); +// In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. +// Ref https://github.com/microsoft/TypeScript/pull/55326 +if (major > 5 || (major === 5 && minor >= 5)) { + moduleWrapper(absRequire(`typescript`)); +} + +// Defer to the real typescript/lib/tsserverlibrary.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`)); diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js new file mode 100644 index 00000000..7b6cc220 --- /dev/null +++ b/.yarn/sdks/typescript/lib/typescript.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript`)); diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json new file mode 100644 index 00000000..19a0b6f1 --- /dev/null +++ b/.yarn/sdks/typescript/package.json @@ -0,0 +1,10 @@ +{ + "name": "typescript", + "version": "5.9.3-sdk", + "main": "./lib/typescript.js", + "type": "commonjs", + "bin": { + "tsc": "./bin/tsc", + "tsserver": "./bin/tsserver" + } +} diff --git a/README.md b/README.md index 08cb1b83..85d2dda3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,43 @@ # torch machine-learning libraries for Source Academy + +## Getting Started + +Install yarn: + +``` bash +corepack enable +# or +npm install -g yarn +``` + +Install dependencies: + +```bash +yarn install +``` + +## Demo Usage + +First, build it: + +```bash +yarn build +``` + +### Node + +See `examples/basic_backpropagation.js`. + +```bash +node examples/basic_backpropagation.js +``` + +### Browser + +You can run `http-server` and load `examples/browser/index.html` to see how it works. + +```bash +npx http-server --cors=* -c-1 . +# and navigate to http://localhost:8080/examples/browser/index.html +``` \ No newline at end of file diff --git a/examples/basic_backpropagation.js b/examples/basic_backpropagation.js new file mode 100644 index 00000000..31339ae6 --- /dev/null +++ b/examples/basic_backpropagation.js @@ -0,0 +1,9 @@ +import { Tensor } from "../build/node/torch.node.es.js"; + +const x = new Tensor([2.0], { requires_grad: true }); +const y = x.pow(new Tensor([2.0])); + +console.log(y.item()); +y.backward(); + +console.log(x.grad?.item()); \ No newline at end of file diff --git a/examples/browser/index.html b/examples/browser/index.html new file mode 100644 index 00000000..e21f2f1b --- /dev/null +++ b/examples/browser/index.html @@ -0,0 +1,32 @@ + + + + + + torch.js browser backprop example + + + + + + +

+  
+
+
+
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 00000000..fcd798d5
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,15 @@
+export default {
+  preset: 'ts-jest',
+  testEnvironment: 'node',
+  roots: ['/test'],
+  testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
+  transform: {
+    '^.+\\.ts$': 'ts-jest',
+  },
+  collectCoverageFrom: [
+    'src/**/*.ts',
+    '!src/**/*.d.ts',
+  ],
+  moduleFileExtensions: ['ts', 'js', 'json'],
+  testTimeout: 10000,
+};
diff --git a/package.json b/package.json
index 94a3065d..126081cc 100644
--- a/package.json
+++ b/package.json
@@ -5,5 +5,42 @@
   "version": "0.1.0",
   "description": "machine-learning libraries for Source Academy",
   "repository": "git@github.com/source-academy/torch.git",
-  "license": "Apache-2.0"
+  "license": "Apache-2.0",
+  "files": [
+    "build"
+  ],
+  "main": "./build/node/torch.node.cjs.js",
+  "module": "./build/node/torch.node.es.js",
+  "types": "./build/types/index.d.ts",
+  "exports": {
+    ".": {
+      "types": "./build/types/index.d.ts",
+      "browser": "./build/browser/torch.browser.es.js",
+      "import": "./build/node/torch.node.es.js",
+      "require": "./build/node/torch.node.cjs.js"
+    }
+  },
+  "scripts": {
+    "clean": "rimraf build",
+    "build:browser": "vite build --config vite.config.browser.ts",
+    "build:node": "vite build --config vite.config.node.ts",
+    "build": "npm run clean && npm run build:node && npm run build:browser",
+    "test": "jest",
+    "test:watch": "jest --watch"
+  },
+  "devDependencies": {
+    "@types/jest": "^30.0.0",
+    "@types/node": "^24.6.2",
+    "jest": "^30.2.0",
+    "jest-util": "^30.2.0",
+    "rimraf": "^6.0.1",
+    "ts-jest": "^29.4.4",
+    "ts-node": "^10.9.2",
+    "typescript": "^5.9.3",
+    "vite": "^7.1.9",
+    "vite-plugin-dts": "^4.5.4"
+  },
+  "dependencies": {
+    "@veehz/gpu.js": "^2.16.0"
+  }
 }
diff --git a/public/gpu-browser.min.js b/public/gpu-browser.min.js
new file mode 100644
index 00000000..e41461ba
--- /dev/null
+++ b/public/gpu-browser.min.js
@@ -0,0 +1,28 @@
+/**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Wed Nov 16 2022 15:48:40 GMT-0500 (Eastern Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2022 gpu.js Team
+ *//**
+ * gpu.js
+ * http://gpu.rocks/
+ *
+ * GPU Accelerated JavaScript
+ *
+ * @version 2.16.0
+ * @date Wed Nov 16 2022 15:48:37 GMT-0500 (Eastern Standard Time)
+ *
+ * @license MIT
+ * The MIT License
+ *
+ * Copyright (c) 2022 gpu.js Team
+ */
+ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).GPU=e()}}((function(){return function e(t,n,r){function i(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var h=n[a]={exports:{}};t[a][0].call(h.exports,(function(e){return i(t[a][1][e]||e)}),h,h.exports,e,t,n,r)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;ae)return!1;if((n+=t[r+1])>=e)return!0}}function p(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&o.test(String.fromCharCode(e)):!1!==t&&c(e,l)))}function d(e,t){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&u.test(String.fromCharCode(e)):!1!==t&&(c(e,l)||c(e,h)))))}var m=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function f(e,t){return new m(e,{beforeExpr:!0,binop:t})}var g={beforeExpr:!0},x={startsExpr:!0},y={};function b(e,t){return void 0===t&&(t={}),t.keyword=e,y[e]=new m(e,t)}var T={num:new m("num",x),regexp:new m("regexp",x),string:new m("string",x),name:new m("name",x),eof:new m("eof"),bracketL:new m("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new m("]"),braceL:new m("{",{beforeExpr:!0,startsExpr:!0}),braceR:new m("}"),parenL:new m("(",{beforeExpr:!0,startsExpr:!0}),parenR:new m(")"),comma:new m(",",g),semi:new m(";",g),colon:new m(":",g),dot:new m("."),question:new m("?",g),arrow:new m("=>",g),template:new m("template"),invalidTemplate:new m("invalidTemplate"),ellipsis:new m("...",g),backQuote:new m("`",x),dollarBraceL:new m("${",{beforeExpr:!0,startsExpr:!0}),eq:new m("=",{beforeExpr:!0,isAssign:!0}),assign:new m("_=",{beforeExpr:!0,isAssign:!0}),incDec:new m("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new m("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:f("||",1),logicalAND:f("&&",2),bitwiseOR:f("|",3),bitwiseXOR:f("^",4),bitwiseAND:f("&",5),equality:f("==/!=/===/!==",6),relational:f("/<=/>=",7),bitShift:f("<>/>>>",8),plusMin:new m("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:f("%",10),star:f("*",10),slash:f("/",10),starstar:new m("**",{beforeExpr:!0}),_break:b("break"),_case:b("case",g),_catch:b("catch"),_continue:b("continue"),_debugger:b("debugger"),_default:b("default",g),_do:b("do",{isLoop:!0,beforeExpr:!0}),_else:b("else",g),_finally:b("finally"),_for:b("for",{isLoop:!0}),_function:b("function",x),_if:b("if"),_return:b("return",g),_switch:b("switch"),_throw:b("throw",g),_try:b("try"),_var:b("var"),_const:b("const"),_while:b("while",{isLoop:!0}),_with:b("with"),_new:b("new",{beforeExpr:!0,startsExpr:!0}),_this:b("this",x),_super:b("super",x),_class:b("class",x),_extends:b("extends",g),_export:b("export"),_import:b("import",x),_null:b("null",x),_true:b("true",x),_false:b("false",x),_in:b("in",{beforeExpr:!0,binop:7}),_instanceof:b("instanceof",{beforeExpr:!0,binop:7}),_typeof:b("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:b("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:b("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},v=/\r\n?|\n|\u2028|\u2029/,S=new RegExp(v.source,"g");function A(e,t){return 10===e||13===e||!t&&(8232===e||8233===e)}var _=/[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/,E=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,w=Object.prototype,k=w.hasOwnProperty,I=w.toString;function D(e,t){return k.call(e,t)}var C=Array.isArray||function(e){return"[object Array]"===I.call(e)};function $(e){return new RegExp("^(?:"+e.replace(/ /g,"|")+")$")}var L=function(e,t){this.line=e,this.column=t};L.prototype.offset=function(e){return new L(this.line,this.column+e)};var R=function(e,t,n){this.start=t,this.end=n,null!==e.sourceFile&&(this.source=e.sourceFile)};function F(e,t){for(var n=1,r=0;;){S.lastIndex=r;var i=S.exec(e);if(!(i&&i.index=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),C(t.onToken)){var r=t.onToken;t.onToken=function(e){return r.push(e)}}return C(t.onComment)&&(t.onComment=function(e,t){return function(n,r,i,s,a,o){var u={type:n?"Block":"Line",value:r,start:i,end:s};e.locations&&(u.loc=new R(this,a,o)),e.ranges&&(u.range=[i,s]),t.push(u)}}(t,t.onComment)),t}function M(e,t){return 2|(e?4:0)|(t?8:0)}var O=function(e,n,i){this.options=e=V(e),this.sourceFile=e.sourceFile,this.keywords=$(r[e.ecmaVersion>=6?6:"module"===e.sourceType?"5module":5]);var s="";if(!0!==e.allowReserved){for(var a=e.ecmaVersion;!(s=t[a]);a--);"module"===e.sourceType&&(s+=" await")}this.reservedWords=$(s);var o=(s?s+" ":"")+t.strict;this.reservedWordsStrict=$(o),this.reservedWordsStrictBind=$(o+" "+t.strictBind),this.input=String(n),this.containsEsc=!1,i?(this.pos=i,this.lineStart=this.input.lastIndexOf("\n",i-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(v).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=T.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports={},0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(1),this.regexpState=null},z={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0}};O.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)},z.inFunction.get=function(){return(2&this.currentVarScope().flags)>0},z.inGenerator.get=function(){return(8&this.currentVarScope().flags)>0},z.inAsync.get=function(){return(4&this.currentVarScope().flags)>0},z.allowSuper.get=function(){return(64&this.currentThisScope().flags)>0},z.allowDirectSuper.get=function(){return(128&this.currentThisScope().flags)>0},z.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())},O.prototype.inNonArrowFunction=function(){return(2&this.currentThisScope().flags)>0},O.extend=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var n=this,r=0;r-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var n=t?e.parenthesizedAssign:e.parenthesizedBind;n>-1&&this.raiseRecoverable(n,"Parenthesized pattern")}},P.checkExpressionErrors=function(e,t){if(!e)return!1;var n=e.shorthandAssign,r=e.doubleProto;if(!t)return n>=0||r>=0;n>=0&&this.raise(n,"Shorthand property assignments are valid only in destructuring patterns"),r>=0&&this.raiseRecoverable(r,"Redefinition of __proto__ property")},P.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos=6&&this.unexpected(),this.parseFunctionStatement(s,!1,!e);case T._class:return e&&this.unexpected(),this.parseClass(s,!0);case T._if:return this.parseIfStatement(s);case T._return:return this.parseReturnStatement(s);case T._switch:return this.parseSwitchStatement(s);case T._throw:return this.parseThrowStatement(s);case T._try:return this.parseTryStatement(s);case T._const:case T._var:return r=r||this.value,e&&"var"!==r&&this.unexpected(),this.parseVarStatement(s,r);case T._while:return this.parseWhileStatement(s);case T._with:return this.parseWithStatement(s);case T.braceL:return this.parseBlock(!0,s);case T.semi:return this.parseEmptyStatement(s);case T._export:case T._import:if(this.options.ecmaVersion>10&&i===T._import){E.lastIndex=this.pos;var a=E.exec(this.input),o=this.pos+a[0].length;if(40===this.input.charCodeAt(o))return this.parseExpressionStatement(s,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),i===T._import?this.parseImport(s):this.parseExport(s,n);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(s,!0,!e);var u=this.value,l=this.parseExpression();return i===T.name&&"Identifier"===l.type&&this.eat(T.colon)?this.parseLabeledStatement(s,u,l,e):this.parseExpressionStatement(s,l)}},U.parseBreakContinueStatement=function(e,t){var n="break"===t;this.next(),this.eat(T.semi)||this.insertSemicolon()?e.label=null:this.type!==T.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var r=0;r=6?this.eat(T.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},U.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&(this.inAsync||!this.inFunction&&this.options.allowAwaitOutsideFunction)&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(B),this.enterScope(0),this.expect(T.parenL),this.type===T.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var n=this.isLet();if(this.type===T._var||this.type===T._const||n){var r=this.startNode(),i=n?"let":this.value;return this.next(),this.parseVar(r,!0,i),this.finishNode(r,"VariableDeclaration"),(this.type===T._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&1===r.declarations.length?(this.options.ecmaVersion>=9&&(this.type===T._in?t>-1&&this.unexpected(t):e.await=t>-1),this.parseForIn(e,r)):(t>-1&&this.unexpected(t),this.parseFor(e,r))}var s=new G,a=this.parseExpression(!0,s);return this.type===T._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.options.ecmaVersion>=9&&(this.type===T._in?t>-1&&this.unexpected(t):e.await=t>-1),this.toAssignable(a,!1,s),this.checkLVal(a),this.parseForIn(e,a)):(this.checkExpressionErrors(s,!0),t>-1&&this.unexpected(t),this.parseFor(e,a))},U.parseFunctionStatement=function(e,t,n){return this.next(),this.parseFunction(e,H|(n?0:X),!1,t)},U.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(T._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")},U.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(T.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},U.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(T.braceL),this.labels.push(W),this.enterScope(0);for(var n=!1;this.type!==T.braceR;)if(this.type===T._case||this.type===T._default){var r=this.type===T._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),r?t.test=this.parseExpression():(n&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),n=!0,t.test=null),this.expect(T.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},U.parseThrowStatement=function(e){return this.next(),v.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var j=[];U.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===T._catch){var t=this.startNode();if(this.next(),this.eat(T.parenL)){t.param=this.parseBindingAtom();var n="Identifier"===t.param.type;this.enterScope(n?32:0),this.checkLVal(t.param,n?4:2),this.expect(T.parenR)}else this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0);t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(T._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},U.parseVarStatement=function(e,t){return this.next(),this.parseVar(e,!1,t),this.semicolon(),this.finishNode(e,"VariableDeclaration")},U.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(B),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")},U.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")},U.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},U.parseLabeledStatement=function(e,t,n,r){for(var i=0,s=this.labels;i=0;o--){var u=this.labels[o];if(u.statementStart!==e.start)break;u.statementStart=this.start,u.kind=a}return this.labels.push({name:t,kind:a,statementStart:this.start}),e.body=this.parseStatement(r?-1===r.indexOf("label")?r+"label":r:"label"),this.labels.pop(),e.label=n,this.finishNode(e,"LabeledStatement")},U.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},U.parseBlock=function(e,t){for(void 0===e&&(e=!0),void 0===t&&(t=this.startNode()),t.body=[],this.expect(T.braceL),e&&this.enterScope(0);!this.eat(T.braceR);){var n=this.parseStatement(null);t.body.push(n)}return e&&this.exitScope(),this.finishNode(t,"BlockStatement")},U.parseFor=function(e,t){return e.init=t,this.expect(T.semi),e.test=this.type===T.semi?null:this.parseExpression(),this.expect(T.semi),e.update=this.type===T.parenR?null:this.parseExpression(),this.expect(T.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")},U.parseForIn=function(e,t){var n=this.type===T._in;return this.next(),"VariableDeclaration"===t.type&&null!=t.declarations[0].init&&(!n||this.options.ecmaVersion<8||this.strict||"var"!==t.kind||"Identifier"!==t.declarations[0].id.type)?this.raise(t.start,(n?"for-in":"for-of")+" loop variable declaration may not have an initializer"):"AssignmentPattern"===t.type&&this.raise(t.start,"Invalid left-hand side in for-loop"),e.left=t,e.right=n?this.parseExpression():this.parseMaybeAssign(),this.expect(T.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,n?"ForInStatement":"ForOfStatement")},U.parseVar=function(e,t,n){for(e.declarations=[],e.kind=n;;){var r=this.startNode();if(this.parseVarId(r,n),this.eat(T.eq)?r.init=this.parseMaybeAssign(t):"const"!==n||this.type===T._in||this.options.ecmaVersion>=6&&this.isContextual("of")?"Identifier"===r.id.type||t&&(this.type===T._in||this.isContextual("of"))?r.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(r,"VariableDeclarator")),!this.eat(T.comma))break}return e},U.parseVarId=function(e,t){e.id=this.parseBindingAtom(),this.checkLVal(e.id,"var"===t?1:2,!1)};var H=1,X=2;U.parseFunction=function(e,t,n,r){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!r)&&(this.type===T.star&&t&X&&this.unexpected(),e.generator=this.eat(T.star)),this.options.ecmaVersion>=8&&(e.async=!!r),t&H&&(e.id=4&t&&this.type!==T.name?null:this.parseIdent(),!e.id||t&X||this.checkLVal(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?1:2:3));var i=this.yieldPos,s=this.awaitPos,a=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(M(e.async,e.generator)),t&H||(e.id=this.type===T.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,n,!1),this.yieldPos=i,this.awaitPos=s,this.awaitIdentPos=a,this.finishNode(e,t&H?"FunctionDeclaration":"FunctionExpression")},U.parseFunctionParams=function(e){this.expect(T.parenL),e.params=this.parseBindingList(T.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},U.parseClass=function(e,t){this.next();var n=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var r=this.startNode(),i=!1;for(r.body=[],this.expect(T.braceL);!this.eat(T.braceR);){var s=this.parseClassElement(null!==e.superClass);s&&(r.body.push(s),"MethodDefinition"===s.type&&"constructor"===s.kind&&(i&&this.raise(s.start,"Duplicate constructor in the same class"),i=!0))}return e.body=this.finishNode(r,"ClassBody"),this.strict=n,this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},U.parseClassElement=function(e){var t=this;if(this.eat(T.semi))return null;var n=this.startNode(),r=function(e,r){void 0===r&&(r=!1);var i=t.start,s=t.startLoc;return!!t.eatContextual(e)&&(!(t.type===T.parenL||r&&t.canInsertSemicolon())||(n.key&&t.unexpected(),n.computed=!1,n.key=t.startNodeAt(i,s),n.key.name=e,t.finishNode(n.key,"Identifier"),!1))};n.kind="method",n.static=r("static");var i=this.eat(T.star),s=!1;i||(this.options.ecmaVersion>=8&&r("async",!0)?(s=!0,i=this.options.ecmaVersion>=9&&this.eat(T.star)):r("get")?n.kind="get":r("set")&&(n.kind="set")),n.key||this.parsePropertyName(n);var a=n.key,o=!1;return n.computed||n.static||!("Identifier"===a.type&&"constructor"===a.name||"Literal"===a.type&&"constructor"===a.value)?n.static&&"Identifier"===a.type&&"prototype"===a.name&&this.raise(a.start,"Classes may not have a static property named prototype"):("method"!==n.kind&&this.raise(a.start,"Constructor can't have get/set modifier"),i&&this.raise(a.start,"Constructor can't be a generator"),s&&this.raise(a.start,"Constructor can't be an async method"),n.kind="constructor",o=e),this.parseClassMethod(n,i,s,o),"get"===n.kind&&0!==n.value.params.length&&this.raiseRecoverable(n.value.start,"getter should have no params"),"set"===n.kind&&1!==n.value.params.length&&this.raiseRecoverable(n.value.start,"setter should have exactly one param"),"set"===n.kind&&"RestElement"===n.value.params[0].type&&this.raiseRecoverable(n.value.params[0].start,"Setter cannot use rest params"),n},U.parseClassMethod=function(e,t,n,r){return e.value=this.parseMethod(t,n,r),this.finishNode(e,"MethodDefinition")},U.parseClassId=function(e,t){this.type===T.name?(e.id=this.parseIdent(),t&&this.checkLVal(e.id,2,!1)):(!0===t&&this.unexpected(),e.id=null)},U.parseClassSuper=function(e){e.superClass=this.eat(T._extends)?this.parseExprSubscripts():null},U.parseExport=function(e,t){if(this.next(),this.eat(T.star))return this.expectContextual("from"),this.type!==T.string&&this.unexpected(),e.source=this.parseExprAtom(),this.semicolon(),this.finishNode(e,"ExportAllDeclaration");if(this.eat(T._default)){var n;if(this.checkExport(t,"default",this.lastTokStart),this.type===T._function||(n=this.isAsyncFunction())){var r=this.startNode();this.next(),n&&this.next(),e.declaration=this.parseFunction(r,4|H,!1,n)}else if(this.type===T._class){var i=this.startNode();e.declaration=this.parseClass(i,"nullableID")}else e.declaration=this.parseMaybeAssign(),this.semicolon();return this.finishNode(e,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement())e.declaration=this.parseStatement(null),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id.name,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==T.string&&this.unexpected(),e.source=this.parseExprAtom();else{for(var s=0,a=e.specifiers;s=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",n&&this.checkPatternErrors(n,!0);for(var r=0,i=e.properties;r=8&&!s&&"async"===a.name&&!this.canInsertSemicolon()&&this.eat(T._function))return this.parseFunction(this.startNodeAt(r,i),0,!1,!0);if(n&&!this.canInsertSemicolon()){if(this.eat(T.arrow))return this.parseArrowExpression(this.startNodeAt(r,i),[a],!1);if(this.options.ecmaVersion>=8&&"async"===a.name&&this.type===T.name&&!s)return a=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(T.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(r,i),[a],!0)}return a;case T.regexp:var o=this.value;return(t=this.parseLiteral(o.value)).regex={pattern:o.pattern,flags:o.flags},t;case T.num:case T.string:return this.parseLiteral(this.value);case T._null:case T._true:case T._false:return(t=this.startNode()).value=this.type===T._null?null:this.type===T._true,t.raw=this.type.keyword,this.next(),this.finishNode(t,"Literal");case T.parenL:var u=this.start,l=this.parseParenAndDistinguishExpression(n);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(l)&&(e.parenthesizedAssign=u),e.parenthesizedBind<0&&(e.parenthesizedBind=u)),l;case T.bracketL:return t=this.startNode(),this.next(),t.elements=this.parseExprList(T.bracketR,!0,!0,e),this.finishNode(t,"ArrayExpression");case T.braceL:return this.parseObj(!1,e);case T._function:return t=this.startNode(),this.next(),this.parseFunction(t,0);case T._class:return this.parseClass(this.startNode(),!1);case T._new:return this.parseNew();case T.backQuote:return this.parseTemplate();case T._import:return this.options.ecmaVersion>=11?this.parseExprImport():this.unexpected();default:this.unexpected()}},Y.parseExprImport=function(){var e=this.startNode();if(this.next(),this.type===T.parenL)return this.parseDynamicImport(e);this.unexpected()},Y.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),!this.eat(T.parenR)){var t=this.start;this.eat(T.comma)&&this.eat(T.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")},Y.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),110===t.raw.charCodeAt(t.raw.length-1)&&(t.bigint=t.raw.slice(0,-1)),this.next(),this.finishNode(t,"Literal")},Y.parseParenExpression=function(){this.expect(T.parenL);var e=this.parseExpression();return this.expect(T.parenR),e},Y.parseParenAndDistinguishExpression=function(e){var t,n=this.start,r=this.startLoc,i=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var s,a=this.start,o=this.startLoc,u=[],l=!0,h=!1,c=new G,p=this.yieldPos,d=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==T.parenR;){if(l?l=!1:this.expect(T.comma),i&&this.afterTrailingComma(T.parenR,!0)){h=!0;break}if(this.type===T.ellipsis){s=this.start,u.push(this.parseParenItem(this.parseRestBinding())),this.type===T.comma&&this.raise(this.start,"Comma is not permitted after the rest element");break}u.push(this.parseMaybeAssign(!1,c,this.parseParenItem))}var m=this.start,f=this.startLoc;if(this.expect(T.parenR),e&&!this.canInsertSemicolon()&&this.eat(T.arrow))return this.checkPatternErrors(c,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=p,this.awaitPos=d,this.parseParenArrowList(n,r,u);u.length&&!h||this.unexpected(this.lastTokStart),s&&this.unexpected(s),this.checkExpressionErrors(c,!0),this.yieldPos=p||this.yieldPos,this.awaitPos=d||this.awaitPos,u.length>1?((t=this.startNodeAt(a,o)).expressions=u,this.finishNodeAt(t,"SequenceExpression",m,f)):t=u[0]}else t=this.parseParenExpression();if(this.options.preserveParens){var g=this.startNodeAt(n,r);return g.expression=t,this.finishNode(g,"ParenthesizedExpression")}return t},Y.parseParenItem=function(e){return e},Y.parseParenArrowList=function(e,t,n){return this.parseArrowExpression(this.startNodeAt(e,t),n)};var Z=[];Y.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode(),t=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(T.dot)){e.meta=t;var n=this.containsEsc;return e.property=this.parseIdent(!0),("target"!==e.property.name||n)&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is new.target"),this.inNonArrowFunction()||this.raiseRecoverable(e.start,"new.target can only be used in functions"),this.finishNode(e,"MetaProperty")}var r=this.start,i=this.startLoc,s=this.type===T._import;return e.callee=this.parseSubscripts(this.parseExprAtom(),r,i,!0),s&&"ImportExpression"===e.callee.type&&this.raise(r,"Cannot use new with import()"),this.eat(T.parenL)?e.arguments=this.parseExprList(T.parenR,this.options.ecmaVersion>=8,!1):e.arguments=Z,this.finishNode(e,"NewExpression")},Y.parseTemplateElement=function(e){var t=e.isTagged,n=this.startNode();return this.type===T.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),n.value={raw:this.value,cooked:null}):n.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),n.tail=this.type===T.backQuote,this.finishNode(n,"TemplateElement")},Y.parseTemplate=function(e){void 0===e&&(e={});var t=e.isTagged;void 0===t&&(t=!1);var n=this.startNode();this.next(),n.expressions=[];var r=this.parseTemplateElement({isTagged:t});for(n.quasis=[r];!r.tail;)this.type===T.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(T.dollarBraceL),n.expressions.push(this.parseExpression()),this.expect(T.braceR),n.quasis.push(r=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(n,"TemplateLiteral")},Y.isAsyncProp=function(e){return!e.computed&&"Identifier"===e.key.type&&"async"===e.key.name&&(this.type===T.name||this.type===T.num||this.type===T.string||this.type===T.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===T.star)&&!v.test(this.input.slice(this.lastTokEnd,this.start))},Y.parseObj=function(e,t){var n=this.startNode(),r=!0,i={};for(n.properties=[],this.next();!this.eat(T.braceR);){if(r)r=!1;else if(this.expect(T.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(T.braceR))break;var s=this.parseProperty(e,t);e||this.checkPropClash(s,i,t),n.properties.push(s)}return this.finishNode(n,e?"ObjectPattern":"ObjectExpression")},Y.parseProperty=function(e,t){var n,r,i,s,a=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(T.ellipsis))return e?(a.argument=this.parseIdent(!1),this.type===T.comma&&this.raise(this.start,"Comma is not permitted after the rest element"),this.finishNode(a,"RestElement")):(this.type===T.parenL&&t&&(t.parenthesizedAssign<0&&(t.parenthesizedAssign=this.start),t.parenthesizedBind<0&&(t.parenthesizedBind=this.start)),a.argument=this.parseMaybeAssign(!1,t),this.type===T.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(a,"SpreadElement"));this.options.ecmaVersion>=6&&(a.method=!1,a.shorthand=!1,(e||t)&&(i=this.start,s=this.startLoc),e||(n=this.eat(T.star)));var o=this.containsEsc;return this.parsePropertyName(a),!e&&!o&&this.options.ecmaVersion>=8&&!n&&this.isAsyncProp(a)?(r=!0,n=this.options.ecmaVersion>=9&&this.eat(T.star),this.parsePropertyName(a,t)):r=!1,this.parsePropertyValue(a,e,n,r,i,s,t,o),this.finishNode(a,"Property")},Y.parsePropertyValue=function(e,t,n,r,i,s,a,o){if((n||r)&&this.type===T.colon&&this.unexpected(),this.eat(T.colon))e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,a),e.kind="init";else if(this.options.ecmaVersion>=6&&this.type===T.parenL)t&&this.unexpected(),e.kind="init",e.method=!0,e.value=this.parseMethod(n,r);else if(t||o||!(this.options.ecmaVersion>=5)||e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||this.type===T.comma||this.type===T.braceR)this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((n||r)&&this.unexpected(),this.checkUnreserved(e.key),"await"!==e.key.name||this.awaitIdentPos||(this.awaitIdentPos=i),e.kind="init",t?e.value=this.parseMaybeDefault(i,s,e.key):this.type===T.eq&&a?(a.shorthandAssign<0&&(a.shorthandAssign=this.start),e.value=this.parseMaybeDefault(i,s,e.key)):e.value=e.key,e.shorthand=!0):this.unexpected();else{(n||r)&&this.unexpected(),e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);var u="get"===e.kind?0:1;if(e.value.params.length!==u){var l=e.value.start;"get"===e.kind?this.raiseRecoverable(l,"getter should have no params"):this.raiseRecoverable(l,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")}},Y.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(T.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(T.bracketR),e.key;e.computed=!1}return e.key=this.type===T.num||this.type===T.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved)},Y.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},Y.parseMethod=function(e,t,n){var r=this.startNode(),i=this.yieldPos,s=this.awaitPos,a=this.awaitIdentPos;return this.initFunction(r),this.options.ecmaVersion>=6&&(r.generator=e),this.options.ecmaVersion>=8&&(r.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(64|M(t,r.generator)|(n?128:0)),this.expect(T.parenL),r.params=this.parseBindingList(T.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(r,!1,!0),this.yieldPos=i,this.awaitPos=s,this.awaitIdentPos=a,this.finishNode(r,"FunctionExpression")},Y.parseArrowExpression=function(e,t,n){var r=this.yieldPos,i=this.awaitPos,s=this.awaitIdentPos;return this.enterScope(16|M(n,!1)),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!n),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1),this.yieldPos=r,this.awaitPos=i,this.awaitIdentPos=s,this.finishNode(e,"ArrowFunctionExpression")},Y.parseFunctionBody=function(e,t,n){var r=t&&this.type!==T.braceL,i=this.strict,s=!1;if(r)e.body=this.parseMaybeAssign(),e.expression=!0,this.checkParams(e,!1);else{var a=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);i&&!a||(s=this.strictDirective(this.end))&&a&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var o=this.labels;this.labels=[],s&&(this.strict=!0),this.checkParams(e,!i&&!s&&!t&&!n&&this.isSimpleParamList(e.params)),e.body=this.parseBlock(!1),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=o}this.exitScope(),this.strict&&e.id&&this.checkLVal(e.id,5),this.strict=i},Y.isSimpleParamList=function(e){for(var t=0,n=e;t-1||i.functions.indexOf(e)>-1||i.var.indexOf(e)>-1,i.lexical.push(e),this.inModule&&1&i.flags&&delete this.undefinedExports[e]}else if(4===t){this.currentScope().lexical.push(e)}else if(3===t){var s=this.currentScope();r=this.treatFunctionsAsVar?s.lexical.indexOf(e)>-1:s.lexical.indexOf(e)>-1||s.var.indexOf(e)>-1,s.functions.push(e)}else for(var a=this.scopeStack.length-1;a>=0;--a){var o=this.scopeStack[a];if(o.lexical.indexOf(e)>-1&&!(32&o.flags&&o.lexical[0]===e)||!this.treatFunctionsAsVarInScope(o)&&o.functions.indexOf(e)>-1){r=!0;break}if(o.var.push(e),this.inModule&&1&o.flags&&delete this.undefinedExports[e],3&o.flags)break}r&&this.raiseRecoverable(n,"Identifier '"+e+"' has already been declared")},Q.checkLocalExport=function(e){-1===this.scopeStack[0].lexical.indexOf(e.name)&&-1===this.scopeStack[0].var.indexOf(e.name)&&(this.undefinedExports[e.name]=e)},Q.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]},Q.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(3&t.flags)return t}},Q.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(3&t.flags&&!(16&t.flags))return t}};var te=function(e,t,n){this.type="",this.start=t,this.end=0,e.options.locations&&(this.loc=new R(e,n)),e.options.directSourceFile&&(this.sourceFile=e.options.directSourceFile),e.options.ranges&&(this.range=[t,0])},ne=O.prototype;function re(e,t,n,r){return e.type=t,e.end=n,this.options.locations&&(e.loc.end=r),this.options.ranges&&(e.range[1]=n),e}ne.startNode=function(){return new te(this,this.start,this.startLoc)},ne.startNodeAt=function(e,t){return new te(this,e,t)},ne.finishNode=function(e,t){return re.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)},ne.finishNodeAt=function(e,t,n,r){return re.call(this,e,t,n,r)};var ie=function(e,t,n,r,i){this.token=e,this.isExpr=!!t,this.preserveSpace=!!n,this.override=r,this.generator=!!i},se={b_stat:new ie("{",!1),b_expr:new ie("{",!0),b_tmpl:new ie("${",!1),p_stat:new ie("(",!1),p_expr:new ie("(",!0),q_tmpl:new ie("`",!0,!0,(function(e){return e.tryReadTemplateToken()})),f_stat:new ie("function",!1),f_expr:new ie("function",!0),f_expr_gen:new ie("function",!0,!1,null,!0),f_gen:new ie("function",!1,!1,null,!0)},ae=O.prototype;ae.initialContext=function(){return[se.b_stat]},ae.braceIsBlock=function(e){var t=this.curContext();return t===se.f_expr||t===se.f_stat||(e!==T.colon||t!==se.b_stat&&t!==se.b_expr?e===T._return||e===T.name&&this.exprAllowed?v.test(this.input.slice(this.lastTokEnd,this.start)):e===T._else||e===T.semi||e===T.eof||e===T.parenR||e===T.arrow||(e===T.braceL?t===se.b_stat:e!==T._var&&e!==T._const&&e!==T.name&&!this.exprAllowed):!t.isExpr)},ae.inGeneratorContext=function(){for(var e=this.context.length-1;e>=1;e--){var t=this.context[e];if("function"===t.token)return t.generator}return!1},ae.updateContext=function(e){var t,n=this.type;n.keyword&&e===T.dot?this.exprAllowed=!1:(t=n.updateContext)?t.call(this,e):this.exprAllowed=n.beforeExpr},T.parenR.updateContext=T.braceR.updateContext=function(){if(1!==this.context.length){var e=this.context.pop();e===se.b_stat&&"function"===this.curContext().token&&(e=this.context.pop()),this.exprAllowed=!e.isExpr}else this.exprAllowed=!0},T.braceL.updateContext=function(e){this.context.push(this.braceIsBlock(e)?se.b_stat:se.b_expr),this.exprAllowed=!0},T.dollarBraceL.updateContext=function(){this.context.push(se.b_tmpl),this.exprAllowed=!0},T.parenL.updateContext=function(e){var t=e===T._if||e===T._for||e===T._with||e===T._while;this.context.push(t?se.p_stat:se.p_expr),this.exprAllowed=!0},T.incDec.updateContext=function(){},T._function.updateContext=T._class.updateContext=function(e){!e.beforeExpr||e===T.semi||e===T._else||e===T._return&&v.test(this.input.slice(this.lastTokEnd,this.start))||(e===T.colon||e===T.braceL)&&this.curContext()===se.b_stat?this.context.push(se.f_stat):this.context.push(se.f_expr),this.exprAllowed=!1},T.backQuote.updateContext=function(){this.curContext()===se.q_tmpl?this.context.pop():this.context.push(se.q_tmpl),this.exprAllowed=!1},T.star.updateContext=function(e){if(e===T._function){var t=this.context.length-1;this.context[t]===se.f_expr?this.context[t]=se.f_expr_gen:this.context[t]=se.f_gen}this.exprAllowed=!0},T.name.updateContext=function(e){var t=!1;this.options.ecmaVersion>=6&&e!==T.dot&&("of"===this.value&&!this.exprAllowed||"yield"===this.value&&this.inGeneratorContext())&&(t=!0),this.exprAllowed=t};var oe="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",ue=oe+" Extended_Pictographic",le={9:oe,10:ue,11:"ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS Extended_Pictographic"},he="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",ce="Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",pe=ce+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",de={9:ce,10:pe,11:"Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"},me={};function fe(e){var t=me[e]={binary:$(le[e]+" "+he),nonBinary:{General_Category:$(he),Script:$(de[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}fe(9),fe(10),fe(11);var ge=O.prototype,xe=function(e){this.parser=e,this.validFlags="gim"+(e.options.ecmaVersion>=6?"uy":"")+(e.options.ecmaVersion>=9?"s":""),this.unicodeProperties=me[e.options.ecmaVersion>=11?11:e.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=[],this.backReferenceNames=[]};function ye(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode(55296+(e>>10),56320+(1023&e)))}function be(e){return 36===e||e>=40&&e<=43||46===e||63===e||e>=91&&e<=94||e>=123&&e<=125}function Te(e){return e>=65&&e<=90||e>=97&&e<=122}function ve(e){return Te(e)||95===e}function Se(e){return ve(e)||Ae(e)}function Ae(e){return e>=48&&e<=57}function _e(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Ee(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e-48}function we(e){return e>=48&&e<=55}xe.prototype.reset=function(e,t,n){var r=-1!==n.indexOf("u");this.start=0|e,this.source=t+"",this.flags=n,this.switchU=r&&this.parser.options.ecmaVersion>=6,this.switchN=r&&this.parser.options.ecmaVersion>=9},xe.prototype.raise=function(e){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+e)},xe.prototype.at=function(e){var t=this.source,n=t.length;if(e>=n)return-1;var r=t.charCodeAt(e);if(!this.switchU||r<=55295||r>=57344||e+1>=n)return r;var i=t.charCodeAt(e+1);return i>=56320&&i<=57343?(r<<10)+i-56613888:r},xe.prototype.nextIndex=function(e){var t=this.source,n=t.length;if(e>=n)return n;var r,i=t.charCodeAt(e);return!this.switchU||i<=55295||i>=57344||e+1>=n||(r=t.charCodeAt(e+1))<56320||r>57343?e+1:e+2},xe.prototype.current=function(){return this.at(this.pos)},xe.prototype.lookahead=function(){return this.at(this.nextIndex(this.pos))},xe.prototype.advance=function(){this.pos=this.nextIndex(this.pos)},xe.prototype.eat=function(e){return this.current()===e&&(this.advance(),!0)},ge.validateRegExpFlags=function(e){for(var t=e.validFlags,n=e.flags,r=0;r-1&&this.raise(e.start,"Duplicate regular expression flag")}},ge.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&e.groupNames.length>0&&(e.switchN=!0,this.regexp_pattern(e))},ge.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames.length=0,e.backReferenceNames.length=0,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,n=e.backReferenceNames;t=9&&(n=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!n,!0}return e.pos=t,!1},ge.regexp_eatQuantifier=function(e,t){return void 0===t&&(t=!1),!!this.regexp_eatQuantifierPrefix(e,t)&&(e.eat(63),!0)},ge.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)},ge.regexp_eatBracedQuantifier=function(e,t){var n=e.pos;if(e.eat(123)){var r=0,i=-1;if(this.regexp_eatDecimalDigits(e)&&(r=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(i=e.lastIntValue),e.eat(125)))return-1!==i&&i=9?this.regexp_groupSpecifier(e):63===e.current()&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1},ge.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)},ge.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1},ge.regexp_eatSyntaxCharacter=function(e){var t=e.current();return!!be(t)&&(e.lastIntValue=t,e.advance(),!0)},ge.regexp_eatPatternCharacters=function(e){for(var t=e.pos,n=0;-1!==(n=e.current())&&!be(n);)e.advance();return e.pos!==t},ge.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return!(-1===t||36===t||t>=40&&t<=43||46===t||63===t||91===t||94===t||124===t)&&(e.advance(),!0)},ge.regexp_groupSpecifier=function(e){if(e.eat(63)){if(this.regexp_eatGroupName(e))return-1!==e.groupNames.indexOf(e.lastStringValue)&&e.raise("Duplicate capture group name"),void e.groupNames.push(e.lastStringValue);e.raise("Invalid group")}},ge.regexp_eatGroupName=function(e){if(e.lastStringValue="",e.eat(60)){if(this.regexp_eatRegExpIdentifierName(e)&&e.eat(62))return!0;e.raise("Invalid capture group name")}return!1},ge.regexp_eatRegExpIdentifierName=function(e){if(e.lastStringValue="",this.regexp_eatRegExpIdentifierStart(e)){for(e.lastStringValue+=ye(e.lastIntValue);this.regexp_eatRegExpIdentifierPart(e);)e.lastStringValue+=ye(e.lastIntValue);return!0}return!1},ge.regexp_eatRegExpIdentifierStart=function(e){var t=e.pos,n=e.current();return e.advance(),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e)&&(n=e.lastIntValue),function(e){return p(e,!0)||36===e||95===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},ge.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,n=e.current();return e.advance(),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e)&&(n=e.lastIntValue),function(e){return d(e,!0)||36===e||95===e||8204===e||8205===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},ge.regexp_eatAtomEscape=function(e){return!!(this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e))||(e.switchU&&(99===e.current()&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)},ge.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var n=e.lastIntValue;if(e.switchU)return n>e.maxBackReference&&(e.maxBackReference=n),!0;if(n<=e.numCapturingParens)return!0;e.pos=t}return!1},ge.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1},ge.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)},ge.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1},ge.regexp_eatZero=function(e){return 48===e.current()&&!Ae(e.lookahead())&&(e.lastIntValue=0,e.advance(),!0)},ge.regexp_eatControlEscape=function(e){var t=e.current();return 116===t?(e.lastIntValue=9,e.advance(),!0):110===t?(e.lastIntValue=10,e.advance(),!0):118===t?(e.lastIntValue=11,e.advance(),!0):102===t?(e.lastIntValue=12,e.advance(),!0):114===t&&(e.lastIntValue=13,e.advance(),!0)},ge.regexp_eatControlLetter=function(e){var t=e.current();return!!Te(t)&&(e.lastIntValue=t%32,e.advance(),!0)},ge.regexp_eatRegExpUnicodeEscapeSequence=function(e){var t,n=e.pos;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var r=e.lastIntValue;if(e.switchU&&r>=55296&&r<=56319){var i=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var s=e.lastIntValue;if(s>=56320&&s<=57343)return e.lastIntValue=1024*(r-55296)+(s-56320)+65536,!0}e.pos=i,e.lastIntValue=r}return!0}if(e.switchU&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&((t=e.lastIntValue)>=0&&t<=1114111))return!0;e.switchU&&e.raise("Invalid unicode escape"),e.pos=n}return!1},ge.regexp_eatIdentityEscape=function(e){if(e.switchU)return!!this.regexp_eatSyntaxCharacter(e)||!!e.eat(47)&&(e.lastIntValue=47,!0);var t=e.current();return!(99===t||e.switchN&&107===t)&&(e.lastIntValue=t,e.advance(),!0)},ge.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do{e.lastIntValue=10*e.lastIntValue+(t-48),e.advance()}while((t=e.current())>=48&&t<=57);return!0}return!1},ge.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(function(e){return 100===e||68===e||115===e||83===e||119===e||87===e}(t))return e.lastIntValue=-1,e.advance(),!0;if(e.switchU&&this.options.ecmaVersion>=9&&(80===t||112===t)){if(e.lastIntValue=-1,e.advance(),e.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(e)&&e.eat(125))return!0;e.raise("Invalid property name")}return!1},ge.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var n=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var r=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,n,r),!0}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var i=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,i),!0}return!1},ge.regexp_validateUnicodePropertyNameAndValue=function(e,t,n){D(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(n)||e.raise("Invalid property value")},ge.regexp_validateUnicodePropertyNameOrValue=function(e,t){e.unicodeProperties.binary.test(t)||e.raise("Invalid property name")},ge.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";ve(t=e.current());)e.lastStringValue+=ye(t),e.advance();return""!==e.lastStringValue},ge.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";Se(t=e.current());)e.lastStringValue+=ye(t),e.advance();return""!==e.lastStringValue},ge.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)},ge.regexp_eatCharacterClass=function(e){if(e.eat(91)){if(e.eat(94),this.regexp_classRanges(e),e.eat(93))return!0;e.raise("Unterminated character class")}return!1},ge.regexp_classRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var n=e.lastIntValue;!e.switchU||-1!==t&&-1!==n||e.raise("Invalid character class"),-1!==t&&-1!==n&&t>n&&e.raise("Range out of order in character class")}}},ge.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var n=e.current();(99===n||we(n))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var r=e.current();return 93!==r&&(e.lastIntValue=r,e.advance(),!0)},ge.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)},ge.regexp_eatClassControlLetter=function(e){var t=e.current();return!(!Ae(t)&&95!==t)&&(e.lastIntValue=t%32,e.advance(),!0)},ge.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1},ge.regexp_eatDecimalDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;Ae(n=e.current());)e.lastIntValue=10*e.lastIntValue+(n-48),e.advance();return e.pos!==t},ge.regexp_eatHexDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;_e(n=e.current());)e.lastIntValue=16*e.lastIntValue+Ee(n),e.advance();return e.pos!==t},ge.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var n=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=64*t+8*n+e.lastIntValue:e.lastIntValue=8*t+n}else e.lastIntValue=t;return!0}return!1},ge.regexp_eatOctalDigit=function(e){var t=e.current();return we(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)},ge.regexp_eatFixedHexDigits=function(e,t){var n=e.pos;e.lastIntValue=0;for(var r=0;r>10),56320+(1023&e)))}Ie.next=function(e){!e&&this.type.keyword&&this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword "+this.type.keyword),this.options.onToken&&this.options.onToken(new ke(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},Ie.getToken=function(){return this.next(),new ke(this)},"undefined"!=typeof Symbol&&(Ie[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===T.eof,value:t}}}}),Ie.curContext=function(){return this.context[this.context.length-1]},Ie.nextToken=function(){var e=this.curContext();return e&&e.preserveSpace||this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length?this.finishToken(T.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},Ie.readToken=function(e){return p(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},Ie.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);return e<=55295||e>=57344?e:(e<<10)+this.input.charCodeAt(this.pos+1)-56613888},Ie.skipBlockComment=function(){var e,t=this.options.onComment&&this.curPosition(),n=this.pos,r=this.input.indexOf("*/",this.pos+=2);if(-1===r&&this.raise(this.pos-2,"Unterminated comment"),this.pos=r+2,this.options.locations)for(S.lastIndex=n;(e=S.exec(this.input))&&e.index8&&e<14||e>=5760&&_.test(String.fromCharCode(e))))break e;++this.pos}}},Ie.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var n=this.type;this.type=e,this.value=t,this.updateContext(n)},Ie.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(T.ellipsis)):(++this.pos,this.finishToken(T.dot))},Ie.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(T.assign,2):this.finishOp(T.slash,1)},Ie.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),n=1,r=42===e?T.star:T.modulo;return this.options.ecmaVersion>=7&&42===e&&42===t&&(++n,r=T.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(T.assign,n+1):this.finishOp(r,n)},Ie.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?this.finishOp(124===e?T.logicalOR:T.logicalAND,2):61===t?this.finishOp(T.assign,2):this.finishOp(124===e?T.bitwiseOR:T.bitwiseAND,1)},Ie.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(T.assign,2):this.finishOp(T.bitwiseXOR,1)},Ie.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45!==t||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!v.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(T.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===t?this.finishOp(T.assign,2):this.finishOp(T.plusMin,1)},Ie.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),n=1;return t===e?(n=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+n)?this.finishOp(T.assign,n+1):this.finishOp(T.bitShift,n)):33!==t||60!==e||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===t&&(n=2),this.finishOp(T.relational,n)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},Ie.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(T.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(T.arrow)):this.finishOp(61===e?T.eq:T.prefix,1)},Ie.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(T.parenL);case 41:return++this.pos,this.finishToken(T.parenR);case 59:return++this.pos,this.finishToken(T.semi);case 44:return++this.pos,this.finishToken(T.comma);case 91:return++this.pos,this.finishToken(T.bracketL);case 93:return++this.pos,this.finishToken(T.bracketR);case 123:return++this.pos,this.finishToken(T.braceL);case 125:return++this.pos,this.finishToken(T.braceR);case 58:return++this.pos,this.finishToken(T.colon);case 63:return++this.pos,this.finishToken(T.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(T.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 126:return this.finishOp(T.prefix,1)}this.raise(this.pos,"Unexpected character '"+De(e)+"'")},Ie.finishOp=function(e,t){var n=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,n)},Ie.readRegexp=function(){for(var e,t,n=this.pos;;){this.pos>=this.input.length&&this.raise(n,"Unterminated regular expression");var r=this.input.charAt(this.pos);if(v.test(r)&&this.raise(n,"Unterminated regular expression"),e)e=!1;else{if("["===r)t=!0;else if("]"===r&&t)t=!1;else if("/"===r&&!t)break;e="\\"===r}++this.pos}var i=this.input.slice(n,this.pos);++this.pos;var s=this.pos,a=this.readWord1();this.containsEsc&&this.unexpected(s);var o=this.regexpState||(this.regexpState=new xe(this));o.reset(n,i,a),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var u=null;try{u=new RegExp(i,a)}catch(e){}return this.finishToken(T.regexp,{pattern:i,flags:a,value:u})},Ie.readInt=function(e,t){for(var n=this.pos,r=0,i=0,s=null==t?1/0:t;i=97?a-97+10:a>=65?a-65+10:a>=48&&a<=57?a-48:1/0)>=e)break;++this.pos,r=r*e+o}return this.pos===n||null!=t&&this.pos-n!==t?null:r},Ie.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var n=this.readInt(e);return null==n&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&110===this.input.charCodeAt(this.pos)?(n="undefined"!=typeof BigInt?BigInt(this.input.slice(t,this.pos)):null,++this.pos):p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(T.num,n)},Ie.readNumber=function(e){var t=this.pos;e||null!==this.readInt(10)||this.raise(t,"Invalid number");var n=this.pos-t>=2&&48===this.input.charCodeAt(t);n&&this.strict&&this.raise(t,"Invalid number");var r=this.input.charCodeAt(this.pos);if(!n&&!e&&this.options.ecmaVersion>=11&&110===r){var i=this.input.slice(t,this.pos),s="undefined"!=typeof BigInt?BigInt(i):null;return++this.pos,p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(T.num,s)}n&&/[89]/.test(this.input.slice(t,this.pos))&&(n=!1),46!==r||n||(++this.pos,this.readInt(10),r=this.input.charCodeAt(this.pos)),69!==r&&101!==r||n||(43!==(r=this.input.charCodeAt(++this.pos))&&45!==r||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number")),p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var a=this.input.slice(t,this.pos),o=n?parseInt(a,8):parseFloat(a);return this.finishToken(T.num,o)},Ie.readCodePoint=function(){var e;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var t=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.invalidStringToken(t,"Code point out of bounds")}else e=this.readHexChar(4);return e},Ie.readString=function(e){for(var t="",n=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var r=this.input.charCodeAt(this.pos);if(r===e)break;92===r?(t+=this.input.slice(n,this.pos),t+=this.readEscapedChar(!1),n=this.pos):(A(r,this.options.ecmaVersion>=10)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(n,this.pos++),this.finishToken(T.string,t)};var Ce={};Ie.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e!==Ce)throw e;this.readInvalidTemplateToken()}this.inTemplateElement=!1},Ie.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw Ce;this.raise(e,t)},Ie.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var n=this.input.charCodeAt(this.pos);if(96===n||36===n&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==T.template&&this.type!==T.invalidTemplate?(e+=this.input.slice(t,this.pos),this.finishToken(T.template,e)):36===n?(this.pos+=2,this.finishToken(T.dollarBraceL)):(++this.pos,this.finishToken(T.backQuote));if(92===n)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(A(n)){switch(e+=this.input.slice(t,this.pos),++this.pos,n){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(n)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},Ie.readInvalidTemplateToken=function(){for(;this.pos=48&&t<=55){var r=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],i=parseInt(r,8);return i>255&&(r=r.slice(0,-1),i=parseInt(r,8)),this.pos+=r.length-1,t=this.input.charCodeAt(this.pos),"0"===r&&56!==t&&57!==t||!this.strict&&!e||this.invalidStringToken(this.pos-1-r.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(i)}return A(t)?"":String.fromCharCode(t)}},Ie.readHexChar=function(e){var t=this.pos,n=this.readInt(16,e);return null===n&&this.invalidStringToken(t,"Bad character escape sequence"),n},Ie.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,n=this.pos,r=this.options.ecmaVersion>=6;this.pos0;)l.pop()}function v(e,t){h[e]=t}function S(e){const t=f[e];return t?n+"."+t:e}function A(e){y=" ".repeat(e)}function _(e,t){const r=`${n}Variable${m.length}`;return l.push(`${y}const ${r} = ${t};`),m.push(e),r}function E(e,t){const r=`${n}Variable${m.length}`,i=`imageDatum${x}`;l.push(`${y}let ${i} = ["P3\\n# ${u}.ppm\\n", ${e}, ' ', ${t}, "\\n255\\n"].join("");`),l.push(`${y}for (let i = 0; i < ${i}.length; i += 4) {`),l.push(`${y}  ${i} += ${r}[i] + ' ' + ${r}[i + 1] + ' ' + ${r}[i + 2] + ' ';`),l.push(`${y}}`),l.push(`${y}if (typeof require !== "undefined") {`),l.push(`${y}  require('fs').writeFileSync('./${u}.ppm', ${i});`),l.push(`${y}}`),x++}function w(e){l.push(`${y}// ${e}`)}function k(){l.push(`${y}(() => {\n${y}const error = ${n}.getError();\n${y}if (error !== ${n}.NONE) {\n${y}  const names = Object.getOwnPropertyNames(gl);\n${y}  for (let i = 0; i < names.length; i++) {\n${y}    const name = names[i];\n${y}    if (${n}[name] === error) {\n${y}      throw new Error('${n} threw ' + name);\n${y}    }\n${y}  }\n${y}}\n${y}})();`)}function I(e,t){return`${n}.${e}(${s(t,{contextName:n,contextVariables:m,getEntity:S,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})})`}function D(e){if(h)for(const t in h)if(h[t]===e)return t;return null}function C(e){const t=m.indexOf(e);return-1!==t?`${n}Variable${t}`:null}}function i(e,t){const n=new Proxy(e,{get:function(t,n){if("function"==typeof t[n])return function(){if("drawBuffersWEBGL"===n)return h.push(`${p}${i}.drawBuffersWEBGL([${s(arguments[0],{contextName:i,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[n].apply(e,arguments);switch(typeof t){case"undefined":return void h.push(`${p}${f(n,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(a(t))?(h.push(`${p}const ${i}Variable${o.length} = ${f(n,arguments)};`),o.push(t=a(t))):(h.push(`${p}const ${i}Variable${o.length} = ${f(n,arguments)};`),o.push(t));break;default:null===t?h.push(`${f(n,arguments)};`):h.push(`${p}const ${i}Variable${o.length} = ${f(n,arguments)};`),o.push(t)}return t};return r[e[n]]=n,e[n]}}),r={},{contextName:i,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return n;function m(e){return r.hasOwnProperty(e)?`${i}.${r[e]}`:u(e)}function f(e,t){return`${i}.${e}(${s(t,{contextName:i,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})})`}function g(e,t){const n=`${i}Variable${o.length}`;return o.push(e),h.push(`${p}const ${n} = ${t};`),n}}function s(e,t){const{variables:n,onUnrecognizedArgumentLookup:r}=t;return Array.from(e).map((e=>{const i=function(e){if(n)for(const t in n)if(n.hasOwnProperty(t)&&n[t]===e)return t;if(r)return r(e);return null}(e);return i||function(e,t){const{contextName:n,contextVariables:r,getEntity:i,addVariable:s,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=r.indexOf(e);if(o>-1)return`${n}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),n=/'/.test(e),r=/"/.test(e);return t?"`"+e+"`":n&&!r?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return i(e);case"Array":return s(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return s(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)})).join(", ")}function a(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:i}),"undefined"!=typeof window&&(r.glExtensionWiretap=i,window.glWiretap=r)},{}],4:[function(e,t,n){function r(e){const t=new Array(e.length);for(let n=0;n{e.output=h(t),e.graphical&&l(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&l(e),e.exec=function(){return new Promise(((t,n)=>{try{t(e.apply(e,arguments))}catch(e){n(e)}}))},e.getPixels=t=>{const{x:n,y:r}=e.output;return t?function(e,t,n){const r=n/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,n=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let r=0;r0&&t.push(", "),t.push("user_"),t.push(n)}t.push(") {\n")}for(let n=0;n0&&t.push(n.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const n=this.getDeclaration(e.left);if(n&&!n.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);return this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let n=0;n0&&t.push(",");const r=n[e],i=this.getDeclaration(r.id);i.valueType||(i.valueType=this.getType(r.init)),this.astGeneric(r,t)}return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:n,cases:r}=e;t.push("switch ("),this.astGeneric(n,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(r[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(r[e].consequent,t),r[e].consequent&&r[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:n,type:r,property:i,xProperty:s,yProperty:a,zProperty:o,name:u,origin:l}=this.getMemberExpressionDetails(e);switch(n){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":default:throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===l)return t.push(Math[u]),t;switch(i){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;case"fn()[][]":return this.astGeneric(e.object.object,t),t.push("["),this.astGeneric(e.object.property,t),t.push("]"),t.push("["),this.astGeneric(e.property,t),t.push("]"),t}if(!e.computed)switch(r){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const h=`${l}_${u}`;{let e,n;if("constants"===l){const t=this.constants[u];n="Input"===this.constantTypes[u],e=n?t.size:null}else n=this.isInput(u),e=n?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${h}`),o&&a?n?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):a?n?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):void 0!==s&&(t.push("["),this.astGeneric(s,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let n=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n);this.isAstMathFunction(e);this.onFunctionCall&&this.onFunctionCall(this.name,n,e.arguments),t.push(n),t.push("(");const r=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", "),this.astGeneric(s,t)}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length,i=[];for(let t=0;t{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});i.push("    _imageData,","    _colorData,",`    color: ${t},`),s.push(`  kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[n].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});s.push(t),i.push("    _mediaTo2DArray,"),i.push("    _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=r.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});s.push(t),i.push("    _mediaTo2DArray,")}return`function(settings) {\n${n.join("\n")}\n  for (const p in _constantTypes) {\n    if (!_constantTypes.hasOwnProperty(p)) continue;\n    const type = _constantTypes[p];\n    switch (type) {\n      case 'Number':\n      case 'Integer':\n      case 'Float':\n      case 'Boolean':\n      case 'Array(2)':\n      case 'Array(3)':\n      case 'Array(4)':\n      case 'Matrix(2)':\n      case 'Matrix(3)':\n      case 'Matrix(4)':\n        if (incomingConstants.hasOwnProperty(p)) {\n          console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n        }\n        continue;\n    }\n    if (!incomingConstants.hasOwnProperty(p)) {\n      throw new Error('constant ' + p + ' not found');\n    }\n    _constants[p] = incomingConstants[p];\n  }\n  const kernel = (function() {\n${e._kernelString}\n  })\n    .apply({ ${i.join("\n")} });\n  ${s.join("\n")}\n  return kernel;\n}`}}},{"../../utils":114}],8:[function(e,t,n){const{Kernel:r}=e("../kernel"),{FunctionBuilder:i}=e("../function-builder"),{CPUFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),{cpuKernelString:o}=e("./kernel-string");t.exports={CPUKernel:class extends r{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(e){return e}static getSignature(e,t){return"cpu"+(t.length>0?":"+t.join(","):"")}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this._prependedString=[],this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d"):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=a.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${n}[x] = subKernelResult_${n};\n`:`result_${n}[x] = subKernelResult_${n};\n`)}this.followingReturnStatement=e.join("")}const e=i.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const n=t[0],r=t[1]||1;e.width=n,e.height=r,this._imageData=this.context.createImageData(n,r),this._colorData=new Uint8ClampedArray(n*r*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments),this.built=!0}color(e,t,n,r){void 0===r&&(r=1),e=Math.floor(255*e),t=Math.floor(255*t),n=Math.floor(255*n),r=Math.floor(255*r);const i=this.output[0],s=this.output[1],a=this.thread.x+(s-this.thread.y-1)*i;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=n,this._colorData[4*a+3]=r}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter((t=>/^function/.test(t)?t:(e=t,!1))):e=t.shift(),this._kernelString=`  const LOOP_MAX = ${this._getLoopMaxString()};\n  ${this.injectedNative||""}\n  const _this = this;\n  ${this._resultKernelHeader()}\n  ${this._processConstants()}\n  return (${this.argumentNames.map((e=>"user_"+e)).join(", ")}) => {\n    ${this._prependedString.join("")}\n    ${this._earlyThrows()}\n    ${this._processArguments()}\n    ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n    ${t.length>0?t.join("\n"):""}\n  };`}toString(){return o(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants){switch(this.constantTypes[t]){case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":e.push(`    const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(`    const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(`    const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(`    const constants_${t} = this.constants.${t};\n`)}}return e.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const e=[];for(let t=0;t`user_${r} === result_${e.name}`)).join(" || ");t.push(`user_${r} === result${i?` || ${i}`:""}`)}return`if (${t.join(" || ")}) throw new Error('Source and destination arrays are the same.  Use immutable = true');`}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,r=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(n);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`)).join("    ")}\n    ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join("    ")}\n    for (let x = 0; x < outputX; x++) {\n      this.thread.x = x;\n      this.thread.y = 0;\n      this.thread.z = 0;\n      ${e}\n    }`}_mutableKernel1DResults(){const e=this._getKernelResultTypeConstructorString();return`  const outputX = _this.output[0];\n    const result = new ${e}(outputX);\n    ${this._mapSubKernels((t=>`const result_${t.name} = new ${e}(outputX);\n`)).join("    ")}\n    ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join("    ")}`}_resultMutableKernel1DLoop(e){return`  const outputX = _this.output[0];\n    for (let x = 0; x < outputX; x++) {\n      this.thread.x = x;\n      this.thread.y = 0;\n      this.thread.z = 0;\n      ${e}\n    }`}_resultImmutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    const result = new Array(outputY);\n    ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputY);\n`)).join("    ")}\n    ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join("    ")}\n    for (let y = 0; y < outputY; y++) {\n      this.thread.z = 0;\n      this.thread.y = y;\n      const resultX = result[y] = new ${t}(outputX);\n      ${this._mapSubKernels((e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`)).join("")}\n      for (let x = 0; x < outputX; x++) {\n        this.thread.x = x;\n        ${e}\n      }\n    }`}_mutableKernel2DResults(){const e=this._getKernelResultTypeConstructorString();return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    const result = new Array(outputY);\n    ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputY);\n`)).join("    ")}\n    ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join("    ")}\n    for (let y = 0; y < outputY; y++) {\n      const resultX = result[y] = new ${e}(outputX);\n      ${this._mapSubKernels((t=>`const resultX_${t.name} = result_${t.name}[y] = new ${e}(outputX);\n`)).join("")}\n    }`}_resultMutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    for (let y = 0; y < outputY; y++) {\n      this.thread.z = 0;\n      this.thread.y = y;\n      const resultX = result[y];\n      ${this._mapSubKernels((e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`)).join("")}\n      for (let x = 0; x < outputX; x++) {\n        this.thread.x = x;\n        ${e}\n      }\n    }`}_graphicalKernel2DLoop(e){return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    for (let y = 0; y < outputY; y++) {\n      this.thread.z = 0;\n      this.thread.y = y;\n      for (let x = 0; x < outputX; x++) {\n        this.thread.x = x;\n        ${e}\n      }\n    }`}_resultImmutableKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    const outputZ = _this.output[2];\n    const result = new Array(outputZ);\n    ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputZ);\n`)).join("    ")}\n    ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join("    ")}\n    for (let z = 0; z < outputZ; z++) {\n      this.thread.z = z;\n      const resultY = result[z] = new Array(outputY);\n      ${this._mapSubKernels((e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`)).join("      ")}\n      for (let y = 0; y < outputY; y++) {\n        this.thread.y = y;\n        const resultX = resultY[y] = new ${t}(outputX);\n        ${this._mapSubKernels((e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`)).join("        ")}\n        for (let x = 0; x < outputX; x++) {\n          this.thread.x = x;\n          ${e}\n        }\n      }\n    }`}_mutableKernel3DResults(){const e=this._getKernelResultTypeConstructorString();return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    const outputZ = _this.output[2];\n    const result = new Array(outputZ);\n    ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputZ);\n`)).join("    ")}\n    ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join("    ")}\n    for (let z = 0; z < outputZ; z++) {\n      const resultY = result[z] = new Array(outputY);\n      ${this._mapSubKernels((e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`)).join("      ")}\n      for (let y = 0; y < outputY; y++) {\n        const resultX = resultY[y] = new ${e}(outputX);\n        ${this._mapSubKernels((t=>`const resultX_${t.name} = resultY_${t.name}[y] = new ${e}(outputX);\n`)).join("        ")}\n      }\n    }`}_resultMutableKernel3DLoop(e){return`  const outputX = _this.output[0];\n    const outputY = _this.output[1];\n    const outputZ = _this.output[2];\n    for (let z = 0; z < outputZ; z++) {\n      this.thread.z = z;\n      const resultY = result[z];\n      for (let y = 0; y < outputY; y++) {\n        this.thread.y = y;\n        const resultX = resultY[y];\n        for (let x = 0; x < outputX; x++) {\n          this.thread.x = x;\n          ${e}\n        }\n      }\n    }`}_kernelOutput(){return this.subKernels?`\n    return {\n      result: result,\n      ${this.subKernels.map((e=>`${e.property}: result_${e.name}`)).join(",\n      ")}\n    };`:"\n    return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=i.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,n]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,n),this._colorData=new Uint8ClampedArray(t*n*4))}prependString(e){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(e)}hasPrependString(e){return this._prependedString.indexOf(e)>-1}}}},{"../../utils":114,"../function-builder":9,"../kernel":36,"./function-node":6,"./kernel-string":7}],9:[function(e,t,n){class r{static fromKernel(e,t,n){const{kernelArguments:i,kernelConstants:s,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:h,debug:c,loopMaxIterations:p,nativeFunctions:d,output:m,optimizeFloatMemory:f,precision:g,plugins:x,source:y,subKernels:b,functions:T,leadingReturnStatement:v,followingReturnStatement:S,dynamicArguments:A,dynamicOutput:_}=e,E=new Array(i.length),w={};for(let e=0;eG.needsArgumentType(e,t),I=(e,t,n)=>{G.assignArgumentType(e,t,n)},D=(e,t,n)=>G.lookupReturnType(e,t,n),C=e=>G.lookupFunctionArgumentTypes(e),$=(e,t)=>G.lookupFunctionArgumentName(e,t),L=(e,t)=>G.lookupFunctionArgumentBitRatio(e,t),R=(e,t,n,r)=>{G.assignArgumentType(e,t,n,r)},F=(e,t,n,r)=>{G.assignArgumentBitRatio(e,t,n,r)},N=(e,t,n)=>{G.trackFunctionCall(e,t,n)},V=(e,n)=>{const r=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:m,plugins:x,constants:l,constantTypes:w,constantBitRatios:h,optimizeFloatMemory:f,precision:g,lookupReturnType:D,lookupFunctionArgumentTypes:C,lookupFunctionArgumentName:$,lookupFunctionArgumentBitRatio:L,needsArgumentType:k,assignArgumentType:I,triggerImplyArgumentType:R,triggerImplyArgumentBitRatio:F,onFunctionCall:N,onNestedFunction:V}))));let K=null;b&&(K=b.map((e=>{const{name:n,source:r}=e;return new t(r,Object.assign({},M,{name:n,isSubKernel:!0,isRootKernel:!1}))})));const G=new r({kernel:e,rootNode:z,functionNodes:P,nativeFunctions:d,subKernelNodes:K});return G}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1){const n=t.indexOf(e);if(-1===n)t.push(e);else{const e=t.splice(n,1)[0];t.push(e)}return t}const n=this.functionMap[e];if(n){const r=t.indexOf(e);if(-1===r){t.push(e),n.toString();for(let e=0;e-1){t.push(this.nativeFunctions[i].source);continue}const s=this.functionMap[r];s&&t.push(s.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map((e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)}))}fromJSON(e,t){this.functionMap={};for(let n=0;n0){const i=t.arguments;for(let t=0;t0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"Math"!==e.object.name?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||r))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0})),n=t.body[0].declarations[0].init;if(this.traceFunctionAST(n),!t)throw new Error("Failed to parse JS code");return this.ast=n}traceFunctionAST(e){const{contexts:t,declarations:n,functions:r,identifiers:i,functionCalls:a}=new s(e);this.contexts=t,this.identifiers=i,this.functionCalls=a,this.functions=r;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const n=this.getType(e.left);if(this.isState("skip-literal-correction"))return n;if("LiteralInteger"===n){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return a[n]||n;case"UpdateExpression":case"ReturnStatement":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let n;for(let e=0;e-1}isAstMathFunction(e){return"CallExpression"===e.type&&e.callee&&"MemberExpression"===e.callee.type&&e.callee.object&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&e.callee.property&&"Identifier"===e.callee.property.type&&["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"].indexOf(e.callee.property.name)>-1}isAstVariable(e){return"Identifier"===e.type||"MemberExpression"===e.type}isSafe(e){return this.isSafeDependencies(this.getDependencies(e))}isSafeDependencies(e){return!e||!e.every||e.every((e=>e.isSafe))}getDependencies(e,t,n){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let r=0;r-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,n);case"Identifier":const r=this.getDeclaration(e);if(r)t.push({name:e.name,origin:"declaration",isSafe:!n&&this.isSafeDependencies(r.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,n);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":case"LogicalExpression":return n="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,n),this.getDependencies(e.right,t,n),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,n);case"VariableDeclaration":return this.getDependencies(e.declarations,t,n);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const i=this.getMemberExpressionDetails(e);switch(i.signature){case"value[]":this.getDependencies(e.object,t,n);break;case"value[][]":this.getDependencies(e.object.object,t,n);break;case"value[][][]":this.getDependencies(e.object.object.object,t,n);break;case"this.output.value":this.dynamicOutput&&t.push({name:i.name,origin:"output",isSafe:!1})}if(i)return i.property&&this.getDependencies(i.property,t,n),i.xProperty&&this.getDependencies(i.xProperty,t,n),i.yProperty&&this.getDependencies(i.yProperty,t,n),i.zProperty&&this.getDependencies(i.zProperty,t,n),t;case"SequenceExpression":return this.getDependencies(e.expressions,t,n);default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e,t){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const n=[];for(;e;)e.computed?n.push("[]"):"ThisExpression"===e.type?n.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?n.unshift(t?"."+e.property.name:".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?n.unshift("."+e.property.name):n.unshift(t?"."+e.property.name:".value"):e.name?n.unshift(t?e.name:"value"):e.callee&&e.callee.name?n.unshift(t?e.callee.name+"()":"fn()"):e.elements?n.unshift("[]"):n.unshift("unknown"),e=e.object;const r=n.join("");if(t)return r;return["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"].indexOf(r)>-1?r:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let n=0;n0?r[r.length-1]:0;return new Error(`${e} on line ${r.length}, position ${s.length}:\n ${n}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t1?t.push("(",r.join(","),")"):t.push(r[0]),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)||(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator))),t}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,n=null;const r=this.getVariableSignature(e);switch(r){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:r,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return t=e.property.name,{name:t,origin:"Math",type:"Number",signature:r};switch(e.property.name){case"r":case"g":case"b":case"a":return t=e.object.name,{name:t,property:e.property.name,origin:"user",signature:r,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"fn()[][]":case"[][]":return{signature:r,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const n=t[0];if("VariableDeclarator"===n.type&&n.id&&n.id.name&&n.id.name===e.name)return n;if(t.shift(),n.argument)t.push(n.argument);else if(n.body)t.push(n.body);else if(n.declarations)t.push(n.declarations);else if(Array.isArray(n))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let n=0;n0?e[e.length-1]:null}const s="trackIdentifiers",a="memberExpression",o="inForLoopInit";t.exports={FunctionTracer:class{constructor(e){this.runningContexts=[],this.functionContexts=[],this.contexts=[],this.functionCalls=[],this.declarations=[],this.identifiers=[],this.functions=[],this.returnStatements=[],this.trackedIdentifiers=null,this.states=[],this.newFunctionContext(),this.scan(e)}isState(e){return this.states[this.states.length-1]===e}hasState(e){return this.states.indexOf(e)>-1}pushState(e){this.states.push(e)}popState(e){if(!this.isState(e))throw new Error(`Cannot pop the non-active state "${e}"`);this.states.pop()}get currentFunctionContext(){return i(this.functionContexts)}get currentContext(){return i(this.runningContexts)}newFunctionContext(){const e={"@contextType":"function"};this.contexts.push(e),this.functionContexts.push(e)}newContext(e){const t=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e();const{currentFunctionContext:n}=this;for(const e in n)n.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=n[e]);return this.runningContexts.pop(),t}useFunctionContext(e){const t=i(this.functionContexts);this.runningContexts.push(t),e(),this.runningContexts.pop()}getIdentifiers(e){const t=this.trackedIdentifiers=[];return this.pushState(s),e(),this.trackedIdentifiers=null,this.popState(s),t}getDeclaration(e){const{currentContext:t,currentFunctionContext:n,runningContexts:r}=this,i=t[e]||n[e]||null;if(!i&&t===n&&r.length>0){const t=r[r.length-2];if(t[e])return t[e]}return i}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)}));break;case"BlockStatement":this.newContext((()=>{this.scan(e.body)}));break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":if("++"===e.operator){const t=this.getDeclaration(e.argument.name);t&&(t.suggestedType="Integer")}this.scan(e.argument);break;case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":"var"===e.kind?this.useFunctionContext((()=>{e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations)})):(e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations));break;case"VariableDeclarator":{const{currentContext:t}=this,n=this.hasState(o),r={ast:e,context:t,name:e.id.name,origin:"declaration",inForLoopInit:n,inForLoopTest:null,assignable:t===this.currentFunctionContext||!n&&!t.hasOwnProperty(e.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};t[e.id.name]||(t[e.id.name]=r),this.declarations.push(r),this.scan(e.id),this.scan(e.init);break}case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":{let t;const n=this.newContext((()=>{this.pushState(o),this.scan(e.init),this.popState(o),t=this.getIdentifiers((()=>{this.scan(e.test)})),this.scan(e.update),this.newContext((()=>{this.scan(e.body)}))}));if(t)for(const e in n)"@contextType"!==e&&t.indexOf(e)>-1&&(n[e].inForLoopTest=!0);break}case"DoWhileStatement":case"WhileStatement":this.newContext((()=>{this.scan(e.body),this.scan(e.test)}));break;case"Identifier":this.isState(s)&&this.trackedIdentifiers.push(e.name),this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(e.name),ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.pushState(a),this.scan(e.object),this.scan(e.property),this.popState(a);break;case"ExpressionStatement":this.scan(e.expression);break;case"SequenceExpression":this.scan(e.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}},{"../utils":114}],12:[function(e,t,n){const{glWiretap:r}=e("gl-wiretap"),{utils:i}=e("../../utils");function s(e){return e.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const n="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${n}, ${t.output[0]})`}function o(e,t,n){const r=e.toArray.toString(),s=!/^function/.test(r);return`() => {\n  function framebuffer() { return ${n}; };\n  ${i.flattenFunctionToString(`${s?"function ":""}${r}`,{findDependency:(t,n)=>{if("utils"===t)return`const ${n} = ${i[n].toString()};`;if("this"===t)return"framebuffer"===n?"":`${s?"function ":""}${e[n].toString()}`;throw new Error("unhandled fromObject")},thisLookup:(n,r)=>{if("texture"===n)return t;if("context"===n)return r?null:"gl";if(e.hasOwnProperty(n))return JSON.stringify(e[n]);throw new Error(`unhandled thisLookup ${n}`)}})}\n  return toArray();\n  }`}function u(e,t,n,r,i){if(null===e)return null;if(null===t)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement)for(let i=0;i{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}})):null;const c=[],p=[],d=r(n.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(N.subKernels){if(m){const t=N.subKernels[f++].property;p.push(`    result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,N)};`)}else p.push(`    const result = { result: ${a(e,N)} };`),m=!0;f===N.subKernels.length&&p.push("    return result;")}else e?p.push(`    return ${a(e,N)};`):p.push("    return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,N.kernelArguments,[],d,c);if(t)return t;const n=u(e,N.kernelConstants,S?Object.keys(S).map((e=>S[e])):[],d,c);return n||null}});let m=!1,f=0;const{source:g,canvas:x,output:y,pipeline:b,graphical:T,loopMaxIterations:v,constants:S,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:k,subKernels:I,immutable:D,argumentTypes:C,constantTypes:$,kernelArguments:L,kernelConstants:R,tactic:F}=n,N=new e(g,{canvas:x,context:d,checkContext:!1,output:y,pipeline:b,graphical:T,loopMaxIterations:v,constants:S,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:k,subKernels:I,immutable:D,argumentTypes:C,constantTypes:$,tactic:F});let V=[];if(d.setIndent(2),N.build.apply(N,t),V.push(d.toString()),d.reset(),N.kernelArguments.forEach(((e,n)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":case"Input":d.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let r=0;re.varName)).join(", ")}) {`),d.setIndent(4),N.run.apply(N,t),N.renderKernels?N.renderKernels():N.renderOutput&&N.renderOutput(),V.push("    /** start setup uploads for kernel values **/"),N.kernelArguments.forEach((e=>{V.push("    "+e.getStringValueHandler().split("\n").join("\n    "))})),V.push("    /** end setup uploads for kernel values **/"),V.push(d.toString()),N.renderOutput===N.renderTexture){d.reset();const e=d.getContextVariableName(N.framebuffer);if(N.renderKernels){const t=N.renderKernels(),n=d.getContextVariableName(N.texture.texture);V.push(`    return {\n      result: {\n        texture: ${n},\n        type: '${t.result.type}',\n        toArray: ${o(t.result,n,e)}\n      },`);const{subKernels:r,mappedTextures:i}=N;for(let n=0;n"utils"===e?`const ${t} = ${i[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(N)),V.push("  innerKernel.getPixels = getPixels;")),V.push("  return innerKernel;");let M=[];return R.forEach((e=>{M.push(`${e.getStringValueHandler()}`)})),`function kernel(settings) {\n  const { context, constants } = settings;\n  ${M.join("")}\n  ${l||""}\n${V.join("\n")}\n}`}}},{"../../utils":114,"gl-wiretap":3}],13:[function(e,t,n){const{Kernel:r}=e("../kernel"),{utils:i}=e("../../utils"),{GLTextureArray2Float:s}=e("./texture/array-2-float"),{GLTextureArray2Float2D:a}=e("./texture/array-2-float-2d"),{GLTextureArray2Float3D:o}=e("./texture/array-2-float-3d"),{GLTextureArray3Float:u}=e("./texture/array-3-float"),{GLTextureArray3Float2D:l}=e("./texture/array-3-float-2d"),{GLTextureArray3Float3D:h}=e("./texture/array-3-float-3d"),{GLTextureArray4Float:c}=e("./texture/array-4-float"),{GLTextureArray4Float2D:p}=e("./texture/array-4-float-2d"),{GLTextureArray4Float3D:d}=e("./texture/array-4-float-3d"),{GLTextureFloat:m}=e("./texture/float"),{GLTextureFloat2D:f}=e("./texture/float-2d"),{GLTextureFloat3D:g}=e("./texture/float-3d"),{GLTextureMemoryOptimized:x}=e("./texture/memory-optimized"),{GLTextureMemoryOptimized2D:y}=e("./texture/memory-optimized-2d"),{GLTextureMemoryOptimized3D:b}=e("./texture/memory-optimized-3d"),{GLTextureUnsigned:T}=e("./texture/unsigned"),{GLTextureUnsigned2D:v}=e("./texture/unsigned-2d"),{GLTextureUnsigned3D:S}=e("./texture/unsigned-3d"),{GLTextureGraphical:A}=e("./texture/graphical");const _={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends r{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n      return 1;\n    }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),2===n[0]&&1511===n[1]}static getIsSpeedTacticSupported(){const e=new this(function(e){return e[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[4],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[0,1,2,3]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),0===Math.round(n[0])&&1===Math.round(n[1])&&2===Math.round(n[2])&&3===Math.round(n[3])}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static getFeatures(){const e=this.testContext,t=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:t,kernelMap:t,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}static getSignature(e,t){return e.getVariablePrecisionString()+(t.length>0?":"+t.join(","):"")}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return i.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],n=[],r=[],i=/^[a-zA-Z_]/,s=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?r[r.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"*"!==h)if("MULTI_LINE_COMMENT"!==c||"*"!==l||"/"!==h)if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"/"!==h)if("COMMENT"!==c||"\n"!==l)if(null!==c||"("!==l){if("FUNCTION_ARGUMENTS"===c){if(")"===l){r.pop();break}if("f"===l&&"l"===h&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){r.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===l&&"n"===h&&"t"===e[a+2]&&" "===e[a+3]){r.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===l){a++;continue}if(!i.test(l))throw new Error("variable name is not expected string")}o+=l,s.test(h)||(r.pop(),n.push(o),t.push(_[u]))}a++}else r.push("FUNCTION_ARGUMENTS"),a++;else r.pop(),a++;else r.push("COMMENT"),a+=2;else r.pop(),a+=2;else r.push("MULTI_LINE_COMMENT"),a+=2}if(r.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:n,argumentTypes:t}}static nativeFunctionReturnType(e){return _[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:n,context:r,threadDim:s}=t.texSize;let a;if("single"===t.precision){const e=n[0],t=Math.ceil(n[1]/4);a=new Float32Array(e*t*4*4),r.readPixels(0,0,e,4*t,r.RGBA,r.FLOAT,a)}else{const e=new Uint8Array(n[0]*n[1]*4);r.readPixels(0,0,n[0],n[1],r.RGBA,r.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}if(a=a.subarray(0,s[0]*s[1]*s[2]),1===t.output.length)return a;if(2===t.output.length)return i.splitArray(a,t.output[0]);if(3===t.output.length){return i.splitArray(a,t.output[0]*t.output[1]).map((function(e){return i.splitArray(e,t.output[0])}))}}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.switchingKernels=null,this._textureSwitched=null,this._mappedTextureSwitched=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=A,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=S,null):this.output[1]>0?(this.TextureConstructor=v,null):(this.TextureConstructor=T,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=S,this.formatValues=i.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=v,this.formatValues=i.erect2DPackedFloat,null):(this.TextureConstructor=T,this.formatValues=i.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=b,null):this.output[1]>0?(this.TextureConstructor=y,null):(this.TextureConstructor=x,null):this.output[2]>0?(this.TextureConstructor=g,null):this.output[1]>0?(this.TextureConstructor=f,null):(this.TextureConstructor=m,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,null):this.output[1]>0?(this.TextureConstructor=a,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,null):this.output[1]>0?(this.TextureConstructor=l,null):(this.TextureConstructor=u,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,null):this.output[1]>0?(this.TextureConstructor=p,null):(this.TextureConstructor=c,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=b,this.formatValues=i.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=y,this.formatValues=i.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=x,this.formatValues=i.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=c,this.formatValues=i.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=g,this.formatValues=i.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=f,this.formatValues=i.erect2DFloat,null):(this.TextureConstructor=m,this.formatValues=i.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=c,this.formatValues=i.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return i.linesToString(this.getMainResultKernelNumberTexture())+i.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return i.linesToString(this.getMainResultKernelArray2Texture())+i.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return i.linesToString(this.getMainResultKernelArray3Texture())+i.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return i.linesToString(this.getMainResultKernelArray4Texture())+i.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} float;\n`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,!0)} int;\n`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D;\n`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray;\n`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,n=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,n),n}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,n=e[0],r=e[1],i=new Float32Array(n*r*4);return t.readPixels(0,0,n,r,t.RGBA,t.FLOAT,i),i}getPixels(e){const{context:t,output:n}=this,[r,s]=n,a=new Uint8Array(r*s*4);return t.readPixels(0,0,r,s,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:i.flipPixels(a,r,s)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0){for(let e=0;e0){const{mappedTextures:n}=this;for(let r=0;r1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:n,kernel:r}=this;r.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),i(e,n),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,n,0);const s=e.createTexture();i(e,s),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t[0],t[1]),s._refs=1,this.texture=s}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const n=e.createTexture();i(e,n),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),n._refs=1,this.texture=n}clear(){if(this.texture._refs){this.texture._refs--;const e=this.context,t=this.texture=e.createTexture();i(e,t);const n=this.size;t._refs=1,e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,n[0],n[1],0,this.textureFormat,this.textureType,null)}const{context:e,texture:t}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.bindTexture(e.TEXTURE_2D,t),i(e,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}delete(){this._deleted||(this._deleted=!0,this.texture._refs&&(this.texture._refs--,this.texture._refs)||this.context.deleteTexture(this.texture))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}},{"../../../texture":113}],28:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized2D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":114,"./float":25}],29:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized3D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":114,"./float":25}],30:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":114,"./float":25}],31:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned2D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":114,"./unsigned":33}],32:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned3D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":114,"./unsigned":33}],33:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTexture:i}=e("./index");t.exports={GLTextureUnsigned:class extends i{get textureType(){return this.context.UNSIGNED_BYTE}constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const t=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,t),t}renderValues(){return this._deleted?null:new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":114,"./index":27}],34:[function(e,t,n){const r=e("gl"),{WebGLKernel:i}=e("../web-gl/kernel"),{glKernelString:s}=e("../gl/kernel-string");let a=null,o=null,u=null,l=null,h=null;t.exports={HeadlessGLKernel:class extends i{static get isSupported(){return null!==a||(this.setupFeatureChecks(),a=null!==u),a}static setupFeatureChecks(){if(o=null,l=null,"function"==typeof r)try{if(u=r(2,2,{preserveDrawingBuffer:!0}),!u||!u.getExtension)return;l={STACKGL_resize_drawingbuffer:u.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:u.getExtension("STACKGL_destroy_context"),OES_texture_float:u.getExtension("OES_texture_float"),OES_texture_float_linear:u.getExtension("OES_texture_float_linear"),OES_element_index_uint:u.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:u.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:u.getExtension("WEBGL_color_buffer_float")},h=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getIsTextureFloat(){return Boolean(l.OES_texture_float)}static getIsDrawBuffers(){return Boolean(l.WEBGL_draw_buffers)}static getChannelCount(){return l.WEBGL_draw_buffers?u.getParameter(l.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return u.getParameter(u.MAX_TEXTURE_SIZE)}static get testCanvas(){return o}static get testContext(){return u}static get features(){return h}initCanvas(){return{}}initContext(){return r(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return s(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n","    if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){return super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1]),this}}}},{"../gl/kernel-string":12,"../web-gl/kernel":70,gl:2}],35:[function(e,t,n){t.exports={KernelValue:class{constructor(e,t){const{name:n,kernel:r,context:i,checkContext:s,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:l,type:h,tactic:c}=t;if(!n)throw new Error("name not set");if(!h)throw new Error("type not set");if(!u)throw new Error("origin not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=n,this.origin=u,this.tactic=c,this.varName="constants"===u?`constants.${n}`:n,this.kernel=r,this.strictIntegers=l,this.type=e.type||h,this.size=e.size||null,this.index=null,this.context=i,this.checkContext=null==s||s,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}},{}],36:[function(e,t,n){const{utils:r}=e("../utils"),{Input:i}=e("../input");t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!r.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.argumentNames="string"==typeof e?r.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.precision=null,this.tactic=null,this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.built=!1,this.signature=null}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":this.functions=[];for(let t=0;te.name)):null,returnType:this.returnType}}}buildSignature(e){const t=this.constructor;this.signature=t.getSignature(this,t.getArgumentTypes(this,e))}static getArgumentTypes(e,t){const n=new Array(t.length);for(let i=0;it.argumentTypes[e]))||[]:t.argumentTypes||[],{name:r.getFunctionNameFromString(n)||null,source:n,argumentTypes:i,returnType:t.returnType||null}}onActivate(e){}}}},{"../input":110,"../utils":114}],37:[function(e,t,n){const r=`__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nfloat acosh(float x) {\n  return log(x + sqrt(x * x - 1.0));\n}\n\nfloat sinh(float x) {\n  return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;\n}\n\nfloat asinh(float x) {\n  return log(x + sqrt(x * x + 1.0));\n}\n\nfloat atan2(float v1, float v2) {\n  if (v1 == 0.0 || v2 == 0.0) return 0.0;\n  return atan(v1 / v2);\n}\n\nfloat atanh(float x) {\n  x = (x + 1.0) / (x - 1.0);\n  if (x < 0.0) {\n    return 0.5 * log(-x);\n  }\n  return 0.5 * log(x);\n}\n\nfloat cbrt(float x) {\n  if (x >= 0.0) {\n    return pow(x, 1.0 / 3.0);\n  } else {\n    return -pow(x, 1.0 / 3.0);\n  }\n}\n\nfloat cosh(float x) {\n  return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; \n}\n\nfloat expm1(float x) {\n  return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n  return x;\n}\n\nfloat imul(float v1, float v2) {\n  return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n  return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n  return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n  if (v2 == 0.0) return 1.0;\n  return pow(v1, v2);\n}\n\nfloat tanh(float x) {\n  float e = exp(2.0 * x);\n  return (e - 1.0) / (e + 1.0);\n}\n\nfloat trunc(float x) {\n  if (x >= 0.0) {\n    return floor(x); \n  } else {\n    return ceil(x);\n  }\n}\n\nvec4 _round(vec4 x) {\n  return floor(x + 0.5);\n}\n\nfloat _round(float x) {\n  return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n  return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n  int result = 0;\n  int n = 1;\n  \n  for (int i = 0; i < BIT_COUNT; i++) {\n    if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n      result += n;\n    }\n    a = a / 2;\n    b = b / 2;\n    n = n * 2;\n    if(!(a > 0 || b > 0)) {\n      break;\n    }\n  }\n  return result;\n}\nint bitwiseXOR(int a, int b) {\n  int result = 0;\n  int n = 1;\n  \n  for (int i = 0; i < BIT_COUNT; i++) {\n    if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n      result += n;\n    }\n    a = a / 2;\n    b = b / 2;\n    n = n * 2;\n    if(!(a > 0 || b > 0)) {\n      break;\n    }\n  }\n  return result;\n}\nint bitwiseAnd(int a, int b) {\n  int result = 0;\n  int n = 1;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n      result += n;\n    }\n    a = a / 2;\n    b = b / 2;\n    n = n * 2;\n    if(!(a > 0 && b > 0)) {\n      break;\n    }\n  }\n  return result;\n}\nint bitwiseNot(int a) {\n  int result = 0;\n  int n = 1;\n  \n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (modi(a, 2) == 0) {\n      result += n;    \n    }\n    a = a / 2;\n    n = n * 2;\n  }\n  return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n  int maxBytes = BIT_COUNT;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (maxBytes >= n) {\n      break;\n    }\n    maxBytes *= 2;\n  }\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= shift) {\n      break;\n    }\n    n *= 2;\n  }\n\n  int result = 0;\n  int byteVal = 1;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= maxBytes) break;\n    if (modi(n, 2) > 0) { result += byteVal; }\n    n = int(n / 2);\n    byteVal *= 2;\n  }\n  return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n  return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n  int maxBytes = BIT_COUNT;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (maxBytes >= n) {\n      break;\n    }\n    maxBytes *= 2;\n  }\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= shift) {\n      break;\n    }\n    n /= 2;\n  }\n  int result = 0;\n  int byteVal = 1;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= maxBytes) break;\n    if (modi(n, 2) > 0) { result += byteVal; }\n    n = int(n / 2);\n    byteVal *= 2;\n  }\n  return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n  vec2 res = floor(mod(x, y));\n  return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n  vec3 res = floor(mod(x, y));\n  return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n  vec4 res = floor(mod(x, y));\n  return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n  float res = floor(mod(x, y));\n  return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n  return x - (y * int(x / y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n  __DECODE32_ENDIANNESS__;\n  texel *= 255.0;\n  vec2 gte128;\n  gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n  gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n  float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n  float res = exp2(_round(exponent));\n  texel.b = texel.b - 128.0 * gte128.x;\n  res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res;\n  res *= gte128.y * -2.0 + 1.0;\n  return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n  int channel = integerMod(index, 2);\n  if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n  if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n  return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n  int channel = integerMod(index, 4);\n  if (channel == 0) return texel.r * 255.0;\n  if (channel == 1) return texel.g * 255.0;\n  if (channel == 2) return texel.b * 255.0;\n  if (channel == 3) return texel.a * 255.0;\n  return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n  float F = abs(f);\n  float sign = f < 0.0 ? 1.0 : 0.0;\n  float exponent = floor(log2(F));\n  float mantissa = (exp2(-exponent) * F);\n  // exponent += floor(log2(mantissa));\n  vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n  texel.rg = integerMod(texel.rg, 256.0);\n  texel.b = integerMod(texel.b, 128.0);\n  texel.a = exponent*0.5 + 63.5;\n  texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n  texel = floor(texel);\n  texel *= 0.003921569; // 1/255\n  __ENCODE32_ENDIANNESS__;\n  return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n  if (value == 0.0) return vec4(0, 0, 0, 0);\n\n  float exponent;\n  float mantissa;\n  vec4  result;\n  float sgn;\n\n  sgn = step(0.0, -value);\n  value = abs(value);\n\n  exponent = floor(log2(value));\n\n  mantissa = value*pow(2.0, -exponent)-1.0;\n  exponent = exponent+127.0;\n  result   = vec4(0,0,0,0);\n\n  result.a = floor(exponent/2.0);\n  exponent = exponent - result.a*2.0;\n  result.a = result.a + 128.0*sgn;\n\n  result.b = floor(mantissa * 128.0);\n  mantissa = mantissa - result.b / 128.0;\n  result.b = result.b + exponent*128.0;\n\n  result.g = floor(mantissa*32768.0);\n  mantissa = mantissa - result.g/32768.0;\n\n  result.r = floor(mantissa*8388608.0);\n  return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n  int z = int(idx / (texDim.x * texDim.y));\n  idx -= z * int(texDim.x * texDim.y);\n  int y = int(idx / texDim.x);\n  int x = int(integerMod(idx, texDim.x));\n  return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture2D(tex, st / vec2(texSize));\n  return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x * 2;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n  return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x * 4;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n  return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int channel = integerMod(index, 4);\n  index = index / 4;\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture2D(tex, st / vec2(texSize));\n  if (channel == 0) return texel.r;\n  if (channel == 1) return texel.g;\n  if (channel == 2) return texel.b;\n  if (channel == 3) return texel.a;\n  return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n  return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n  return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + (texDim.x * (y + (texDim.y * z)));\n  int channel = integerMod(index, 2);\n  index = index / 2;\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture2D(tex, st / vec2(texSize));\n  if (channel == 0) return vec2(texel.r, texel.g);\n  if (channel == 1) return vec2(texel.b, texel.a);\n  return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n  return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n  int vectorIndex = fieldIndex / 4;\n  int vectorOffset = fieldIndex - vectorIndex * 4;\n  int readY = vectorIndex / texSize.x;\n  int readX = vectorIndex - readY * texSize.x;\n  vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n  \n  if (vectorOffset == 0) {\n    return tex1.xyz;\n  } else if (vectorOffset == 1) {\n    return tex1.yzw;\n  } else {\n    readX++;\n    if (readX >= texSize.x) {\n      readX = 0;\n      readY++;\n    }\n    vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n    if (vectorOffset == 2) {\n      return vec3(tex1.z, tex1.w, tex2.x);\n    } else {\n      return vec3(tex1.w, tex2.x, tex2.y);\n    }\n  }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int channel = integerMod(index, 2);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture2D(tex, st / vec2(texSize));\n  return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n  actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n  color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n  actualColor = texture2D(image, vTexCoord);\n}\n\nfloat modulo(float number, float divisor) {\n  if (number < 0.0) {\n    number = abs(number);\n    if (divisor < 0.0) {\n      divisor = abs(divisor);\n    }\n    return -mod(number, divisor);\n  }\n  if (divisor < 0.0) {\n    divisor = abs(divisor);\n  }\n  return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n  index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n  __MAIN_RESULT__;\n}`;t.exports={fragmentShader:r}},{}],38:[function(e,t,n){const{utils:r}=e("../../utils"),{FunctionNode:i}=e("../function-node");const s={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLCanvas:"sampler2D",OffscreenCanvas:"sampler2D",HTMLImage:"sampler2D",ImageBitmap:"sampler2D",ImageData:"sampler2D",HTMLImageArray:"sampler2DArray"},a={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends i{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const n=this.getType(e.consequent),r=this.getType(e.alternate);return null===n&&null===r?(t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t):(t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{if(!this.returnType){this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"))}const{returnType:n}=this;if(n){const e=s[n];if(!e)throw new Error(`unknown type ${n}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let n=0;n0&&t.push(", ");let a=this.argumentTypes[this.argumentNames.indexOf(i)];if(!a)throw this.astErrorOutput(`Unknown argument ${i} type`,e);"LiteralInteger"===a&&(this.argumentTypes[n]=a="Number");const o=s[a];if(!o)throw this.astErrorOutput("Unexpected expression",e);const u=r.sanitizeName(i);"sampler2D"===o||"sampler2DArray"===o?t.push(`${o} user_${u},ivec2 user_${u}Size,ivec3 user_${u}Dim`):t.push(`${o} user_${u}`)}t.push(") {\n");for(let n=0;n"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const n=[];this.astGeneric(e.right,n);if("Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(n.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${i}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const n=this.checkAndUpconvertBitwiseOperators(e,t);if(n)return n;const r={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const n={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!n)return null;t.push(n),t.push("(");switch(this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}t.push(",");switch(this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const n={"~":"bitwiseNot"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),i=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const n=[],r=[],i=[],s=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,n);for(let e=0;e0&&t.push(n.join(""),"\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const n=this.getInternalVariableName("safeI");return t.push(`for (int ${n}=0;${n}0&&o.push(u.join(",")),i.push(o.join(";")),t.push(i.join("")),t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){if("SwitchStatement"!==e.type)throw this.astErrorOutput("Invalid switch statement",e);const{discriminant:n,cases:r}=e,i=this.getType(n),s=`switchDiscriminant${this.astKey(e,"_")}`;switch(i){case"Float":case"Number":t.push(`float ${s} = `),this.astGeneric(n,t),t.push(";\n");break;case"Integer":t.push(`int ${s} = `),this.astGeneric(n,t),t.push(";\n")}if(1===r.length&&!r[0].test)return this.astGeneric(r[0].consequent,t),t;let a=!1,o=[],u=!1,l=!1;for(let e=0;ee+1){u=!0,this.astGeneric(r[e].consequent,o);continue}t.push(" else {\n")}this.astGeneric(r[e].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:n,name:i,signature:s,origin:a,type:o,xProperty:u,yProperty:l,zProperty:h}=this.getMemberExpressionDetails(e);switch(s){case"value.thread.value":case"this.thread.value":if("x"!==i&&"y"!==i&&"z"!==i)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${i}`),t;case"this.output.value":if(this.dynamicOutput)switch(i){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(i){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===a)return t.push(Math[i]),t;const s=r.sanitizeName(i);switch(n){case"r":return t.push(`user_${s}.r`),t;case"g":return t.push(`user_${s}.g`),t;case"b":return t.push(`user_${s}.b`),t;case"a":return t.push(`user_${s}.a`),t}break;case"this.constants.value":if(void 0===u)switch(o){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r.sanitizeName(i)}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;case"fn()[][]":return this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.object.property)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.property)),t.push("]"),t;case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(o){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${a}_${r.sanitizeName(i)}`),t}const c=`${a}_${r.sanitizeName(i)}`;switch(o){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(u)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,i):this.constantBitRatios[i];switch(e){case 1:t.push(`get8(${c}, ${c}Size, ${c}Dim, `);break;case 2:t.push(`get16(${c}, ${c}Size, ${c}Dim, `);break;case 4:case 0:t.push(`get32(${c}, ${c}Size, ${c}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,l,h,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${c}[${this.memberExpressionPropertyMarkup(l)}]`),l&&t.push(`[${this.memberExpressionPropertyMarkup(u)}]`);break;default:throw new Error(`unhandled member expression "${o}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const i=this.isAstMathFunction(e);if(n=i||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name,!n)throw this.astErrorOutput("Unhandled function, couldn't find name",e);switch(n){case"pow":n="_pow";break;case"round":n="_round"}if(this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),"Integer"===i)this.castValueToFloat(r,t);else this.astGeneric(r,t)}else{const i=this.lookupFunctionArgumentTypes(n)||[];for(let s=0;s0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,s,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("int("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("float("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){if("Identifier"===a.type)t.push(`user_${r.sanitizeName(a.name)}`);else{if("ArrayExpression"!==a.type&&"MemberExpression"!==a.type&&"CallExpression"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.astGeneric(a,t)}continue}break;case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(o===u){if("Identifier"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.triggerImplyArgumentBitRatio(this.name,a.name,n,s);const i=r.sanitizeName(a.name);t.push(`user_${i},user_${i}Size,user_${i}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length;switch(n){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`mat${r}(`);break;default:t.push(`vec${r}(`)}for(let n=0;n0&&t.push(", ");const r=e.elements[n];this.astGeneric(r,t)}return t.push(")"),t}memberExpressionXYZ(e,t,n,r){return n?r.push(this.memberExpressionPropertyMarkup(n),", "):r.push("0, "),t?r.push(this.memberExpressionPropertyMarkup(t),", "):r.push("0, "),r.push(this.memberExpressionPropertyMarkup(e)),r}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}return t.join("")}}}},{"../../utils":114,"../function-node":10}],39:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGLKernelValueFloat:i}=e("./kernel-value/float"),{WebGLKernelValueInteger:s}=e("./kernel-value/integer"),{WebGLKernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGLKernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGLKernelValueHTMLVideo:u}=e("./kernel-value/html-video"),{WebGLKernelValueDynamicHTMLVideo:l}=e("./kernel-value/dynamic-html-video"),{WebGLKernelValueSingleInput:h}=e("./kernel-value/single-input"),{WebGLKernelValueDynamicSingleInput:c}=e("./kernel-value/dynamic-single-input"),{WebGLKernelValueUnsignedInput:p}=e("./kernel-value/unsigned-input"),{WebGLKernelValueDynamicUnsignedInput:d}=e("./kernel-value/dynamic-unsigned-input"),{WebGLKernelValueMemoryOptimizedNumberTexture:m}=e("./kernel-value/memory-optimized-number-texture"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:f}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGLKernelValueNumberTexture:g}=e("./kernel-value/number-texture"),{WebGLKernelValueDynamicNumberTexture:x}=e("./kernel-value/dynamic-number-texture"),{WebGLKernelValueSingleArray:y}=e("./kernel-value/single-array"),{WebGLKernelValueDynamicSingleArray:b}=e("./kernel-value/dynamic-single-array"),{WebGLKernelValueSingleArray1DI:T}=e("./kernel-value/single-array1d-i"),{WebGLKernelValueDynamicSingleArray1DI:v}=e("./kernel-value/dynamic-single-array1d-i"),{WebGLKernelValueSingleArray2DI:S}=e("./kernel-value/single-array2d-i"),{WebGLKernelValueDynamicSingleArray2DI:A}=e("./kernel-value/dynamic-single-array2d-i"),{WebGLKernelValueSingleArray3DI:_}=e("./kernel-value/single-array3d-i"),{WebGLKernelValueDynamicSingleArray3DI:E}=e("./kernel-value/dynamic-single-array3d-i"),{WebGLKernelValueArray2:w}=e("./kernel-value/array2"),{WebGLKernelValueArray3:k}=e("./kernel-value/array3"),{WebGLKernelValueArray4:I}=e("./kernel-value/array4"),{WebGLKernelValueUnsignedArray:D}=e("./kernel-value/unsigned-array"),{WebGLKernelValueDynamicUnsignedArray:C}=e("./kernel-value/dynamic-unsigned-array"),$={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:C,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:D,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:b,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":v,"Array1D(3)":v,"Array1D(4)":v,"Array2D(2)":A,"Array2D(3)":A,"Array2D(4)":A,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:c,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:y,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:h,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u}}};t.exports={lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const i=$[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]},kernelValueMaps:$}},{"./kernel-value/array2":41,"./kernel-value/array3":42,"./kernel-value/array4":43,"./kernel-value/boolean":44,"./kernel-value/dynamic-html-image":45,"./kernel-value/dynamic-html-video":46,"./kernel-value/dynamic-memory-optimized-number-texture":47,"./kernel-value/dynamic-number-texture":48,"./kernel-value/dynamic-single-array":49,"./kernel-value/dynamic-single-array1d-i":50,"./kernel-value/dynamic-single-array2d-i":51,"./kernel-value/dynamic-single-array3d-i":52,"./kernel-value/dynamic-single-input":53,"./kernel-value/dynamic-unsigned-array":54,"./kernel-value/dynamic-unsigned-input":55,"./kernel-value/float":56,"./kernel-value/html-image":57,"./kernel-value/html-video":58,"./kernel-value/integer":60,"./kernel-value/memory-optimized-number-texture":61,"./kernel-value/number-texture":62,"./kernel-value/single-array":63,"./kernel-value/single-array1d-i":64,"./kernel-value/single-array2d-i":65,"./kernel-value/single-array3d-i":66,"./kernel-value/single-input":67,"./kernel-value/unsigned-array":68,"./kernel-value/unsigned-input":69}],40:[function(e,t,n){const{WebGLKernelValue:r}=e("./index"),{Input:i}=e("../../../input");t.exports={WebGLKernelArray:class extends r{checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:n}=this.kernel.constructor.features;if(e>n||t>n)throw e>t?new Error(`Argument texture width of ${e} larger than maximum size of ${n} for your GPU`):ee===r.name))&&t.push(r)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision=t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let n=y.indexOf(t);-1===n&&(n=y.length,y.push(t),b[n]=[e[0],e[1]]),this.maxTexSize=b[n]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:n}=this;let r=0;const i=()=>this.createTexture(),s=()=>this.constantTextureCount+r++,o=e=>{this.switchKernels({type:"argumentMismatch",needed:e})},u=()=>n.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++;for(let r=0;rthis.createTexture(),onRequestIndex:()=>r++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[i]=l.bitRatio,this.kernelConstants.push(l),l.setup(),l.forceUploadEachRun&&this.forceUploadKernelConstants.push(l)}}build(){if(this.built)return;if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:n,canvas:r}=this;n.enable(n.SCISSOR_TEST),this.pipeline&&this.precision,n.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),r.width=this.maxTexSize[0],r.height=this.maxTexSize[1];const i=this.threadDim=Array.from(this.output);for(;i.length<3;)i.push(1);const s=this.getVertexShader(arguments),a=n.createShader(n.VERTEX_SHADER);n.shaderSource(a,s),n.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=n.createShader(n.FRAGMENT_SHADER);if(n.shaderSource(u,o),n.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!n.getShaderParameter(a,n.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+n.getShaderInfoLog(a));if(!n.getShaderParameter(u,n.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+n.getShaderInfoLog(u));const l=this.program=n.createProgram();n.attachShader(l,a),n.attachShader(l,u),n.linkProgram(l),this.framebuffer=n.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1],this.rawValueFramebuffers={};const h=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=h.byteLength;let d=this.buffer;d?n.bindBuffer(n.ARRAY_BUFFER,d):(d=this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,d),n.bufferData(n.ARRAY_BUFFER,h.byteLength+c.byteLength,n.STATIC_DRAW)),n.bufferSubData(n.ARRAY_BUFFER,0,h),n.bufferSubData(n.ARRAY_BUFFER,p,c);const m=n.getAttribLocation(this.program,"aPos");n.enableVertexAttribArray(m),n.vertexAttribPointer(m,2,n.FLOAT,!1,0,0);const f=n.getAttribLocation(this.program,"aTexCoord");n.enableVertexAttribArray(f),n.vertexAttribPointer(f,2,n.FLOAT,!1,0,p),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer);let g=0;n.useProgram(this.program);for(let e in this.constants)this.kernelConstants[g++].updateValue(this.constants[e]);this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&(this._mappedTextureSwitched={},this._setupSubOutputTextures()),this.buildSignature(arguments),this.built=!0}translateSource(){const e=i.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}setupReturnTypes(e){if(this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"")).join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:n}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${n[0]}, ${n[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":"  texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":"  texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float divWithIntCheck(float x, float y) {\n  if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\n    return float(int(x) / int(y));\n  }\n  return x / y;\n}\n\nfloat integerCorrectionModulo(float number, float divisor) {\n  if (number < 0.0) {\n    number = abs(number);\n    if (divisor < 0.0) {\n      divisor = abs(divisor);\n    }\n    return -(number - (divisor * floor(divWithIntCheck(number, divisor))));\n  }\n  if (divisor < 0.0) {\n    divisor = abs(divisor);\n  }\n  return number - (divisor * floor(divWithIntCheck(number, divisor)));\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:n}=this;for(let r=0;r{if(t.hasOwnProperty(n))return t[n];throw`unhandled artifact ${n}`}))}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return h(this.constructor,arguments,this,e)}destroy(e){if(!this.context)return;this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer);for(const e in this.rawValueFramebuffers){for(const t in this.rawValueFramebuffers[e])this.context.deleteFramebuffer(this.rawValueFramebuffers[e][t]),delete this.rawValueFramebuffers[e][t];delete this.rawValueFramebuffers[e]}if(this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program),this.texture){this.texture.delete();const e=this.textureCache.indexOf(this.texture.texture);e>-1&&this.textureCache.splice(e,1),this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let e=0;e-1&&this.textureCache.splice(n,1)}this.mappedTextures=null}if(this.kernelArguments)for(let e=0;e0;){const e=this.textureCache.pop();this.context.deleteTexture(e)}if(e){const e=y.indexOf(this.canvas);e>=0&&(y[e]=null,b[e]=null)}if(this.destroyExtensions(),delete this.context,delete this.canvas,!this.gpu)return;const t=this.gpu.kernels.indexOf(this);-1!==t&&this.gpu.kernels.splice(t,1)}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=i.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}},{"../../plugins/math-random-uniformly-distributed":112,"../../utils":114,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":37,"./function-node":38,"./kernel-value-maps":39,"./vertex-shader":71}],71:[function(e,t,n){t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n  gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n  vTexCoord = aTexCoord;\n}"}},{}],72:[function(e,t,n){const r=`#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nfloat atan2(float v1, float v2) {\n  if (v1 == 0.0 || v2 == 0.0) return 0.0;\n  return atan(v1 / v2);\n}\n\nfloat cbrt(float x) {\n  if (x >= 0.0) {\n    return pow(x, 1.0 / 3.0);\n  } else {\n    return -pow(x, 1.0 / 3.0);\n  }\n}\n\nfloat expm1(float x) {\n  return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n  return x;\n}\n\nfloat imul(float v1, float v2) {\n  return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n  return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n  return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n  if (v2 == 0.0) return 1.0;\n  return pow(v1, v2);\n}\n\nfloat _round(float x) {\n  return floor(x + 0.5);\n}\n\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n  return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n  int result = 0;\n  int n = 1;\n  \n  for (int i = 0; i < BIT_COUNT; i++) {\n    if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n      result += n;\n    }\n    a = a / 2;\n    b = b / 2;\n    n = n * 2;\n    if(!(a > 0 || b > 0)) {\n      break;\n    }\n  }\n  return result;\n}\nint bitwiseXOR(int a, int b) {\n  int result = 0;\n  int n = 1;\n  \n  for (int i = 0; i < BIT_COUNT; i++) {\n    if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n      result += n;\n    }\n    a = a / 2;\n    b = b / 2;\n    n = n * 2;\n    if(!(a > 0 || b > 0)) {\n      break;\n    }\n  }\n  return result;\n}\nint bitwiseAnd(int a, int b) {\n  int result = 0;\n  int n = 1;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n      result += n;\n    }\n    a = a / 2;\n    b = b / 2;\n    n = n * 2;\n    if(!(a > 0 && b > 0)) {\n      break;\n    }\n  }\n  return result;\n}\nint bitwiseNot(int a) {\n  int result = 0;\n  int n = 1;\n  \n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (modi(a, 2) == 0) {\n      result += n;    \n    }\n    a = a / 2;\n    n = n * 2;\n  }\n  return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n  int maxBytes = BIT_COUNT;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (maxBytes >= n) {\n      break;\n    }\n    maxBytes *= 2;\n  }\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= shift) {\n      break;\n    }\n    n *= 2;\n  }\n\n  int result = 0;\n  int byteVal = 1;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= maxBytes) break;\n    if (modi(n, 2) > 0) { result += byteVal; }\n    n = int(n / 2);\n    byteVal *= 2;\n  }\n  return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n  return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n  int maxBytes = BIT_COUNT;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (maxBytes >= n) {\n      break;\n    }\n    maxBytes *= 2;\n  }\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= shift) {\n      break;\n    }\n    n /= 2;\n  }\n  int result = 0;\n  int byteVal = 1;\n  for (int i = 0; i < BIT_COUNT; i++) {\n    if (i >= maxBytes) break;\n    if (modi(n, 2) > 0) { result += byteVal; }\n    n = int(n / 2);\n    byteVal *= 2;\n  }\n  return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n  vec2 res = floor(mod(x, y));\n  return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n  vec3 res = floor(mod(x, y));\n  return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n  vec4 res = floor(mod(x, y));\n  return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n  float res = floor(mod(x, y));\n  return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n  return x - (y * int(x/y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n  __DECODE32_ENDIANNESS__;\n  texel *= 255.0;\n  vec2 gte128;\n  gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n  gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n  float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n  float res = exp2(round(exponent));\n  texel.b = texel.b - 128.0 * gte128.x;\n  res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n  res *= gte128.y * -2.0 + 1.0;\n  return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n  int channel = integerMod(index, 2);\n  return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n  int channel = integerMod(index, 4);\n  return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n  float F = abs(f);\n  float sign = f < 0.0 ? 1.0 : 0.0;\n  float exponent = floor(log2(F));\n  float mantissa = (exp2(-exponent) * F);\n  // exponent += floor(log2(mantissa));\n  vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n  texel.rg = integerMod(texel.rg, 256.0);\n  texel.b = integerMod(texel.b, 128.0);\n  texel.a = exponent*0.5 + 63.5;\n  texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n  texel = floor(texel);\n  texel *= 0.003921569; // 1/255\n  __ENCODE32_ENDIANNESS__;\n  return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n  if (value == 0.0) return vec4(0, 0, 0, 0);\n\n  float exponent;\n  float mantissa;\n  vec4  result;\n  float sgn;\n\n  sgn = step(0.0, -value);\n  value = abs(value);\n\n  exponent = floor(log2(value));\n\n  mantissa = value*pow(2.0, -exponent)-1.0;\n  exponent = exponent+127.0;\n  result   = vec4(0,0,0,0);\n\n  result.a = floor(exponent/2.0);\n  exponent = exponent - result.a*2.0;\n  result.a = result.a + 128.0*sgn;\n\n  result.b = floor(mantissa * 128.0);\n  mantissa = mantissa - result.b / 128.0;\n  result.b = result.b + exponent*128.0;\n\n  result.g = floor(mantissa*32768.0);\n  mantissa = mantissa - result.g/32768.0;\n\n  result.r = floor(mantissa*8388608.0);\n  return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n  int z = int(idx / (texDim.x * texDim.y));\n  idx -= z * int(texDim.x * texDim.y);\n  int y = int(idx / texDim.x);\n  int x = int(integerMod(idx, texDim.x));\n  return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture(tex, st / vec2(texSize));\n  return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + (texDim.x * (y + (texDim.y * z)));\n  int w = texSize.x * 2;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n  return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + (texDim.x * (y + (texDim.y * z)));\n  int w = texSize.x * 4;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n  return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + (texDim.x * (y + (texDim.y * z)));\n  int channel = integerMod(index, 4);\n  index = index / 4;\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  index = index / 4;\n  vec4 texel = texture(tex, st / vec2(texSize));\n  return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n  return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n  return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int channel = integerMod(index, 2);\n  index = index / 2;\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture(tex, st / vec2(texSize));\n  if (channel == 0) return vec2(texel.r, texel.g);\n  if (channel == 1) return vec2(texel.b, texel.a);\n  return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n  return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n  int vectorIndex = fieldIndex / 4;\n  int vectorOffset = fieldIndex - vectorIndex * 4;\n  int readY = vectorIndex / texSize.x;\n  int readX = vectorIndex - readY * texSize.x;\n  vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n  if (vectorOffset == 0) {\n    return tex1.xyz;\n  } else if (vectorOffset == 1) {\n    return tex1.yzw;\n  } else {\n    readX++;\n    if (readX >= texSize.x) {\n      readX = 0;\n      readY++;\n    }\n    vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n    if (vectorOffset == 2) {\n      return vec3(tex1.z, tex1.w, tex2.x);\n    } else {\n      return vec3(tex1.w, tex2.x, tex2.y);\n    }\n  }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n  int index = x + texDim.x * (y + texDim.y * z);\n  int channel = integerMod(index, 2);\n  int w = texSize.x;\n  vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n  vec4 texel = texture(tex, st / vec2(texSize));\n  return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n  actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n  color(r,g,b,1.0);\n}\n\nfloat modulo(float number, float divisor) {\n  if (number < 0.0) {\n    number = abs(number);\n    if (divisor < 0.0) {\n      divisor = abs(divisor);\n    }\n    return -mod(number, divisor);\n  }\n  if (divisor < 0.0) {\n    divisor = abs(divisor);\n  }\n  return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n  index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n  __MAIN_RESULT__;\n}`;t.exports={fragmentShader:r}},{}],73:[function(e,t,n){const{utils:r}=e("../../utils"),{WebGLFunctionNode:i}=e("../web-gl/function-node");t.exports={WebGL2FunctionNode:class extends i{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),i=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}}}},{"../../utils":114,"../web-gl/function-node":38}],74:[function(e,t,n){const{WebGL2KernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGL2KernelValueFloat:i}=e("./kernel-value/float"),{WebGL2KernelValueInteger:s}=e("./kernel-value/integer"),{WebGL2KernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGL2KernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGL2KernelValueHTMLImageArray:u}=e("./kernel-value/html-image-array"),{WebGL2KernelValueDynamicHTMLImageArray:l}=e("./kernel-value/dynamic-html-image-array"),{WebGL2KernelValueHTMLVideo:h}=e("./kernel-value/html-video"),{WebGL2KernelValueDynamicHTMLVideo:c}=e("./kernel-value/dynamic-html-video"),{WebGL2KernelValueSingleInput:p}=e("./kernel-value/single-input"),{WebGL2KernelValueDynamicSingleInput:d}=e("./kernel-value/dynamic-single-input"),{WebGL2KernelValueUnsignedInput:m}=e("./kernel-value/unsigned-input"),{WebGL2KernelValueDynamicUnsignedInput:f}=e("./kernel-value/dynamic-unsigned-input"),{WebGL2KernelValueMemoryOptimizedNumberTexture:g}=e("./kernel-value/memory-optimized-number-texture"),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:x}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGL2KernelValueNumberTexture:y}=e("./kernel-value/number-texture"),{WebGL2KernelValueDynamicNumberTexture:b}=e("./kernel-value/dynamic-number-texture"),{WebGL2KernelValueSingleArray:T}=e("./kernel-value/single-array"),{WebGL2KernelValueDynamicSingleArray:v}=e("./kernel-value/dynamic-single-array"),{WebGL2KernelValueSingleArray1DI:S}=e("./kernel-value/single-array1d-i"),{WebGL2KernelValueDynamicSingleArray1DI:A}=e("./kernel-value/dynamic-single-array1d-i"),{WebGL2KernelValueSingleArray2DI:_}=e("./kernel-value/single-array2d-i"),{WebGL2KernelValueDynamicSingleArray2DI:E}=e("./kernel-value/dynamic-single-array2d-i"),{WebGL2KernelValueSingleArray3DI:w}=e("./kernel-value/single-array3d-i"),{WebGL2KernelValueDynamicSingleArray3DI:k}=e("./kernel-value/dynamic-single-array3d-i"),{WebGL2KernelValueArray2:I}=e("./kernel-value/array2"),{WebGL2KernelValueArray3:D}=e("./kernel-value/array3"),{WebGL2KernelValueArray4:C}=e("./kernel-value/array4"),{WebGL2KernelValueUnsignedArray:$}=e("./kernel-value/unsigned-array"),{WebGL2KernelValueDynamicUnsignedArray:L}=e("./kernel-value/dynamic-unsigned-array"),R={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:L,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:f,NumberTexture:b,"ArrayTexture(1)":b,"ArrayTexture(2)":b,"ArrayTexture(3)":b,"ArrayTexture(4)":b,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:c},static:{Boolean:r,Float:i,Integer:s,Array:$,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:m,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:x,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:v,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":k,"Array3D(3)":k,"Array3D(4)":k,Input:d,NumberTexture:b,"ArrayTexture(1)":b,"ArrayTexture(2)":b,"ArrayTexture(3)":b,"ArrayTexture(4)":b,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:c},static:{Boolean:r,Float:i,Integer:s,Array:T,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h}}};t.exports={kernelValueMaps:R,lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const i=R[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]}}},{"./kernel-value/array2":75,"./kernel-value/array3":76,"./kernel-value/array4":77,"./kernel-value/boolean":78,"./kernel-value/dynamic-html-image":80,"./kernel-value/dynamic-html-image-array":79,"./kernel-value/dynamic-html-video":81,"./kernel-value/dynamic-memory-optimized-number-texture":82,"./kernel-value/dynamic-number-texture":83,"./kernel-value/dynamic-single-array":84,"./kernel-value/dynamic-single-array1d-i":85,"./kernel-value/dynamic-single-array2d-i":86,"./kernel-value/dynamic-single-array3d-i":87,"./kernel-value/dynamic-single-input":88,"./kernel-value/dynamic-unsigned-array":89,"./kernel-value/dynamic-unsigned-input":90,"./kernel-value/float":91,"./kernel-value/html-image":93,"./kernel-value/html-image-array":92,"./kernel-value/html-video":94,"./kernel-value/integer":95,"./kernel-value/memory-optimized-number-texture":96,"./kernel-value/number-texture":97,"./kernel-value/single-array":98,"./kernel-value/single-array1d-i":99,"./kernel-value/single-array2d-i":100,"./kernel-value/single-array3d-i":101,"./kernel-value/single-input":102,"./kernel-value/unsigned-array":103,"./kernel-value/unsigned-input":104}],75:[function(e,t,n){const{WebGLKernelValueArray2:r}=e("../../web-gl/kernel-value/array2");t.exports={WebGL2KernelValueArray2:class extends r{}}},{"../../web-gl/kernel-value/array2":41}],76:[function(e,t,n){const{WebGLKernelValueArray3:r}=e("../../web-gl/kernel-value/array3");t.exports={WebGL2KernelValueArray3:class extends r{}}},{"../../web-gl/kernel-value/array3":42}],77:[function(e,t,n){const{WebGLKernelValueArray4:r}=e("../../web-gl/kernel-value/array4");t.exports={WebGL2KernelValueArray4:class extends r{}}},{"../../web-gl/kernel-value/array4":43}],78:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("../../web-gl/kernel-value/boolean");t.exports={WebGL2KernelValueBoolean:class extends r{}}},{"../../web-gl/kernel-value/boolean":44}],79:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueHTMLImageArray:i}=e("./html-image-array");t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=e[0];this.checkSize(t,n),this.dimensions=[t,n,e.length],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"./html-image-array":92}],80:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicHTMLImage:i}=e("../../web-gl/kernel-value/dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLImage:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-html-image":45}],81:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueDynamicHTMLImage:i}=e("./dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends i{}}},{"../../../utils":114,"./dynamic-html-image":80}],82:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":47}],83:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-number-texture");t.exports={WebGL2KernelValueDynamicNumberTexture:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-number-texture":48}],84:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray:i}=e("../../web-gl2/kernel-value/single-array");t.exports={WebGL2KernelValueDynamicSingleArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array":98}],85:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray1DI:i}=e("../../web-gl2/kernel-value/single-array1d-i");t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array1d-i":99}],86:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray2DI:i}=e("../../web-gl2/kernel-value/single-array2d-i");t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array2d-i":100}],87:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray3DI:i}=e("../../web-gl2/kernel-value/single-array3d-i");t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array3d-i":101}],88:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleInput:i}=e("../../web-gl2/kernel-value/single-input");t.exports={WebGL2KernelValueDynamicSingleInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,i]=e.size;this.dimensions=new Int32Array([t||1,n||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-input":102}],89:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedArray:i}=e("../../web-gl/kernel-value/dynamic-unsigned-array");t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-array":54}],90:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedInput:i}=e("../../web-gl/kernel-value/dynamic-unsigned-input");t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-input":55}],91:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueFloat:i}=e("../../web-gl/kernel-value/float");t.exports={WebGL2KernelValueFloat:class extends i{}}},{"../../../utils":114,"../../web-gl/kernel-value/float":56}],92:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelArray:i}=e("../../web-gl/kernel-value/array");t.exports={WebGL2KernelValueHTMLImageArray:class extends i{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}defineTexture(){const{context:e}=this;e.activeTexture(this.contextHandle),e.bindTexture(e.TEXTURE_2D_ARRAY,this.texture),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MIN_FILTER,e.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let n=0;ni})}"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=r},{"./index":109}],108:[function(e,t,n){const{gpuMock:r}=e("gpu-mock.js"),{utils:i}=e("./utils"),{Kernel:s}=e("./backend/kernel"),{CPUKernel:a}=e("./backend/cpu/kernel"),{HeadlessGLKernel:o}=e("./backend/headless-gl/kernel"),{WebGL2Kernel:u}=e("./backend/web-gl2/kernel"),{WebGLKernel:l}=e("./backend/web-gl/kernel"),{kernelRunShortcut:h}=e("./kernel-run-shortcut"),c=[o,u,l],p=["gpu","cpu"],d={headlessgl:o,webgl2:u,webgl:l};let m=!0;function f(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(i.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(i.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(i.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(i.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}t.exports={GPU:class{static disableValidation(){m=!1}static enableValidation(){m=!0}static get isGPUSupported(){return c.some((e=>e.isSupported))}static get isKernelMapSupported(){return c.some((e=>e.isSupported&&e.features.kernelMap))}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return l.isSupported}static get isWebGL2Supported(){return u.isSupported}static get isHeadlessGLSupported(){return o.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return u.isSupported}static get isSinglePrecisionSupported(){return c.some((e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat))}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tt.argumentTypes[e])));const l=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:m,onRequestFallback:u,onRequestSwitchKernel:function t(r,i,a){a.debug&&console.warn("Switching kernels");let o=null;if(a.signature&&!s[a.signature]&&(s[a.signature]=a),a.dynamicOutput)for(let e=r.length-1;e>=0;e--){const t=r[e];"outputPrecisionMismatch"===t.type&&(o=t.needed)}const l=a.constructor,h=l.getArgumentTypes(a,i),c=l.getSignature(a,h),d=s[c];if(d)return d.onActivate(a),d;const f=s[c]=new l(e,{argumentTypes:h,constantTypes:a.constantTypes,graphical:a.graphical,loopMaxIterations:a.loopMaxIterations,constants:a.constants,dynamicOutput:a.dynamicOutput,dynamicArgument:a.dynamicArguments,context:a.context,canvas:a.canvas,output:o||a.output,precision:a.precision,pipeline:a.pipeline,immutable:a.immutable,optimizeFloatMemory:a.optimizeFloatMemory,fixIntegerDivisionAccuracy:a.fixIntegerDivisionAccuracy,functions:a.functions,nativeFunctions:a.nativeFunctions,injectedNative:a.injectedNative,subKernels:a.subKernels,strictIntegers:a.strictIntegers,debug:a.debug,gpu:a.gpu,validate:m,returnType:a.returnType,tactic:a.tactic,onRequestFallback:u,onRequestSwitchKernel:t,texture:a.texture,mappedTextures:a.mappedTextures,drawBuffersMap:a.drawBuffersMap});return f.build.apply(f,i),p.replaceKernel(f),n.push(f),f}},o),c=new this.Kernel(e,l),p=h(c);return this.canvas||(this.canvas=c.canvas),this.context||(this.context=c.context),n.push(c),p}createKernelMap(){let e,t;const n=typeof arguments[arguments.length-2];if("function"===n||"string"===n?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],"dev"!==this.mode&&(!this.Kernel.isSupported||!this.Kernel.features.kernelMap)&&this.mode&&p.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const r=f(t);if(t&&"object"==typeof t.argumentTypes&&(r.argumentTypes=Object.keys(t.argumentTypes).map((e=>t.argumentTypes[e]))),Array.isArray(arguments[0])){r.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');return this.nativeFunctions.push(Object.assign({name:e,source:t},n)),this}injectNative(e){return this.injectedNative=e,this}destroy(){return new Promise(((e,t)=>{this.kernels||e(),setTimeout((()=>{try{for(let e=0;et.kernel[i])),t.__defineSetter__(i,(e=>{t.kernel[i]=e}))))}t.kernel=e}t.exports={kernelRunShortcut:function(e){let t=function(){return e.build.apply(e,arguments),t=function(){let t=e.run.apply(e,arguments);if(e.switchingKernels){const r=e.resetSwitchingKernels(),i=e.onRequestSwitchKernel(r,arguments,e);n.kernel=e=i,t=i.run.apply(i,arguments)}return e.renderKernels?e.renderKernels():e.renderOutput?e.renderOutput():t},t.apply(e,arguments)};const n=function(){return t.apply(e,arguments)};return n.exec=function(){return new Promise(((e,n)=>{try{e(t.apply(this,arguments))}catch(e){n(e)}}))},n.replaceKernel=function(t){i(e=t,n)},i(e,n),n}}},{"./utils":114}],112:[function(e,t,n){const r={name:"math-random-uniformly-distributed",onBeforeRun:e=>{e.setUniform1f("randomSeed1",Math.random()),e.setUniform1f("randomSeed2",Math.random())},functionMatch:"Math.random()",functionReplace:"nrand(vTexCoord)",functionReturnType:"Number",source:"// https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0,1]\nhighp float randomSeedShift = 1.0;\nhighp float slide = 1.0;\nuniform highp float randomSeed1;\nuniform highp float randomSeed2;\n\nhighp float nrand(highp vec2 n) {\n  highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);\n  randomSeedShift = result;\n  if (randomSeedShift > 0.5) {\n    slide += 0.00009; \n  } else {\n    slide += 0.0009;\n  }\n  return result;\n}"};t.exports=r},{}],113:[function(e,t,n){t.exports={Texture:class{constructor(e){const{texture:t,size:n,dimensions:r,output:i,context:s,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:l}=e;if(!i)throw new Error('settings property "output" required.');if(!s)throw new Error('settings property "context" required.');if(!t)throw new Error('settings property "texture" required.');if(!o)throw new Error('settings property "kernel" required.');this.texture=t,t._refs?t._refs++:t._refs=1,this.size=n,this.dimensions=r,this.output=i,this.context=s,this.kernel=o,this.type=a,this._deleted=!1,this.internalFormat=u,this.textureFormat=l}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}}},{}],114:[function(e,t,n){const r=e("acorn"),{Input:i}=e("./input"),{Texture:s}=e("./texture"),a=/function ([^(]*)/,o=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,u=/([^\s,]+)/g,l={systemEndianness:()=>d,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),n=new Uint8Array(e);if(t[0]=3735928559,239===n[0])return"LE";if(222===n[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,"function".length).toLowerCase(),getFunctionNameFromString(e){const t=a.exec(e);return t&&0!==t.length?t[1].trim():null},getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(o,"");let n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(u);return null===n&&(n=[]),n},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&(e.isActiveClone=null,t[n]=l.clone(e[n]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(l.isArray(e))return e.length>0&&"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case s:return e.type;case i:return"Input"}if("nodeName"in e)switch(e.nodeName){case"IMG":case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}else{if(e.hasOwnProperty("type"))return e.type;if("undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return"OffscreenCanvas";if("undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap)return"ImageBitmap";if("undefined"!=typeof ImageData&&e instanceof ImageData)return"ImageData"}return"Unknown"},getKernelTextureSize(e,t){let[n,r,i]=t,s=(n||1)*(r||1)*(i||1);return e.optimizeFloatMemory&&"single"===e.precision&&(n=s=Math.ceil(s/4)),r>1&&n*r===s?new Int32Array([n,r]):l.closestSquareDimensions(s)},closestSquareDimensions(e){const t=Math.sqrt(e);let n=Math.ceil(t),r=Math.floor(t);for(;n*rMath.floor((e+t-1)/t)*t,getDimensions(e,t){let n;if(l.isArray(e)){const t=[];let r=e;for(;l.isArray(r);)t.push(r.length),r=r[0];n=t.reverse()}else if(e instanceof s)n=e.output;else{if(!(e instanceof i))throw new Error(`Unknown dimensions of ${e}`);n=e.size}if(t)for(n=Array.from(n);n.length<3;)n.push(1);return new Int32Array(n)},flatten2dArrayTo(e,t){let n=0;for(let r=0;re.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,n){n?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${n}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},flipPixels:(e,t,n)=>{const r=n/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;se.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;s{const n=new Float32Array(t);let r=0;for(let i=0;i{const r=new Array(n);let i=0;for(let s=0;s{const i=new Array(r);let s=0;for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=new Array(n),i=4*t;for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(e),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const{findDependency:n,thisLookup:i,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=r.parse(e),u=[];let h=0;const c=function e(t){if(Array.isArray(t)){const n=[];for(let r=0;rnull!==e));return r.length<1?"":`${t.kind} ${r.join(",")}`;case"VariableDeclarator":if(t.init.object&&"ThisExpression"===t.init.object.type){return i(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null}return`${t.id.name} = ${e(t.init)}`;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map((t=>e(t))).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map((t=>e(t))).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(n("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`;if(t.callee.object.name){const r=n(t.callee.object.name,t.callee.property.name);return null===r?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`:(u.push(r),`${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`${e(t.expression)}`;case"SequenceExpression":return`(${e(t.expressions)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?i(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map((t=>e(t))).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":return`if (${e(t.test)}) ${e(t.consequent)}`;case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let n=0;n{if("VariableDeclaration"!==e.type)throw new Error('Ast is not of type "VariableDeclaration"');const t=[];for(let n=0;n{const n=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].r}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),r=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].g}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),i=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].b}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].a}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),a=[n(t),r(t),i(t),s(t)];return a.rKernel=n,a.gKernel=r,a.bKernel=i,a.aKernel=s,a.gpu=e,a},splitRGBAToCanvases:(e,t,n,r)=>{const i=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});i(t);const s=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});s(t);const a=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});a(t);const o=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return o(t),[i.canvas,s.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const t=r.parse(`const value = ${e.toString()}`),{init:n}=t.body[0].declarations[0];return n.body.name||n.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type.  Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return h.test(e)&&(e=e.replace(h,"S_S")),c.test(e)?e=e.replace(c,"U_U"):p.test(e)&&(e=e.replace(p,"u_u")),e}},h=/\$/,c=/__/,p=/_/,d=l.getSystemEndianness();t.exports={utils:l}},{"./input":110,"./texture":113,acorn:1}]},{},[107])(107)}));
\ No newline at end of file
diff --git a/src/broadcasting.ts b/src/broadcasting.ts
new file mode 100644
index 00000000..e8ef6947
--- /dev/null
+++ b/src/broadcasting.ts
@@ -0,0 +1,56 @@
+// https://docs.pytorch.org/docs/stable/notes/broadcasting.html
+export function _broadcast_shape(a_shape: number[], b_shape: number[]): number[] {
+    const result_length = Math.max(a_shape.length, b_shape.length);
+    const padded_a_shape = [...Array(result_length - a_shape.length).fill(1), ...a_shape];
+    const padded_b_shape = [...Array(result_length - b_shape.length).fill(1), ...b_shape];
+
+    let result_shape: number[] = [];
+
+    for (let i = 0; i < result_length; i++) {
+        if (padded_a_shape[i] !== padded_b_shape[i] && padded_a_shape[i] !== 1 && padded_b_shape[i] !== 1) {
+            throw new Error(`Shape mismatch: ${a_shape} and ${b_shape}`);
+        }
+
+        result_shape.push(Math.max(padded_a_shape[i], padded_b_shape[i]));
+    }
+
+    return result_shape;
+}
+
+export function _pad_shape(shape: number[], broadcast_shape: number[]): number[] {
+    return [...Array(broadcast_shape.length - shape.length).fill(1), ...shape];
+}
+
+export function _get_original_index(original_shape: number[], new_shape: number[], index: number): number {
+    let original_index = 0;
+    let cur_stride = 1;
+    let temp_index = index;
+
+    for (let i = original_shape.length - 1; i >= 0; i--) {
+        if(original_shape[i] > 1) {
+            const dim_index = Math.floor(temp_index % new_shape[i]);
+            original_index = original_index + (dim_index * cur_stride);
+        }
+        cur_stride *= original_shape[i];
+        temp_index = Math.floor(temp_index / new_shape[i]);
+    }
+    return original_index;
+}
+
+
+export function _get_original_index_gpu(original_shape: number[], new_shape: number[], index: number): number {
+    let original_index = 0;
+    let cur_stride = 1;
+    let temp_index = index;
+
+    for (let i = this.constants.shape_length - 1; i >= 0; i--) {
+        if(original_shape[i] > 1) {
+            // const dim_index = temp_index % new_shape[i];
+            const dim_index = temp_index - new_shape[i] * Math.floor(temp_index / new_shape[i]);
+            original_index = original_index + (dim_index * cur_stride);
+        }
+        cur_stride = cur_stride * original_shape[i];
+        temp_index = Math.floor(temp_index / new_shape[i]);
+    }
+    return original_index;
+}
diff --git a/src/gpu.ts b/src/gpu.ts
new file mode 100644
index 00000000..194f8bd5
--- /dev/null
+++ b/src/gpu.ts
@@ -0,0 +1,21 @@
+/*
+ * TODO:
+ * - Probably use Source Academy gpu.js
+ */
+
+import { GPU } from '@veehz/gpu.js';
+import { _get_original_index_gpu } from './broadcasting';
+
+const gpu = new GPU();
+
+gpu.addFunction(_get_original_index_gpu, {
+    returnType: 'Integer',
+    argumentTypes: {
+        original_shape: 'Array',
+        new_shape: 'Array',
+        // shape_length: 'Integer',
+        index: 'Integer'
+    }
+});
+
+export default gpu;
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 00000000..e58b4e8e
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,16 @@
+import { registerOperation } from './operations/registry';
+import { Tensor } from './tensor';
+
+import { Add, Div, Log, Mul, Pow, Sub, Sum } from './operations/basic';
+
+import { _broadcast_shape, _get_original_index_gpu } from './broadcasting';
+
+export { Tensor };
+
+registerOperation('add', Add);
+registerOperation('mul', Mul);
+registerOperation('sum', Sum);
+registerOperation('sub', Sub);
+registerOperation('pow', Pow);
+registerOperation('log', Log);
+registerOperation('div', Div);
\ No newline at end of file
diff --git a/src/operations/basic.ts b/src/operations/basic.ts
new file mode 100644
index 00000000..234d0faa
--- /dev/null
+++ b/src/operations/basic.ts
@@ -0,0 +1,415 @@
+import gpu from "../gpu";
+import { _broadcast_shape, _get_original_index_gpu, _pad_shape } from "../broadcasting";
+import { Tensor } from "../tensor";
+// import * as utils from "../utils";
+import { Operation, BinaryOperation, UnaryOperation } from "./function_base";
+
+/* This did not work as it doesn't support dynamic function registration */
+// export function _broadcast_operation(
+//   f: (a: number, b: number) => number
+// ): (a: Tensor, b: Tensor) => Tensor {
+//   return (a: Tensor, b: Tensor) => {
+//     const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+
+//     gpu.addFunction(f, {
+//       returnType: 'Number',
+//       argumentTypes: {
+//         a: 'Number',
+//         b: 'Number'
+//       }
+//     });
+
+//     const kernel = gpu
+//       .createKernel(function (
+//         a: number[],
+//         as: number[],
+//         b: number[],
+//         bs: number[],
+//         bcs: number[]
+//       ) {
+//         const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
+//         const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
+
+//         return f(a[a_index], b[b_index]);
+//       })
+//       .setConstants({ shape_length: broadcast_shape.length })
+//       .setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)])
+//       .setFunctions([f]);
+
+//     return new Tensor(
+//       kernel(a.data, a.shape, b.data, b.shape, broadcast_shape) as number[]
+//     );
+//   };
+// }
+
+export function _add(a: number[], b: number[]): number[] {
+  const kernel = gpu
+    .createKernel(function (a: number[], b: number[]) {
+      return a[this.thread.x] + b[this.thread.x];
+    })
+    .setOutput([a.length]);
+
+  return kernel(a, b) as number[];
+}
+
+export function _add_broadcast(
+  a: number[],
+  a_shape: number[],
+  b: number[],
+  b_shape: number[]
+): number[] {
+  const broadcast_shape = _broadcast_shape(a_shape, b_shape);
+
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+      a_shape: number[],
+      b: number[],
+      b_shape: number[],
+      broadcast_shape: number[]
+    ) {
+      const a_index = _get_original_index_gpu(
+        a_shape,
+        broadcast_shape,
+        this.thread.x
+      );
+      const b_index = _get_original_index_gpu(
+        b_shape,
+        broadcast_shape,
+        this.thread.x
+      );
+
+      return a[a_index] + b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length,
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return kernel(a, a_shape, b, b_shape, broadcast_shape) as number[];
+}
+
+// export function _add_tensor(
+//   a: Tensor,
+//   b: Tensor,
+//   operation: Operation | null = null
+// ): Tensor {
+//   const a_shape = a.shape;
+//   const b_shape = b.shape;
+
+//   const result = _add_broadcast(a.data, a_shape, b.data, b_shape);
+
+//   return new Tensor(
+//     result,
+//     { requires_grad: a.requires_grad || b.requires_grad },
+//     { operation: operation }
+//   );
+// }
+
+// export function _add_tensor(a: Tensor, b: Tensor): Tensor {
+//     function _add_(a: number, b: number): number { return a + b }
+//     return _broadcast_operation(_add_)(a, b);
+// }
+
+
+export function _add_tensor(
+  a: Tensor,
+  b: Tensor,
+  operation: Operation | null = null
+): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+      as: number[],
+      b: number[],
+      bs: number[],
+      bcs: number[]
+    ) {
+      const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
+      const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
+
+      return a[a_index] + b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length,
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+
+export class Add extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _add_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+    a.backward(dz);
+    b.backward(dz);
+  }
+}
+
+export function _sub_tensor(
+  a: Tensor,
+  b: Tensor,
+  operation: Operation | null = null
+): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+      as: number[],
+      b: number[],
+      bs: number[],
+      bcs: number[]
+    ) {
+      const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
+      const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
+
+      return a[a_index] - b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape?.length || 0,
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+
+export class Sub extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _sub_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+    a.backward(dz);
+    b.backward(dz.mul(new Tensor(-1)));
+  }
+}
+
+export function _mul_tensor(
+  a: Tensor,
+  b: Tensor,
+  operation: Operation | null = null
+): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+      as: number[],
+      b: number[],
+      bs: number[],
+      bcs: number[]
+    ) {
+      const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
+      const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
+
+      return a[a_index] * b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length,
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+
+export class Mul extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _mul_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+    a.backward(dz.mul(b));
+    b.backward(dz.mul(a));
+  }
+}
+
+export function _div_tensor(
+  a: Tensor,
+  b: Tensor,
+  operation: Operation | null = null
+): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+      as: number[],
+      b: number[],
+      bs: number[],
+      bcs: number[]
+    ) {
+      const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
+      const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
+
+      return a[a_index] / b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length,
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+
+export class Div extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _div_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+    a.backward(dz.div(b));
+    b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));
+  }
+}
+
+export class Sum extends UnaryOperation {
+  cache: [Tensor];
+  forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return new Tensor(
+      a.data.reduce((acc, val) => acc + val, 0),
+      { requires_grad: a.requires_grad },
+      { operation: this }
+    );
+  }
+
+  backward(dz: Tensor): void {
+    const [a] = this.cache;
+    const result = new Tensor(Array(a.data.length).fill(dz.data[0]));
+    a.backward(result);
+  }
+}
+
+export function _pow_tensor(
+  a: Tensor,
+  b: Tensor,
+  operation: Operation | null = null
+): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+      as: number[],
+      b: number[],
+      bs: number[],
+      bcs: number[]
+    ) {
+      const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
+      const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
+
+      return Math.pow(a[a_index], b[b_index]);
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length,
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+
+export class Pow extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _pow_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+    a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));
+    b.backward(dz.mul(a.pow(b)).mul(a.log()));
+  }
+}
+
+export function _log_tensor(
+  a: Tensor,
+  operation: Operation | null = null
+): Tensor {
+  const kernel = gpu.createKernel(
+    function (
+      a: number[],
+    ) {
+      return Math.log(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+
+export class Log extends UnaryOperation {
+  cache: [Tensor];
+  forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _log_tensor(a, this);
+  }
+  backward(dz: Tensor): void {
+    const [a] = this.cache;
+    a.backward((new Tensor(1)).div(a));
+  }
+}
\ No newline at end of file
diff --git a/src/operations/function_base.ts b/src/operations/function_base.ts
new file mode 100644
index 00000000..c46625ca
--- /dev/null
+++ b/src/operations/function_base.ts
@@ -0,0 +1,23 @@
+import { Tensor } from '../tensor';
+
+
+abstract class Operation {
+    abstract forward(...args: Tensor[]): Tensor;
+    abstract backward(dz: Tensor): void;
+}
+
+abstract class UnaryOperation extends Operation {
+    abstract forward(a: Tensor): Tensor;
+    abstract backward(dz: Tensor): void;
+}
+
+abstract class BinaryOperation extends Operation {
+    abstract forward(a: Tensor, b: Tensor): Tensor;
+    abstract backward(dz: Tensor): void;
+}
+
+export type OperationConstructor = new () => Operation;
+export type UnaryOperationConstructor = new () => UnaryOperation;
+export type BinaryOperationConstructor = new () => BinaryOperation;
+
+export { Operation, UnaryOperation, BinaryOperation };
diff --git a/src/operations/registry.ts b/src/operations/registry.ts
new file mode 100644
index 00000000..91a0a9da
--- /dev/null
+++ b/src/operations/registry.ts
@@ -0,0 +1,16 @@
+import { Operation, OperationConstructor } from "./function_base";
+
+// Only allow registering concrete, constructible Operation classes
+const operations = new Map();
+
+export function registerOperation(name: string, func: OperationConstructor) {
+  operations.set(name, func);
+}
+
+export function getOperation(name: string): OperationConstructor {
+  const func = operations.get(name);
+  if (!func) {
+    throw new Error(`Operation '${name}' is not registered.`);
+  }
+  return func;
+}
diff --git a/src/tensor.ts b/src/tensor.ts
new file mode 100644
index 00000000..0b1a0fe7
--- /dev/null
+++ b/src/tensor.ts
@@ -0,0 +1,157 @@
+import { _get_original_index } from "./broadcasting";
+import { Operation } from "./operations/function_base";
+import { getOperation } from "./operations/registry";
+import { TensorBase } from "./tensor_base";
+
+/*
+ * TODO:
+ * - Add support for Textures to be stored in Tensors
+ */
+
+type TypedArray =
+  | Int8Array
+  | Uint8Array
+  | Uint8ClampedArray
+  | Int16Array
+  | Uint16Array
+  | Int32Array
+  | Uint32Array
+  | Float32Array
+  | Float64Array;
+
+type NestedNumberArray = number | TypedArray | NestedNumberArray[];
+
+function _get_shape(data: NestedNumberArray): number[] {
+  if (ArrayBuffer.isView(data)) {
+    return [data.length];
+  }
+
+  const shape = [];
+  while (Array.isArray(data)) {
+    shape.push(data.length);
+    data = data[0];
+  }
+  return shape;
+}
+
+function _flatten(data: NestedNumberArray): number[] {
+  if (Array.isArray(data)) {
+    return data.flatMap((item) => _flatten(item));
+  } else if (ArrayBuffer.isView(data)) {
+    return Array.from(data);
+  } else {
+    return [data];
+  }
+}
+
+export class Tensor extends TensorBase {
+  data: number[];
+  _shape: number[];
+  operation: any = null;
+  public grad: Tensor | null = null;
+
+  requires_grad: boolean;
+
+  constructor(
+    data: NestedNumberArray,
+    options: { requires_grad?: boolean } = {},
+    internal_options: { operation?: Operation, shape?: number[] } = {}
+  ) {
+    super();
+    this.data = _flatten(data);
+    this.requires_grad = options.requires_grad ?? false;
+
+    this._shape = internal_options.shape ?? _get_shape(data);
+    this.operation = internal_options.operation ?? null;
+  }
+
+  // TODO: Somehow having a shape of [] will have a weird error:
+  // TypeError: Cannot read properties of undefined (reading 'length')
+  // when running kernel (something to do with constants?)
+  // so a little hack to return [1] when the shape is []
+  get shape(): number[] {
+    return this._shape.length === 0 ? [1] : this._shape;
+    // return this._shape;
+  }
+
+  set shape(shape: number[]) {
+    this._shape = shape;
+  }
+
+  private _executeUnaryOp(opName: string): Tensor {
+    const operation = new (getOperation(opName))();
+    return operation.forward(this);
+  }
+
+  private _executeBinaryOp(opName: string, other: Tensor): Tensor {
+    const operation = new (getOperation(opName))();
+    return operation.forward(this, other);
+  }
+
+  add(other: Tensor): Tensor {
+    return this._executeBinaryOp("add", other);
+  }
+
+  sub(other: Tensor): Tensor {
+    return this._executeBinaryOp("sub", other);
+  }
+
+  mul(other: Tensor): Tensor {
+    return this._executeBinaryOp("mul", other);
+  }
+
+  div(other: Tensor): Tensor {
+    return this._executeBinaryOp("div", other);
+  }
+
+  sum(): Tensor {
+    return this._executeUnaryOp("sum");
+  }
+
+  pow(other: Tensor): Tensor {
+    return this._executeBinaryOp("pow", other);
+  }
+
+  log(): Tensor {
+    return this._executeUnaryOp("log");
+  }
+
+  item(): number {
+    if (this.data.length !== 1) {
+      throw new Error("Tensor.item() is only valid for scalars");
+    }
+    return this.data[0];
+  }
+
+  backward(grad?: Tensor | null): void {
+    if (!this.requires_grad) {
+      // If this tensor does not require gradients, stop propagation.
+      return;
+    }
+
+    if (!grad) {
+      if (this.data.length !== 1) {
+        throw new Error("Gradient is required for non-scalar tensors");
+      }
+
+      grad = new Tensor(1);
+    }
+
+    if (!this.grad) {
+      this.grad = new Tensor(Array(this.data.length).fill(0));
+    }
+
+    // Add grad to this.grad
+    for (let i = 0; i < grad.data.length; i++) {
+      this.grad.data[_get_original_index(this.shape, grad.shape, i)] += grad.data[i];
+    }
+
+    if (this.operation) {
+      // Propagate only the incoming local gradient, not the accumulated one,
+      // to avoid double-counting when a tensor receives gradients from
+      // multiple downstream paths.
+      // this.operation.backward(grad);
+      this.operation.backward(this.grad);
+    }
+  }
+}
diff --git a/src/tensor_base.ts b/src/tensor_base.ts
new file mode 100644
index 00000000..d35a4498
--- /dev/null
+++ b/src/tensor_base.ts
@@ -0,0 +1 @@
+export class TensorBase {}
\ No newline at end of file
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 00000000..59713714
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,7 @@
+import { Tensor } from './tensor';
+
+export function ones_like(other: Tensor): Tensor {
+    const tensor = new Tensor(Array(other.data.length).fill(1));
+    tensor.shape = other.shape;
+    return tensor;
+}
\ No newline at end of file
diff --git a/test/backward.test.ts b/test/backward.test.ts
new file mode 100644
index 00000000..c7daf279
--- /dev/null
+++ b/test/backward.test.ts
@@ -0,0 +1,59 @@
+import { Tensor } from '../src/index';
+
+describe('Autograd', () => {
+
+    test('y = x**2, dy/dx at x=2 is 4', () => {
+        const x = new Tensor([2.0], { requires_grad: true });
+        const y = x.pow(new Tensor([2.0]));
+        expect(y.item()).toBe(4.0);
+        y.backward();
+        expect(x.grad?.item()).toBe(4.0);
+    });
+
+    test('y = 2*x, dy/dx at x=2 is 2', () => {
+        const x = new Tensor([2.0], { requires_grad: true });
+        const y = x.mul(new Tensor(2.0));
+        expect(y.item()).toBe(4.0);
+        y.backward();
+        expect(x.grad?.item()).toBe(2.0);
+    });
+
+    test('z = x + y, dz/dx at x=2, y=3 is 1', () => {
+        const x = new Tensor([2.0], { requires_grad: true });
+        const y = new Tensor([3.0], { requires_grad: true });
+        const z = x.add(y);
+        expect(z.item()).toBe(5.0);
+        z.backward();
+        expect(x.grad?.item()).toBe(1.0);
+        expect(y.grad?.item()).toBe(1.0);
+    });
+
+  test('y = x**2 + 2*x (seperated operations), dy/dx at x=2 is 6', () => {
+    const x = new Tensor([2.0], { requires_grad: true });
+
+    const y1 = x.pow(new Tensor(2.0));
+    const y2 = x.mul(new Tensor(2.0));
+
+    const y = y1.add(y2);
+
+    expect(y.item()).toBe(8.0);
+    expect(y1.item()).toBe(4.0);
+    expect(y2.item()).toBe(4.0);
+
+    y.backward();
+
+    expect(y1.grad?.item()).toBe(1.0);
+    expect(y2.grad?.item()).toBe(1.0);
+
+    expect(x.grad?.item()).toBe(6.0);
+    expect(x.item()).toBe(2.0);
+  });
+
+  test('y = x**2 + 2*x (combined operations), dy/dx at x=2 is 6', () => {
+    const x = new Tensor([2.0], { requires_grad: true });
+    const y = (x.pow(new Tensor(2.0))).add(x.mul(new Tensor(2.0)));
+    expect(y.item()).toBe(8.0);
+    y.backward();
+    expect(x.grad?.item()).toBe(6.0);
+  });
+});
diff --git a/test/broadcast.test.ts b/test/broadcast.test.ts
new file mode 100644
index 00000000..f29f318d
--- /dev/null
+++ b/test/broadcast.test.ts
@@ -0,0 +1,21 @@
+import { _broadcast_shape } from '../src/broadcasting';
+
+describe('Broadcasting', () => {
+    test('Broadcast shape of same dimensions', () => {
+        expect(_broadcast_shape([1, 3, 1], [4, 3, 6])).toEqual([4, 3, 6]);
+        expect(_broadcast_shape([4, 3, 6], [1, 3, 1])).toEqual([4, 3, 6]);
+        expect(_broadcast_shape([2, 2, 2], [2, 2, 2])).toEqual([2, 2, 2]);
+
+        expect(() => _broadcast_shape([1, 2, 1], [1, 3, 1])).toThrow(Error);
+    });
+
+    test('Broadcast shape of different dimensions', () => {
+        expect(_broadcast_shape([2, 3, 1], [3, 1])).toEqual([2, 3, 1]);
+        expect(_broadcast_shape([3, 1], [2, 3, 1])).toEqual([2, 3, 1]);
+        expect(_broadcast_shape([1], [2, 2, 2])).toEqual([2, 2, 2]);
+        expect(_broadcast_shape([2], [])).toEqual([2]);
+        expect(_broadcast_shape([1, 4], [3, 3, 1])).toEqual([3, 3, 4]);
+
+        expect(() => _broadcast_shape([1, 2], [3, 3, 6])).toThrow(Error);
+    });
+});
\ No newline at end of file
diff --git a/test/tensor.test.ts b/test/tensor.test.ts
new file mode 100644
index 00000000..2fbb610b
--- /dev/null
+++ b/test/tensor.test.ts
@@ -0,0 +1,68 @@
+import { Tensor } from '../src/index';
+
+describe('Tensor', () => {
+  describe('Constructor', () => {
+    test('should create a tensor with correct data and shape', () => {
+      const tensor = new Tensor([10, 20, 30]);
+      expect(tensor.data).toEqual([10, 20, 30]);
+      expect(tensor.shape).toEqual([3]);
+    });
+
+    test('should create a tensor with nested array', () => {
+      const tensor = new Tensor([[1, 2], [3, 4]]);
+      expect(tensor.data).toEqual([1, 2, 3, 4]);
+      expect(tensor.shape).toEqual([2, 2]);
+    });
+  });
+
+  describe('Addition', () => {
+    test('should add two tensors with same shape', () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = t1.add(t2);
+      
+      expect(Array.from(result.data)).toEqual([30]);
+      expect(result.shape).toEqual([1]);
+    });
+
+    test('should add tensors with different shapes (broadcasting)', () => {
+      const t1 = new Tensor([10, 20, 30]);
+      const t2 = new Tensor([1]);
+      const result = t1.add(t2);
+      
+      expect(Array.from(result.data)).toEqual([11, 21, 31]);
+      expect(result.shape).toEqual([3]);
+    });
+
+    test('should add two 1D tensors of same length', () => {
+      const t1 = new Tensor([1, 2, 3]);
+      const t2 = new Tensor([4, 5, 6]);
+      const result = t1.add(t2);
+      
+      expect(Array.from(result.data)).toEqual([5, 7, 9]);
+      expect(result.shape).toEqual([3]);
+    });
+  });
+
+  describe('Multiplication', () => {
+    test('should multiply two tensors with same shape', () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = t1.mul(t2);
+
+      expect(Array.from(result.data)).toEqual([200]);
+      expect(result.shape).toEqual([1]);
+    });
+  });
+
+  describe('should multiply tensors with different shapes (broadcasting)', () => {
+    test('should multiply two tensors with different shapes (broadcasting)', () => {
+      const t1 = new Tensor([10, 20, 30]);
+      const t2 = new Tensor([1]);
+      const result = t1.mul(t2);
+
+      expect(Array.from(result.data)).toEqual([10, 20, 30]);
+      expect(result.shape).toEqual([3]);
+    });
+  });
+});
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..eafdb462
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,18 @@
+{
+    "compilerOptions": {
+      "target": "ESNext",
+      "useDefineForClassFields": true,
+      "module": "ESNext",
+      "lib": ["ESNext", "DOM"],
+      "moduleResolution": "bundler",
+      "strict": false,
+      "noImplicitAny": false,
+      "resolveJsonModule": true,
+      "esModuleInterop": true,
+      "noEmit": true,
+      "skipLibCheck": true,
+      "types": ["node", "jest"]
+    },
+    "include": ["src", "test", "vite.config.browser.ts", "vite.config.node.ts"]
+  }
+  
\ No newline at end of file
diff --git a/vite.config.browser.ts b/vite.config.browser.ts
new file mode 100644
index 00000000..2e5f901f
--- /dev/null
+++ b/vite.config.browser.ts
@@ -0,0 +1,39 @@
+import { defineConfig } from 'vite';
+import path from 'path';
+import dts from 'vite-plugin-dts';
+
+export default defineConfig({
+  plugins: [
+    dts({
+      outDir: 'build/types'
+    })
+  ],
+  build: {
+    // Avoid transforming/minifying function bodies used by gpu.js kernel parser
+    minify: false,
+    sourcemap: true,
+    lib: {
+      entry: path.resolve(__dirname, 'src/index.ts'),
+      name: 'torch',
+      fileName: (format) => `torch.browser.${format}.js`,
+      formats: ['es', 'umd']
+    },
+    outDir: 'build/browser',
+    rollupOptions: {
+      treeshake: false,
+      output: {
+        compact: false,
+        inlineDynamicImports: false,
+        minifyInternalExports: false,
+      }
+    }
+  },
+  esbuild: {
+    keepNames: true,
+  },
+  resolve: {
+    alias: {
+      'gpu.js': path.resolve(__dirname, './public/gpu-browser.min.js'),
+    },
+  },
+});
diff --git a/vite.config.node.ts b/vite.config.node.ts
new file mode 100644
index 00000000..fe637bf0
--- /dev/null
+++ b/vite.config.node.ts
@@ -0,0 +1,19 @@
+import { defineConfig } from 'vite';
+import path from 'path';
+
+export default defineConfig({
+  build: {
+    lib: {
+      entry: path.resolve(__dirname, 'src/index.ts'),
+      fileName: (format) => `torch.node.${format}.js`,
+      formats: ['es', 'cjs']
+    },
+    rollupOptions: {
+      // Don't bundle 'gpu.js'. The user's Node project will provide it.
+      external: ['gpu.js']
+    },
+    outDir: 'build/node',
+    target: 'node20',
+    minify: false,
+  },
+});
diff --git a/yarn.lock b/yarn.lock
index 96714d87..86a0d9dd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5,8 +5,5968 @@ __metadata:
   version: 8
   cacheKey: 10c0
 
+"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/code-frame@npm:7.27.1"
+  dependencies:
+    "@babel/helper-validator-identifier": "npm:^7.27.1"
+    js-tokens: "npm:^4.0.0"
+    picocolors: "npm:^1.1.1"
+  checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00
+  languageName: node
+  linkType: hard
+
+"@babel/compat-data@npm:^7.27.2":
+  version: 7.28.4
+  resolution: "@babel/compat-data@npm:7.28.4"
+  checksum: 10c0/9d346471e0a016641df9a325f42ad1e8324bbdc0243ce4af4dd2b10b974128590da9eb179eea2c36647b9bb987343119105e96773c1f6981732cd4f87e5a03b9
+  languageName: node
+  linkType: hard
+
+"@babel/core@npm:^7.23.9, @babel/core@npm:^7.27.4":
+  version: 7.28.4
+  resolution: "@babel/core@npm:7.28.4"
+  dependencies:
+    "@babel/code-frame": "npm:^7.27.1"
+    "@babel/generator": "npm:^7.28.3"
+    "@babel/helper-compilation-targets": "npm:^7.27.2"
+    "@babel/helper-module-transforms": "npm:^7.28.3"
+    "@babel/helpers": "npm:^7.28.4"
+    "@babel/parser": "npm:^7.28.4"
+    "@babel/template": "npm:^7.27.2"
+    "@babel/traverse": "npm:^7.28.4"
+    "@babel/types": "npm:^7.28.4"
+    "@jridgewell/remapping": "npm:^2.3.5"
+    convert-source-map: "npm:^2.0.0"
+    debug: "npm:^4.1.0"
+    gensync: "npm:^1.0.0-beta.2"
+    json5: "npm:^2.2.3"
+    semver: "npm:^6.3.1"
+  checksum: 10c0/ef5a6c3c6bf40d3589b5593f8118cfe2602ce737412629fb6e26d595be2fcbaae0807b43027a5c42ec4fba5b895ff65891f2503b5918c8a3ea3542ab44d4c278
+  languageName: node
+  linkType: hard
+
+"@babel/generator@npm:^7.27.5, @babel/generator@npm:^7.28.3":
+  version: 7.28.3
+  resolution: "@babel/generator@npm:7.28.3"
+  dependencies:
+    "@babel/parser": "npm:^7.28.3"
+    "@babel/types": "npm:^7.28.2"
+    "@jridgewell/gen-mapping": "npm:^0.3.12"
+    "@jridgewell/trace-mapping": "npm:^0.3.28"
+    jsesc: "npm:^3.0.2"
+  checksum: 10c0/0ff58bcf04f8803dcc29479b547b43b9b0b828ec1ee0668e92d79f9e90f388c28589056637c5ff2fd7bcf8d153c990d29c448d449d852bf9d1bc64753ca462bc
+  languageName: node
+  linkType: hard
+
+"@babel/helper-compilation-targets@npm:^7.27.2":
+  version: 7.27.2
+  resolution: "@babel/helper-compilation-targets@npm:7.27.2"
+  dependencies:
+    "@babel/compat-data": "npm:^7.27.2"
+    "@babel/helper-validator-option": "npm:^7.27.1"
+    browserslist: "npm:^4.24.0"
+    lru-cache: "npm:^5.1.1"
+    semver: "npm:^6.3.1"
+  checksum: 10c0/f338fa00dcfea931804a7c55d1a1c81b6f0a09787e528ec580d5c21b3ecb3913f6cb0f361368973ce953b824d910d3ac3e8a8ee15192710d3563826447193ad1
+  languageName: node
+  linkType: hard
+
+"@babel/helper-globals@npm:^7.28.0":
+  version: 7.28.0
+  resolution: "@babel/helper-globals@npm:7.28.0"
+  checksum: 10c0/5a0cd0c0e8c764b5f27f2095e4243e8af6fa145daea2b41b53c0c1414fe6ff139e3640f4e2207ae2b3d2153a1abd346f901c26c290ee7cb3881dd922d4ee9232
+  languageName: node
+  linkType: hard
+
+"@babel/helper-module-imports@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/helper-module-imports@npm:7.27.1"
+  dependencies:
+    "@babel/traverse": "npm:^7.27.1"
+    "@babel/types": "npm:^7.27.1"
+  checksum: 10c0/e00aace096e4e29290ff8648455c2bc4ed982f0d61dbf2db1b5e750b9b98f318bf5788d75a4f974c151bd318fd549e81dbcab595f46b14b81c12eda3023f51e8
+  languageName: node
+  linkType: hard
+
+"@babel/helper-module-transforms@npm:^7.28.3":
+  version: 7.28.3
+  resolution: "@babel/helper-module-transforms@npm:7.28.3"
+  dependencies:
+    "@babel/helper-module-imports": "npm:^7.27.1"
+    "@babel/helper-validator-identifier": "npm:^7.27.1"
+    "@babel/traverse": "npm:^7.28.3"
+  peerDependencies:
+    "@babel/core": ^7.0.0
+  checksum: 10c0/549be62515a6d50cd4cfefcab1b005c47f89bd9135a22d602ee6a5e3a01f27571868ada10b75b033569f24dc4a2bb8d04bfa05ee75c16da7ade2d0db1437fcdb
+  languageName: node
+  linkType: hard
+
+"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0":
+  version: 7.27.1
+  resolution: "@babel/helper-plugin-utils@npm:7.27.1"
+  checksum: 10c0/94cf22c81a0c11a09b197b41ab488d416ff62254ce13c57e62912c85700dc2e99e555225787a4099ff6bae7a1812d622c80fbaeda824b79baa10a6c5ac4cf69b
+  languageName: node
+  linkType: hard
+
+"@babel/helper-string-parser@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/helper-string-parser@npm:7.27.1"
+  checksum: 10c0/8bda3448e07b5583727c103560bcf9c4c24b3c1051a4c516d4050ef69df37bb9a4734a585fe12725b8c2763de0a265aa1e909b485a4e3270b7cfd3e4dbe4b602
+  languageName: node
+  linkType: hard
+
+"@babel/helper-validator-identifier@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/helper-validator-identifier@npm:7.27.1"
+  checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84
+  languageName: node
+  linkType: hard
+
+"@babel/helper-validator-option@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/helper-validator-option@npm:7.27.1"
+  checksum: 10c0/6fec5f006eba40001a20f26b1ef5dbbda377b7b68c8ad518c05baa9af3f396e780bdfded24c4eef95d14bb7b8fd56192a6ed38d5d439b97d10efc5f1a191d148
+  languageName: node
+  linkType: hard
+
+"@babel/helpers@npm:^7.28.4":
+  version: 7.28.4
+  resolution: "@babel/helpers@npm:7.28.4"
+  dependencies:
+    "@babel/template": "npm:^7.27.2"
+    "@babel/types": "npm:^7.28.4"
+  checksum: 10c0/aaa5fb8098926dfed5f223adf2c5e4c7fbba4b911b73dfec2d7d3083f8ba694d201a206db673da2d9b3ae8c01793e795767654558c450c8c14b4c2175b4fcb44
+  languageName: node
+  linkType: hard
+
+"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4":
+  version: 7.28.4
+  resolution: "@babel/parser@npm:7.28.4"
+  dependencies:
+    "@babel/types": "npm:^7.28.4"
+  bin:
+    parser: ./bin/babel-parser.js
+  checksum: 10c0/58b239a5b1477ac7ed7e29d86d675cc81075ca055424eba6485872626db2dc556ce63c45043e5a679cd925e999471dba8a3ed4864e7ab1dbf64306ab72c52707
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-async-generators@npm:^7.8.4":
+  version: 7.8.4
+  resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-bigint@npm:^7.8.3":
+  version: 7.8.3
+  resolution: "@babel/plugin-syntax-bigint@npm:7.8.3"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/686891b81af2bc74c39013655da368a480f17dd237bf9fbc32048e5865cb706d5a8f65438030da535b332b1d6b22feba336da8fa931f663b6b34e13147d12dde
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-class-properties@npm:^7.12.13":
+  version: 7.12.13
+  resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.12.13"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-class-static-block@npm:^7.14.5":
+  version: 7.14.5
+  resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.14.5"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/4464bf9115f4a2d02ce1454411baf9cfb665af1da53709c5c56953e5e2913745b0fcce82982a00463d6facbdd93445c691024e310b91431a1e2f024b158f6371
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-import-attributes@npm:^7.24.7":
+  version: 7.27.1
+  resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.27.1"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/e66f7a761b8360419bbb93ab67d87c8a97465ef4637a985ff682ce7ba6918b34b29d81190204cf908d0933058ee7b42737423cd8a999546c21b3aabad4affa9a
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-import-meta@npm:^7.10.4":
+  version: 7.10.4
+  resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.10.4"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-json-strings@npm:^7.8.3":
+  version: 7.8.3
+  resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-jsx@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/plugin-syntax-jsx@npm:7.27.1"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.27.1"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/bc5afe6a458d5f0492c02a54ad98c5756a0c13bd6d20609aae65acd560a9e141b0876da5f358dce34ea136f271c1016df58b461184d7ae9c4321e0f98588bc84
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4":
+  version: 7.10.4
+  resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.10.4"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3":
+  version: 7.8.3
+  resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-numeric-separator@npm:^7.10.4":
+  version: 7.10.4
+  resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.10.4"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3":
+  version: 7.8.3
+  resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3":
+  version: 7.8.3
+  resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-optional-chaining@npm:^7.8.3":
+  version: 7.8.3
+  resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.8.0"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5":
+  version: 7.14.5
+  resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.14.5"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/69822772561706c87f0a65bc92d0772cea74d6bc0911537904a676d5ff496a6d3ac4e05a166d8125fce4a16605bace141afc3611074e170a994e66e5397787f3
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-top-level-await@npm:^7.14.5":
+  version: 7.14.5
+  resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.14.5"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f
+  languageName: node
+  linkType: hard
+
+"@babel/plugin-syntax-typescript@npm:^7.27.1":
+  version: 7.27.1
+  resolution: "@babel/plugin-syntax-typescript@npm:7.27.1"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.27.1"
+  peerDependencies:
+    "@babel/core": ^7.0.0-0
+  checksum: 10c0/11589b4c89c66ef02d57bf56c6246267851ec0c361f58929327dc3e070b0dab644be625bbe7fb4c4df30c3634bfdfe31244e1f517be397d2def1487dbbe3c37d
+  languageName: node
+  linkType: hard
+
+"@babel/template@npm:^7.27.2":
+  version: 7.27.2
+  resolution: "@babel/template@npm:7.27.2"
+  dependencies:
+    "@babel/code-frame": "npm:^7.27.1"
+    "@babel/parser": "npm:^7.27.2"
+    "@babel/types": "npm:^7.27.1"
+  checksum: 10c0/ed9e9022651e463cc5f2cc21942f0e74544f1754d231add6348ff1b472985a3b3502041c0be62dc99ed2d12cfae0c51394bf827452b98a2f8769c03b87aadc81
+  languageName: node
+  linkType: hard
+
+"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4":
+  version: 7.28.4
+  resolution: "@babel/traverse@npm:7.28.4"
+  dependencies:
+    "@babel/code-frame": "npm:^7.27.1"
+    "@babel/generator": "npm:^7.28.3"
+    "@babel/helper-globals": "npm:^7.28.0"
+    "@babel/parser": "npm:^7.28.4"
+    "@babel/template": "npm:^7.27.2"
+    "@babel/types": "npm:^7.28.4"
+    debug: "npm:^4.3.1"
+  checksum: 10c0/ee678fdd49c9f54a32e07e8455242390d43ce44887cea6567b233fe13907b89240c377e7633478a32c6cf1be0e17c2f7f3b0c59f0666e39c5074cc47b968489c
+  languageName: node
+  linkType: hard
+
+"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4":
+  version: 7.28.4
+  resolution: "@babel/types@npm:7.28.4"
+  dependencies:
+    "@babel/helper-string-parser": "npm:^7.27.1"
+    "@babel/helper-validator-identifier": "npm:^7.27.1"
+  checksum: 10c0/ac6f909d6191319e08c80efbfac7bd9a25f80cc83b43cd6d82e7233f7a6b9d6e7b90236f3af7400a3f83b576895bcab9188a22b584eb0f224e80e6d4e95f4517
+  languageName: node
+  linkType: hard
+
+"@bcoe/v8-coverage@npm:^0.2.3":
+  version: 0.2.3
+  resolution: "@bcoe/v8-coverage@npm:0.2.3"
+  checksum: 10c0/6b80ae4cb3db53f486da2dc63b6e190a74c8c3cca16bb2733f234a0b6a9382b09b146488ae08e2b22cf00f6c83e20f3e040a2f7894f05c045c946d6a090b1d52
+  languageName: node
+  linkType: hard
+
+"@cspotcode/source-map-support@npm:^0.8.0":
+  version: 0.8.1
+  resolution: "@cspotcode/source-map-support@npm:0.8.1"
+  dependencies:
+    "@jridgewell/trace-mapping": "npm:0.3.9"
+  checksum: 10c0/05c5368c13b662ee4c122c7bfbe5dc0b613416672a829f3e78bc49a357a197e0218d6e74e7c66cfcd04e15a179acab080bd3c69658c9fbefd0e1ccd950a07fc6
+  languageName: node
+  linkType: hard
+
+"@emnapi/core@npm:^1.4.3":
+  version: 1.5.0
+  resolution: "@emnapi/core@npm:1.5.0"
+  dependencies:
+    "@emnapi/wasi-threads": "npm:1.1.0"
+    tslib: "npm:^2.4.0"
+  checksum: 10c0/52ba3485277706d92fa27d92b37e5b4f6ef0742c03ed68f8096f294c6bfa30f0752c82d4c2bfa14bff4dc30d63c9f71a8f9fb64a92743d00807d9e468fafd5ff
+  languageName: node
+  linkType: hard
+
+"@emnapi/runtime@npm:^1.4.3":
+  version: 1.5.0
+  resolution: "@emnapi/runtime@npm:1.5.0"
+  dependencies:
+    tslib: "npm:^2.4.0"
+  checksum: 10c0/a85c9fc4e3af49cbe41e5437e5be2551392a931910cd0a5b5d3572532786927810c9cc1db11b232ec8f9657b33d4e6f7c4f985f1a052917d7cd703b5b2a20faa
+  languageName: node
+  linkType: hard
+
+"@emnapi/wasi-threads@npm:1.1.0":
+  version: 1.1.0
+  resolution: "@emnapi/wasi-threads@npm:1.1.0"
+  dependencies:
+    tslib: "npm:^2.4.0"
+  checksum: 10c0/e6d54bf2b1e64cdd83d2916411e44e579b6ae35d5def0dea61a3c452d9921373044dff32a8b8473ae60c80692bdc39323e98b96a3f3d87ba6886b24dd0ef7ca1
+  languageName: node
+  linkType: hard
+
+"@esbuild/aix-ppc64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/aix-ppc64@npm:0.25.10"
+  conditions: os=aix & cpu=ppc64
+  languageName: node
+  linkType: hard
+
+"@esbuild/android-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/android-arm64@npm:0.25.10"
+  conditions: os=android & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/android-arm@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/android-arm@npm:0.25.10"
+  conditions: os=android & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@esbuild/android-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/android-x64@npm:0.25.10"
+  conditions: os=android & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/darwin-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/darwin-arm64@npm:0.25.10"
+  conditions: os=darwin & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/darwin-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/darwin-x64@npm:0.25.10"
+  conditions: os=darwin & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/freebsd-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/freebsd-arm64@npm:0.25.10"
+  conditions: os=freebsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/freebsd-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/freebsd-x64@npm:0.25.10"
+  conditions: os=freebsd & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-arm64@npm:0.25.10"
+  conditions: os=linux & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-arm@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-arm@npm:0.25.10"
+  conditions: os=linux & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-ia32@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-ia32@npm:0.25.10"
+  conditions: os=linux & cpu=ia32
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-loong64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-loong64@npm:0.25.10"
+  conditions: os=linux & cpu=loong64
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-mips64el@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-mips64el@npm:0.25.10"
+  conditions: os=linux & cpu=mips64el
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-ppc64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-ppc64@npm:0.25.10"
+  conditions: os=linux & cpu=ppc64
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-riscv64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-riscv64@npm:0.25.10"
+  conditions: os=linux & cpu=riscv64
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-s390x@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-s390x@npm:0.25.10"
+  conditions: os=linux & cpu=s390x
+  languageName: node
+  linkType: hard
+
+"@esbuild/linux-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/linux-x64@npm:0.25.10"
+  conditions: os=linux & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/netbsd-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/netbsd-arm64@npm:0.25.10"
+  conditions: os=netbsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/netbsd-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/netbsd-x64@npm:0.25.10"
+  conditions: os=netbsd & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/openbsd-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/openbsd-arm64@npm:0.25.10"
+  conditions: os=openbsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/openbsd-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/openbsd-x64@npm:0.25.10"
+  conditions: os=openbsd & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/openharmony-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/openharmony-arm64@npm:0.25.10"
+  conditions: os=openharmony & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/sunos-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/sunos-x64@npm:0.25.10"
+  conditions: os=sunos & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@esbuild/win32-arm64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/win32-arm64@npm:0.25.10"
+  conditions: os=win32 & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/win32-ia32@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/win32-ia32@npm:0.25.10"
+  conditions: os=win32 & cpu=ia32
+  languageName: node
+  linkType: hard
+
+"@esbuild/win32-x64@npm:0.25.10":
+  version: 0.25.10
+  resolution: "@esbuild/win32-x64@npm:0.25.10"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@isaacs/balanced-match@npm:^4.0.1":
+  version: 4.0.1
+  resolution: "@isaacs/balanced-match@npm:4.0.1"
+  checksum: 10c0/7da011805b259ec5c955f01cee903da72ad97c5e6f01ca96197267d3f33103d5b2f8a1af192140f3aa64526c593c8d098ae366c2b11f7f17645d12387c2fd420
+  languageName: node
+  linkType: hard
+
+"@isaacs/brace-expansion@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "@isaacs/brace-expansion@npm:5.0.0"
+  dependencies:
+    "@isaacs/balanced-match": "npm:^4.0.1"
+  checksum: 10c0/b4d4812f4be53afc2c5b6c545001ff7a4659af68d4484804e9d514e183d20269bb81def8682c01a22b17c4d6aed14292c8494f7d2ac664e547101c1a905aa977
+  languageName: node
+  linkType: hard
+
+"@isaacs/cliui@npm:^8.0.2":
+  version: 8.0.2
+  resolution: "@isaacs/cliui@npm:8.0.2"
+  dependencies:
+    string-width: "npm:^5.1.2"
+    string-width-cjs: "npm:string-width@^4.2.0"
+    strip-ansi: "npm:^7.0.1"
+    strip-ansi-cjs: "npm:strip-ansi@^6.0.1"
+    wrap-ansi: "npm:^8.1.0"
+    wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0"
+  checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e
+  languageName: node
+  linkType: hard
+
+"@isaacs/fs-minipass@npm:^4.0.0":
+  version: 4.0.1
+  resolution: "@isaacs/fs-minipass@npm:4.0.1"
+  dependencies:
+    minipass: "npm:^7.0.4"
+  checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2
+  languageName: node
+  linkType: hard
+
+"@istanbuljs/load-nyc-config@npm:^1.0.0":
+  version: 1.1.0
+  resolution: "@istanbuljs/load-nyc-config@npm:1.1.0"
+  dependencies:
+    camelcase: "npm:^5.3.1"
+    find-up: "npm:^4.1.0"
+    get-package-type: "npm:^0.1.0"
+    js-yaml: "npm:^3.13.1"
+    resolve-from: "npm:^5.0.0"
+  checksum: 10c0/dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42
+  languageName: node
+  linkType: hard
+
+"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3":
+  version: 0.1.3
+  resolution: "@istanbuljs/schema@npm:0.1.3"
+  checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a
+  languageName: node
+  linkType: hard
+
+"@jest/console@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/console@npm:30.2.0"
+  dependencies:
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    chalk: "npm:^4.1.2"
+    jest-message-util: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+  checksum: 10c0/ecf7ca43698863095500710a5aa08c38b1731c9d89ba32f4d9da7424b53ce1e86b3db8ccbbb27b695f49b4f94bc1d7d0c63c751d73c83d59488a682bc98b7e70
+  languageName: node
+  linkType: hard
+
+"@jest/core@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/core@npm:30.2.0"
+  dependencies:
+    "@jest/console": "npm:30.2.0"
+    "@jest/pattern": "npm:30.0.1"
+    "@jest/reporters": "npm:30.2.0"
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/transform": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    ansi-escapes: "npm:^4.3.2"
+    chalk: "npm:^4.1.2"
+    ci-info: "npm:^4.2.0"
+    exit-x: "npm:^0.2.2"
+    graceful-fs: "npm:^4.2.11"
+    jest-changed-files: "npm:30.2.0"
+    jest-config: "npm:30.2.0"
+    jest-haste-map: "npm:30.2.0"
+    jest-message-util: "npm:30.2.0"
+    jest-regex-util: "npm:30.0.1"
+    jest-resolve: "npm:30.2.0"
+    jest-resolve-dependencies: "npm:30.2.0"
+    jest-runner: "npm:30.2.0"
+    jest-runtime: "npm:30.2.0"
+    jest-snapshot: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    jest-validate: "npm:30.2.0"
+    jest-watcher: "npm:30.2.0"
+    micromatch: "npm:^4.0.8"
+    pretty-format: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+  peerDependencies:
+    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+  peerDependenciesMeta:
+    node-notifier:
+      optional: true
+  checksum: 10c0/03b3e35df3bbbbe28e2b53c0fe82d39b748d99b3bc88bb645c76593cdca44d7115f03ef6e6a1715f0862151d0ebab496199283def248fc05eb520f6aec6b20f3
+  languageName: node
+  linkType: hard
+
+"@jest/diff-sequences@npm:30.0.1":
+  version: 30.0.1
+  resolution: "@jest/diff-sequences@npm:30.0.1"
+  checksum: 10c0/3a840404e6021725ef7f86b11f7b2d13dd02846481264db0e447ee33b7ee992134e402cdc8b8b0ac969d37c6c0183044e382dedee72001cdf50cfb3c8088de74
+  languageName: node
+  linkType: hard
+
+"@jest/environment@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/environment@npm:30.2.0"
+  dependencies:
+    "@jest/fake-timers": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    jest-mock: "npm:30.2.0"
+  checksum: 10c0/56a9f1b82ee2623c13eece7d58188be35bd6e5c3c4ee3fbaedb1c4d7242c1b57d020f1a26ab127fa9496fdc11306c7ad1c4a2b7eba1fc726a27ae0873e907e47
+  languageName: node
+  linkType: hard
+
+"@jest/expect-utils@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/expect-utils@npm:30.2.0"
+  dependencies:
+    "@jest/get-type": "npm:30.1.0"
+  checksum: 10c0/e25a809ff2ab62292e2569f8d97f89168d27d078903f0306af5f70f1771b7efc62c458eca1dcb491ab1ed96cefedf403bd7acbb050c997105bc29b220fd9d61a
+  languageName: node
+  linkType: hard
+
+"@jest/expect@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/expect@npm:30.2.0"
+  dependencies:
+    expect: "npm:30.2.0"
+    jest-snapshot: "npm:30.2.0"
+  checksum: 10c0/3984879022780dd480301c560cef465156b29d610f2c698fcdf81ad76930411d7816eff7cb721e81a1d9aaa8c2240a73c20be9385d1978c14b405a2ac6c9104a
+  languageName: node
+  linkType: hard
+
+"@jest/fake-timers@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/fake-timers@npm:30.2.0"
+  dependencies:
+    "@jest/types": "npm:30.2.0"
+    "@sinonjs/fake-timers": "npm:^13.0.0"
+    "@types/node": "npm:*"
+    jest-message-util: "npm:30.2.0"
+    jest-mock: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+  checksum: 10c0/b29505528e546f08489535814f7dfcd3a2318660b987d605f44d41672e91a0c8c0dfc01e3dd1302e66e511409c3012d41e2e16703b214502b54ccc023773e3dc
+  languageName: node
+  linkType: hard
+
+"@jest/get-type@npm:30.1.0":
+  version: 30.1.0
+  resolution: "@jest/get-type@npm:30.1.0"
+  checksum: 10c0/3e65fd5015f551c51ec68fca31bbd25b466be0e8ee8075d9610fa1c686ea1e70a942a0effc7b10f4ea9a338c24337e1ad97ff69d3ebacc4681b7e3e80d1b24ac
+  languageName: node
+  linkType: hard
+
+"@jest/globals@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/globals@npm:30.2.0"
+  dependencies:
+    "@jest/environment": "npm:30.2.0"
+    "@jest/expect": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    jest-mock: "npm:30.2.0"
+  checksum: 10c0/7433a501e3122e94b24a7bacc44fdc3921b20abf67c9d795f5bdd169f1beac058cff8109e4fddf71fdc8b18e532cb88c55412ca9927966f354930d6bb3fcaf9c
+  languageName: node
+  linkType: hard
+
+"@jest/pattern@npm:30.0.1":
+  version: 30.0.1
+  resolution: "@jest/pattern@npm:30.0.1"
+  dependencies:
+    "@types/node": "npm:*"
+    jest-regex-util: "npm:30.0.1"
+  checksum: 10c0/32c5a7bfb6c591f004dac0ed36d645002ed168971e4c89bd915d1577031672870032594767557b855c5bc330aa1e39a2f54bf150d2ee88a7a0886e9cb65318bc
+  languageName: node
+  linkType: hard
+
+"@jest/reporters@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/reporters@npm:30.2.0"
+  dependencies:
+    "@bcoe/v8-coverage": "npm:^0.2.3"
+    "@jest/console": "npm:30.2.0"
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/transform": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@jridgewell/trace-mapping": "npm:^0.3.25"
+    "@types/node": "npm:*"
+    chalk: "npm:^4.1.2"
+    collect-v8-coverage: "npm:^1.0.2"
+    exit-x: "npm:^0.2.2"
+    glob: "npm:^10.3.10"
+    graceful-fs: "npm:^4.2.11"
+    istanbul-lib-coverage: "npm:^3.0.0"
+    istanbul-lib-instrument: "npm:^6.0.0"
+    istanbul-lib-report: "npm:^3.0.0"
+    istanbul-lib-source-maps: "npm:^5.0.0"
+    istanbul-reports: "npm:^3.1.3"
+    jest-message-util: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    jest-worker: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+    string-length: "npm:^4.0.2"
+    v8-to-istanbul: "npm:^9.0.1"
+  peerDependencies:
+    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+  peerDependenciesMeta:
+    node-notifier:
+      optional: true
+  checksum: 10c0/1f25d0896f857f220466cae3145a20f9e13e7d73aeccf87a1f8a5accb42bb7a564864ba63befa3494d76d1335b86c24d66054d62330c3dcffc9c2c5f4e740d6e
+  languageName: node
+  linkType: hard
+
+"@jest/schemas@npm:30.0.5":
+  version: 30.0.5
+  resolution: "@jest/schemas@npm:30.0.5"
+  dependencies:
+    "@sinclair/typebox": "npm:^0.34.0"
+  checksum: 10c0/449dcd7ec5c6505e9ac3169d1143937e67044ae3e66a729ce4baf31812dfd30535f2b3b2934393c97cfdf5984ff581120e6b38f62b8560c8b5b7cc07f4175f65
+  languageName: node
+  linkType: hard
+
+"@jest/snapshot-utils@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/snapshot-utils@npm:30.2.0"
+  dependencies:
+    "@jest/types": "npm:30.2.0"
+    chalk: "npm:^4.1.2"
+    graceful-fs: "npm:^4.2.11"
+    natural-compare: "npm:^1.4.0"
+  checksum: 10c0/df69ee3b95d64db6d1e79e39d5dc226e417b412a1d5113264b487eb3a8887366a7952c350c378e2292f8e83ec1b3be22040317b795e85eb431830cbde06d09d8
+  languageName: node
+  linkType: hard
+
+"@jest/source-map@npm:30.0.1":
+  version: 30.0.1
+  resolution: "@jest/source-map@npm:30.0.1"
+  dependencies:
+    "@jridgewell/trace-mapping": "npm:^0.3.25"
+    callsites: "npm:^3.1.0"
+    graceful-fs: "npm:^4.2.11"
+  checksum: 10c0/e7bda2786fc9f483d9dd7566c58c4bd948830997be862dfe80a3ae5550ff3f84753abb52e705d02ebe9db9f34ba7ebec4c2db11882048cdeef7a66f6332b3897
+  languageName: node
+  linkType: hard
+
+"@jest/test-result@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/test-result@npm:30.2.0"
+  dependencies:
+    "@jest/console": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/istanbul-lib-coverage": "npm:^2.0.6"
+    collect-v8-coverage: "npm:^1.0.2"
+  checksum: 10c0/87566d56b4f90630282c103f41ea9031f4647902f2cd9839bc49af6248301c1a95cbc4432a9512e61f6c6d778e8b925d0573588b26a211d3198c62471ba08c81
+  languageName: node
+  linkType: hard
+
+"@jest/test-sequencer@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/test-sequencer@npm:30.2.0"
+  dependencies:
+    "@jest/test-result": "npm:30.2.0"
+    graceful-fs: "npm:^4.2.11"
+    jest-haste-map: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+  checksum: 10c0/b8366e629b885bfc4b2b95f34f47405e70120eb8601f42de20ea4de308a5088d7bd9f535abf67a2a0d083a2b49864176e1333e036426a5d6b6bd02c1c4dda40b
+  languageName: node
+  linkType: hard
+
+"@jest/transform@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/transform@npm:30.2.0"
+  dependencies:
+    "@babel/core": "npm:^7.27.4"
+    "@jest/types": "npm:30.2.0"
+    "@jridgewell/trace-mapping": "npm:^0.3.25"
+    babel-plugin-istanbul: "npm:^7.0.1"
+    chalk: "npm:^4.1.2"
+    convert-source-map: "npm:^2.0.0"
+    fast-json-stable-stringify: "npm:^2.1.0"
+    graceful-fs: "npm:^4.2.11"
+    jest-haste-map: "npm:30.2.0"
+    jest-regex-util: "npm:30.0.1"
+    jest-util: "npm:30.2.0"
+    micromatch: "npm:^4.0.8"
+    pirates: "npm:^4.0.7"
+    slash: "npm:^3.0.0"
+    write-file-atomic: "npm:^5.0.1"
+  checksum: 10c0/c0f21576de9f7ad8a2647450b5cd127d7c60176c19a666230241d121b9f928b036dd19973363e4acd7db2f8b82caff2b624930f57471be6092d73a7775365606
+  languageName: node
+  linkType: hard
+
+"@jest/types@npm:30.2.0":
+  version: 30.2.0
+  resolution: "@jest/types@npm:30.2.0"
+  dependencies:
+    "@jest/pattern": "npm:30.0.1"
+    "@jest/schemas": "npm:30.0.5"
+    "@types/istanbul-lib-coverage": "npm:^2.0.6"
+    "@types/istanbul-reports": "npm:^3.0.4"
+    "@types/node": "npm:*"
+    "@types/yargs": "npm:^17.0.33"
+    chalk: "npm:^4.1.2"
+  checksum: 10c0/ae121f6963bd9ed1cd9651db7be91bf14c05bff0d0eec4fca9fecf586bea4005e8f1de8cc9b8ef72e424ea96a309d123bef510b55a6a17a3b4b91a39d775e5cd
+  languageName: node
+  linkType: hard
+
+"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5":
+  version: 0.3.13
+  resolution: "@jridgewell/gen-mapping@npm:0.3.13"
+  dependencies:
+    "@jridgewell/sourcemap-codec": "npm:^1.5.0"
+    "@jridgewell/trace-mapping": "npm:^0.3.24"
+  checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b
+  languageName: node
+  linkType: hard
+
+"@jridgewell/remapping@npm:^2.3.5":
+  version: 2.3.5
+  resolution: "@jridgewell/remapping@npm:2.3.5"
+  dependencies:
+    "@jridgewell/gen-mapping": "npm:^0.3.5"
+    "@jridgewell/trace-mapping": "npm:^0.3.24"
+  checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194
+  languageName: node
+  linkType: hard
+
+"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0":
+  version: 3.1.2
+  resolution: "@jridgewell/resolve-uri@npm:3.1.2"
+  checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e
+  languageName: node
+  linkType: hard
+
+"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5":
+  version: 1.5.5
+  resolution: "@jridgewell/sourcemap-codec@npm:1.5.5"
+  checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0
+  languageName: node
+  linkType: hard
+
+"@jridgewell/trace-mapping@npm:0.3.9":
+  version: 0.3.9
+  resolution: "@jridgewell/trace-mapping@npm:0.3.9"
+  dependencies:
+    "@jridgewell/resolve-uri": "npm:^3.0.3"
+    "@jridgewell/sourcemap-codec": "npm:^1.4.10"
+  checksum: 10c0/fa425b606d7c7ee5bfa6a31a7b050dd5814b4082f318e0e4190f991902181b4330f43f4805db1dd4f2433fd0ed9cc7a7b9c2683f1deeab1df1b0a98b1e24055b
+  languageName: node
+  linkType: hard
+
+"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28":
+  version: 0.3.31
+  resolution: "@jridgewell/trace-mapping@npm:0.3.31"
+  dependencies:
+    "@jridgewell/resolve-uri": "npm:^3.1.0"
+    "@jridgewell/sourcemap-codec": "npm:^1.4.14"
+  checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9
+  languageName: node
+  linkType: hard
+
+"@microsoft/api-extractor-model@npm:7.31.0":
+  version: 7.31.0
+  resolution: "@microsoft/api-extractor-model@npm:7.31.0"
+  dependencies:
+    "@microsoft/tsdoc": "npm:~0.15.1"
+    "@microsoft/tsdoc-config": "npm:~0.17.1"
+    "@rushstack/node-core-library": "npm:5.16.0"
+  checksum: 10c0/b8fc06a8aea98fc6f9357e8ea59177fc3432e0c309a1604d80d28ed6723bd9c5292c02723d7ad1a5097aef54d3daaf65c529bf9c3717edff2f02994f92dc8fd1
+  languageName: node
+  linkType: hard
+
+"@microsoft/api-extractor@npm:^7.50.1":
+  version: 7.53.0
+  resolution: "@microsoft/api-extractor@npm:7.53.0"
+  dependencies:
+    "@microsoft/api-extractor-model": "npm:7.31.0"
+    "@microsoft/tsdoc": "npm:~0.15.1"
+    "@microsoft/tsdoc-config": "npm:~0.17.1"
+    "@rushstack/node-core-library": "npm:5.16.0"
+    "@rushstack/rig-package": "npm:0.6.0"
+    "@rushstack/terminal": "npm:0.19.0"
+    "@rushstack/ts-command-line": "npm:5.1.0"
+    lodash: "npm:~4.17.15"
+    minimatch: "npm:10.0.3"
+    resolve: "npm:~1.22.1"
+    semver: "npm:~7.5.4"
+    source-map: "npm:~0.6.1"
+    typescript: "npm:5.8.2"
+  bin:
+    api-extractor: bin/api-extractor
+  checksum: 10c0/bc092cadd8f5dec025b9b379ed6e7be6ff1ce694be0e3f53d04829c50897f085ee5dd25793f2727fe2bd862175a2b69d022009212bc0ec36eae225e6bb810e36
+  languageName: node
+  linkType: hard
+
+"@microsoft/tsdoc-config@npm:~0.17.1":
+  version: 0.17.1
+  resolution: "@microsoft/tsdoc-config@npm:0.17.1"
+  dependencies:
+    "@microsoft/tsdoc": "npm:0.15.1"
+    ajv: "npm:~8.12.0"
+    jju: "npm:~1.4.0"
+    resolve: "npm:~1.22.2"
+  checksum: 10c0/a686355796f492f27af17e2a17d615221309caf4d9f9047a5a8f17f8625c467c4c81e2a7923ddafd71b892631d5e5013c4b8cc49c5867d3cc1d260fd90c1413d
+  languageName: node
+  linkType: hard
+
+"@microsoft/tsdoc@npm:0.15.1, @microsoft/tsdoc@npm:~0.15.1":
+  version: 0.15.1
+  resolution: "@microsoft/tsdoc@npm:0.15.1"
+  checksum: 10c0/09948691fac56c45a0d1920de478d66a30371a325bd81addc92eea5654d95106ce173c440fea1a1bd5bb95b3a544b6d4def7bb0b5a846c05d043575d8369a20c
+  languageName: node
+  linkType: hard
+
+"@napi-rs/wasm-runtime@npm:^0.2.11":
+  version: 0.2.12
+  resolution: "@napi-rs/wasm-runtime@npm:0.2.12"
+  dependencies:
+    "@emnapi/core": "npm:^1.4.3"
+    "@emnapi/runtime": "npm:^1.4.3"
+    "@tybys/wasm-util": "npm:^0.10.0"
+  checksum: 10c0/6d07922c0613aab30c6a497f4df297ca7c54e5b480e00035e0209b872d5c6aab7162fc49477267556109c2c7ed1eb9c65a174e27e9b87568106a87b0a6e3ca7d
+  languageName: node
+  linkType: hard
+
+"@npmcli/agent@npm:^2.0.0":
+  version: 2.2.2
+  resolution: "@npmcli/agent@npm:2.2.2"
+  dependencies:
+    agent-base: "npm:^7.1.0"
+    http-proxy-agent: "npm:^7.0.0"
+    https-proxy-agent: "npm:^7.0.1"
+    lru-cache: "npm:^10.0.1"
+    socks-proxy-agent: "npm:^8.0.3"
+  checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae
+  languageName: node
+  linkType: hard
+
+"@npmcli/agent@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "@npmcli/agent@npm:3.0.0"
+  dependencies:
+    agent-base: "npm:^7.1.0"
+    http-proxy-agent: "npm:^7.0.0"
+    https-proxy-agent: "npm:^7.0.1"
+    lru-cache: "npm:^10.0.1"
+    socks-proxy-agent: "npm:^8.0.3"
+  checksum: 10c0/efe37b982f30740ee77696a80c196912c274ecd2cb243bc6ae7053a50c733ce0f6c09fda085145f33ecf453be19654acca74b69e81eaad4c90f00ccffe2f9271
+  languageName: node
+  linkType: hard
+
+"@npmcli/fs@npm:^3.1.0":
+  version: 3.1.1
+  resolution: "@npmcli/fs@npm:3.1.1"
+  dependencies:
+    semver: "npm:^7.3.5"
+  checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99
+  languageName: node
+  linkType: hard
+
+"@npmcli/fs@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "@npmcli/fs@npm:4.0.0"
+  dependencies:
+    semver: "npm:^7.3.5"
+  checksum: 10c0/c90935d5ce670c87b6b14fab04a965a3b8137e585f8b2a6257263bd7f97756dd736cb165bb470e5156a9e718ecd99413dccc54b1138c1a46d6ec7cf325982fe5
+  languageName: node
+  linkType: hard
+
+"@pkgjs/parseargs@npm:^0.11.0":
+  version: 0.11.0
+  resolution: "@pkgjs/parseargs@npm:0.11.0"
+  checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd
+  languageName: node
+  linkType: hard
+
+"@pkgr/core@npm:^0.2.9":
+  version: 0.2.9
+  resolution: "@pkgr/core@npm:0.2.9"
+  checksum: 10c0/ac8e4e8138b1a7a4ac6282873aef7389c352f1f8b577b4850778f5182e4a39a5241facbe48361fec817f56d02b51691b383010843fb08b34a8e8ea3614688fd5
+  languageName: node
+  linkType: hard
+
+"@rollup/pluginutils@npm:^5.1.4":
+  version: 5.3.0
+  resolution: "@rollup/pluginutils@npm:5.3.0"
+  dependencies:
+    "@types/estree": "npm:^1.0.0"
+    estree-walker: "npm:^2.0.2"
+    picomatch: "npm:^4.0.2"
+  peerDependencies:
+    rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+  peerDependenciesMeta:
+    rollup:
+      optional: true
+  checksum: 10c0/001834bf62d7cf5bac424d2617c113f7f7d3b2bf3c1778cbcccb72cdc957b68989f8e7747c782c2b911f1dde8257f56f8ac1e779e29e74e638e3f1e2cac2bcd0
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-android-arm-eabi@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-android-arm-eabi@npm:4.52.4"
+  conditions: os=android & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-android-arm64@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-android-arm64@npm:4.52.4"
+  conditions: os=android & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-darwin-arm64@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-darwin-arm64@npm:4.52.4"
+  conditions: os=darwin & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-darwin-x64@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-darwin-x64@npm:4.52.4"
+  conditions: os=darwin & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-freebsd-arm64@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-freebsd-arm64@npm:4.52.4"
+  conditions: os=freebsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-freebsd-x64@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-freebsd-x64@npm:4.52.4"
+  conditions: os=freebsd & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm-gnueabihf@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.52.4"
+  conditions: os=linux & cpu=arm & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm-musleabihf@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.52.4"
+  conditions: os=linux & cpu=arm & libc=musl
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm64-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.52.4"
+  conditions: os=linux & cpu=arm64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm64-musl@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-arm64-musl@npm:4.52.4"
+  conditions: os=linux & cpu=arm64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-loong64-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.52.4"
+  conditions: os=linux & cpu=loong64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-ppc64-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.52.4"
+  conditions: os=linux & cpu=ppc64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-riscv64-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.52.4"
+  conditions: os=linux & cpu=riscv64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-riscv64-musl@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.52.4"
+  conditions: os=linux & cpu=riscv64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-s390x-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.52.4"
+  conditions: os=linux & cpu=s390x & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-x64-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-x64-gnu@npm:4.52.4"
+  conditions: os=linux & cpu=x64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-x64-musl@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-linux-x64-musl@npm:4.52.4"
+  conditions: os=linux & cpu=x64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-openharmony-arm64@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-openharmony-arm64@npm:4.52.4"
+  conditions: os=openharmony & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-arm64-msvc@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.52.4"
+  conditions: os=win32 & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-ia32-msvc@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.52.4"
+  conditions: os=win32 & cpu=ia32
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-x64-gnu@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-win32-x64-gnu@npm:4.52.4"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-win32-x64-msvc@npm:4.52.4":
+  version: 4.52.4
+  resolution: "@rollup/rollup-win32-x64-msvc@npm:4.52.4"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@rushstack/node-core-library@npm:5.16.0":
+  version: 5.16.0
+  resolution: "@rushstack/node-core-library@npm:5.16.0"
+  dependencies:
+    ajv: "npm:~8.13.0"
+    ajv-draft-04: "npm:~1.0.0"
+    ajv-formats: "npm:~3.0.1"
+    fs-extra: "npm:~11.3.0"
+    import-lazy: "npm:~4.0.0"
+    jju: "npm:~1.4.0"
+    resolve: "npm:~1.22.1"
+    semver: "npm:~7.5.4"
+  peerDependencies:
+    "@types/node": "*"
+  peerDependenciesMeta:
+    "@types/node":
+      optional: true
+  checksum: 10c0/b89ede99eb050f8430c742d8cb57446bba9cb0aaa0948df75cc0b93abfdb1cc83fc6f8d1d984a6011c4e92a32229de3c43273e9d49c7d5b84693b5cf159f6907
+  languageName: node
+  linkType: hard
+
+"@rushstack/problem-matcher@npm:0.1.1":
+  version: 0.1.1
+  resolution: "@rushstack/problem-matcher@npm:0.1.1"
+  peerDependencies:
+    "@types/node": "*"
+  peerDependenciesMeta:
+    "@types/node":
+      optional: true
+  checksum: 10c0/c847e721d3536ebb316fdd90b3e4033a7d24ff8c70e38e3eaeaadf167c4d14a7f16377ae4af8097532386bcfa81c15cfec7d2da517542c07882d273d56861d78
+  languageName: node
+  linkType: hard
+
+"@rushstack/rig-package@npm:0.6.0":
+  version: 0.6.0
+  resolution: "@rushstack/rig-package@npm:0.6.0"
+  dependencies:
+    resolve: "npm:~1.22.1"
+    strip-json-comments: "npm:~3.1.1"
+  checksum: 10c0/303c5c010a698343124036414dbeed44b24e67585307ffa6effd052624b0384cc08a12aeb153e8466b7abd6f516900ecf8629600230f0f2c33cd5c0c3dace65e
+  languageName: node
+  linkType: hard
+
+"@rushstack/terminal@npm:0.19.0":
+  version: 0.19.0
+  resolution: "@rushstack/terminal@npm:0.19.0"
+  dependencies:
+    "@rushstack/node-core-library": "npm:5.16.0"
+    "@rushstack/problem-matcher": "npm:0.1.1"
+    supports-color: "npm:~8.1.1"
+  peerDependencies:
+    "@types/node": "*"
+  peerDependenciesMeta:
+    "@types/node":
+      optional: true
+  checksum: 10c0/c7e9b14c9ad1a174861ec15d19f6725db3c74771c87b16089a2010d8721e7136f72dcf432832ad8a348d45805360983206f10095e9d4ac1eb3861ff243062b30
+  languageName: node
+  linkType: hard
+
+"@rushstack/ts-command-line@npm:5.1.0":
+  version: 5.1.0
+  resolution: "@rushstack/ts-command-line@npm:5.1.0"
+  dependencies:
+    "@rushstack/terminal": "npm:0.19.0"
+    "@types/argparse": "npm:1.0.38"
+    argparse: "npm:~1.0.9"
+    string-argv: "npm:~0.3.1"
+  checksum: 10c0/5b32e2f3bc11c32bed6f46510bccb53d691d41769767de823cb945baa0a999918a69b4f69e35db7d7df1ded67fa547085ff46856cea383475f4d2254f6400576
+  languageName: node
+  linkType: hard
+
+"@sinclair/typebox@npm:^0.34.0":
+  version: 0.34.41
+  resolution: "@sinclair/typebox@npm:0.34.41"
+  checksum: 10c0/0fb61fc2f90c25e30b19b0096eb8ab3ccef401d3e2acfce42168ff0ee877ba5981c8243fa6b1035ac756cde95316724e978b2837dd642d7e4e095de03a999c90
+  languageName: node
+  linkType: hard
+
+"@sinonjs/commons@npm:^3.0.1":
+  version: 3.0.1
+  resolution: "@sinonjs/commons@npm:3.0.1"
+  dependencies:
+    type-detect: "npm:4.0.8"
+  checksum: 10c0/1227a7b5bd6c6f9584274db996d7f8cee2c8c350534b9d0141fc662eaf1f292ea0ae3ed19e5e5271c8fd390d27e492ca2803acd31a1978be2cdc6be0da711403
+  languageName: node
+  linkType: hard
+
+"@sinonjs/fake-timers@npm:^13.0.0":
+  version: 13.0.5
+  resolution: "@sinonjs/fake-timers@npm:13.0.5"
+  dependencies:
+    "@sinonjs/commons": "npm:^3.0.1"
+  checksum: 10c0/a707476efd523d2138ef6bba916c83c4a377a8372ef04fad87499458af9f01afc58f4f245c5fd062793d6d70587309330c6f96947b5bd5697961c18004dc3e26
+  languageName: node
+  linkType: hard
+
+"@tsconfig/node10@npm:^1.0.7":
+  version: 1.0.11
+  resolution: "@tsconfig/node10@npm:1.0.11"
+  checksum: 10c0/28a0710e5d039e0de484bdf85fee883bfd3f6a8980601f4d44066b0a6bcd821d31c4e231d1117731c4e24268bd4cf2a788a6787c12fc7f8d11014c07d582783c
+  languageName: node
+  linkType: hard
+
+"@tsconfig/node12@npm:^1.0.7":
+  version: 1.0.11
+  resolution: "@tsconfig/node12@npm:1.0.11"
+  checksum: 10c0/dddca2b553e2bee1308a056705103fc8304e42bb2d2cbd797b84403a223b25c78f2c683ec3e24a095e82cd435387c877239bffcb15a590ba817cd3f6b9a99fd9
+  languageName: node
+  linkType: hard
+
+"@tsconfig/node14@npm:^1.0.0":
+  version: 1.0.3
+  resolution: "@tsconfig/node14@npm:1.0.3"
+  checksum: 10c0/67c1316d065fdaa32525bc9449ff82c197c4c19092b9663b23213c8cbbf8d88b6ed6a17898e0cbc2711950fbfaf40388938c1c748a2ee89f7234fc9e7fe2bf44
+  languageName: node
+  linkType: hard
+
+"@tsconfig/node16@npm:^1.0.2":
+  version: 1.0.4
+  resolution: "@tsconfig/node16@npm:1.0.4"
+  checksum: 10c0/05f8f2734e266fb1839eb1d57290df1664fe2aa3b0fdd685a9035806daa635f7519bf6d5d9b33f6e69dd545b8c46bd6e2b5c79acb2b1f146e885f7f11a42a5bb
+  languageName: node
+  linkType: hard
+
+"@tybys/wasm-util@npm:^0.10.0":
+  version: 0.10.1
+  resolution: "@tybys/wasm-util@npm:0.10.1"
+  dependencies:
+    tslib: "npm:^2.4.0"
+  checksum: 10c0/b255094f293794c6d2289300c5fbcafbb5532a3aed3a5ffd2f8dc1828e639b88d75f6a376dd8f94347a44813fd7a7149d8463477a9a49525c8b2dcaa38c2d1e8
+  languageName: node
+  linkType: hard
+
+"@types/argparse@npm:1.0.38":
+  version: 1.0.38
+  resolution: "@types/argparse@npm:1.0.38"
+  checksum: 10c0/4fc892da5df16923f48180da2d1f4562fa8b0507cf636b24780444fa0a1d7321d4dc0c0ecbee6152968823f5a2ae0d321b4f8c705a489bf1ae1245bdeb0868fd
+  languageName: node
+  linkType: hard
+
+"@types/babel__core@npm:^7.20.5":
+  version: 7.20.5
+  resolution: "@types/babel__core@npm:7.20.5"
+  dependencies:
+    "@babel/parser": "npm:^7.20.7"
+    "@babel/types": "npm:^7.20.7"
+    "@types/babel__generator": "npm:*"
+    "@types/babel__template": "npm:*"
+    "@types/babel__traverse": "npm:*"
+  checksum: 10c0/bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff
+  languageName: node
+  linkType: hard
+
+"@types/babel__generator@npm:*":
+  version: 7.27.0
+  resolution: "@types/babel__generator@npm:7.27.0"
+  dependencies:
+    "@babel/types": "npm:^7.0.0"
+  checksum: 10c0/9f9e959a8792df208a9d048092fda7e1858bddc95c6314857a8211a99e20e6830bdeb572e3587ae8be5429e37f2a96fcf222a9f53ad232f5537764c9e13a2bbd
+  languageName: node
+  linkType: hard
+
+"@types/babel__template@npm:*":
+  version: 7.4.4
+  resolution: "@types/babel__template@npm:7.4.4"
+  dependencies:
+    "@babel/parser": "npm:^7.1.0"
+    "@babel/types": "npm:^7.0.0"
+  checksum: 10c0/cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b
+  languageName: node
+  linkType: hard
+
+"@types/babel__traverse@npm:*":
+  version: 7.28.0
+  resolution: "@types/babel__traverse@npm:7.28.0"
+  dependencies:
+    "@babel/types": "npm:^7.28.2"
+  checksum: 10c0/b52d7d4e8fc6a9018fe7361c4062c1c190f5778cf2466817cb9ed19d69fbbb54f9a85ffedeb748ed8062d2cf7d4cc088ee739848f47c57740de1c48cbf0d0994
+  languageName: node
+  linkType: hard
+
+"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0":
+  version: 1.0.8
+  resolution: "@types/estree@npm:1.0.8"
+  checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5
+  languageName: node
+  linkType: hard
+
+"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6":
+  version: 2.0.6
+  resolution: "@types/istanbul-lib-coverage@npm:2.0.6"
+  checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7
+  languageName: node
+  linkType: hard
+
+"@types/istanbul-lib-report@npm:*":
+  version: 3.0.3
+  resolution: "@types/istanbul-lib-report@npm:3.0.3"
+  dependencies:
+    "@types/istanbul-lib-coverage": "npm:*"
+  checksum: 10c0/247e477bbc1a77248f3c6de5dadaae85ff86ac2d76c5fc6ab1776f54512a745ff2a5f791d22b942e3990ddbd40f3ef5289317c4fca5741bedfaa4f01df89051c
+  languageName: node
+  linkType: hard
+
+"@types/istanbul-reports@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "@types/istanbul-reports@npm:3.0.4"
+  dependencies:
+    "@types/istanbul-lib-report": "npm:*"
+  checksum: 10c0/1647fd402aced5b6edac87274af14ebd6b3a85447ef9ad11853a70fd92a98d35f81a5d3ea9fcb5dbb5834e800c6e35b64475e33fcae6bfa9acc70d61497c54ee
+  languageName: node
+  linkType: hard
+
+"@types/jest@npm:^30.0.0":
+  version: 30.0.0
+  resolution: "@types/jest@npm:30.0.0"
+  dependencies:
+    expect: "npm:^30.0.0"
+    pretty-format: "npm:^30.0.0"
+  checksum: 10c0/20c6ce574154bc16f8dd6a97afacca4b8c4921a819496a3970382031c509ebe87a1b37b152a1b8475089b82d8ca951a9e95beb4b9bf78fbf579b1536f0b65969
+  languageName: node
+  linkType: hard
+
+"@types/node@npm:*, @types/node@npm:^24.6.2":
+  version: 24.6.2
+  resolution: "@types/node@npm:24.6.2"
+  dependencies:
+    undici-types: "npm:~7.13.0"
+  checksum: 10c0/d029757711be85ec468686f66cd8eca78f5996d7e2b1a5b818436e0299b19925b0fb4f7509a6b62750abdc72d66f5750ce22fb8b55559baca86df89a9c44722e
+  languageName: node
+  linkType: hard
+
+"@types/stack-utils@npm:^2.0.3":
+  version: 2.0.3
+  resolution: "@types/stack-utils@npm:2.0.3"
+  checksum: 10c0/1f4658385ae936330581bcb8aa3a066df03867d90281cdf89cc356d404bd6579be0f11902304e1f775d92df22c6dd761d4451c804b0a4fba973e06211e9bd77c
+  languageName: node
+  linkType: hard
+
+"@types/yargs-parser@npm:*":
+  version: 21.0.3
+  resolution: "@types/yargs-parser@npm:21.0.3"
+  checksum: 10c0/e71c3bd9d0b73ca82e10bee2064c384ab70f61034bbfb78e74f5206283fc16a6d85267b606b5c22cb2a3338373586786fed595b2009825d6a9115afba36560a0
+  languageName: node
+  linkType: hard
+
+"@types/yargs@npm:^17.0.33":
+  version: 17.0.33
+  resolution: "@types/yargs@npm:17.0.33"
+  dependencies:
+    "@types/yargs-parser": "npm:*"
+  checksum: 10c0/d16937d7ac30dff697801c3d6f235be2166df42e4a88bf730fa6dc09201de3727c0a9500c59a672122313341de5f24e45ee0ff579c08ce91928e519090b7906b
+  languageName: node
+  linkType: hard
+
+"@ungap/structured-clone@npm:^1.3.0":
+  version: 1.3.0
+  resolution: "@ungap/structured-clone@npm:1.3.0"
+  checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1"
+  conditions: os=android & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-android-arm64@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1"
+  conditions: os=android & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-darwin-arm64@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1"
+  conditions: os=darwin & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-darwin-x64@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1"
+  conditions: os=darwin & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-freebsd-x64@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1"
+  conditions: os=freebsd & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1"
+  conditions: os=linux & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1"
+  conditions: os=linux & cpu=arm
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1"
+  conditions: os=linux & cpu=arm64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1"
+  conditions: os=linux & cpu=arm64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1"
+  conditions: os=linux & cpu=ppc64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1"
+  conditions: os=linux & cpu=riscv64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1"
+  conditions: os=linux & cpu=riscv64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1"
+  conditions: os=linux & cpu=s390x & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1"
+  conditions: os=linux & cpu=x64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1"
+  conditions: os=linux & cpu=x64 & libc=musl
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1"
+  dependencies:
+    "@napi-rs/wasm-runtime": "npm:^0.2.11"
+  conditions: cpu=wasm32
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1"
+  conditions: os=win32 & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1"
+  conditions: os=win32 & cpu=ia32
+  languageName: node
+  linkType: hard
+
+"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1":
+  version: 1.11.1
+  resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1"
+  conditions: os=win32 & cpu=x64
+  languageName: node
+  linkType: hard
+
+"@veehz/gpu.js@npm:^2.16.0":
+  version: 2.16.0
+  resolution: "@veehz/gpu.js@npm:2.16.0"
+  dependencies:
+    acorn: "npm:8.14.0"
+    gl: "npm:8.1.6"
+    gl-wiretap: "npm:0.6.2"
+    gpu-mock.js: "github:weagle08/gpu-mock.js"
+    ordered-read-streams: "npm:^2.0.0"
+    webgpu: "npm:0.2.9"
+  checksum: 10c0/1f9aed520f34d871908f7014d1f345838a87d5931232ebc8ca95772b6cb6dc496e19d33199799e1946b1f2225f37dccf5bdc2e83727f27000c2a0c229c9b6833
+  languageName: node
+  linkType: hard
+
+"@volar/language-core@npm:2.4.23, @volar/language-core@npm:~2.4.11":
+  version: 2.4.23
+  resolution: "@volar/language-core@npm:2.4.23"
+  dependencies:
+    "@volar/source-map": "npm:2.4.23"
+  checksum: 10c0/1b8d60c7c0faa29ef5ec46dd2b673227592d0697753767e4df088f7c2d93843828116fe59472bb9d604ba653400be32a538e985730844b1af4f42a7075e62049
+  languageName: node
+  linkType: hard
+
+"@volar/source-map@npm:2.4.23":
+  version: 2.4.23
+  resolution: "@volar/source-map@npm:2.4.23"
+  checksum: 10c0/08af690093b811d0a37bdd8d306755b4e7f1535b67625c26f6fa6eb9ae081e24c55dabc8231ce8856aa1b731a5ac137b3f0449b34c093923c3545afdbe462c7a
+  languageName: node
+  linkType: hard
+
+"@volar/typescript@npm:^2.4.11":
+  version: 2.4.23
+  resolution: "@volar/typescript@npm:2.4.23"
+  dependencies:
+    "@volar/language-core": "npm:2.4.23"
+    path-browserify: "npm:^1.0.1"
+    vscode-uri: "npm:^3.0.8"
+  checksum: 10c0/dbb449b66e627a75f8f6df98b3210c32edff62747a12d1e6237a6dc2a75f26432833d4d3646d6fbd60ed21fa52d7e342437377973b80cf4bbeacee1980ffd0cb
+  languageName: node
+  linkType: hard
+
+"@vue/compiler-core@npm:3.5.22":
+  version: 3.5.22
+  resolution: "@vue/compiler-core@npm:3.5.22"
+  dependencies:
+    "@babel/parser": "npm:^7.28.4"
+    "@vue/shared": "npm:3.5.22"
+    entities: "npm:^4.5.0"
+    estree-walker: "npm:^2.0.2"
+    source-map-js: "npm:^1.2.1"
+  checksum: 10c0/7575fdef8d2b69aa9a7f55ba237abe0ab86a855dba1048dc32b32e2e5212a66410f922603b1191a8fbbf6e0caee7efab0cea705516304eeb1108d3819a10b092
+  languageName: node
+  linkType: hard
+
+"@vue/compiler-dom@npm:^3.5.0":
+  version: 3.5.22
+  resolution: "@vue/compiler-dom@npm:3.5.22"
+  dependencies:
+    "@vue/compiler-core": "npm:3.5.22"
+    "@vue/shared": "npm:3.5.22"
+  checksum: 10c0/f853e7533a6e2f51321b5ce258c6ed2bdac8a294e833a61e87b00d3fdd36cd39e1045c03027c31d85f518422062e50085f1358a37d104ccf0866bc174a5c7b9a
+  languageName: node
+  linkType: hard
+
+"@vue/compiler-vue2@npm:^2.7.16":
+  version: 2.7.16
+  resolution: "@vue/compiler-vue2@npm:2.7.16"
+  dependencies:
+    de-indent: "npm:^1.0.2"
+    he: "npm:^1.2.0"
+  checksum: 10c0/c76c3fad770b9a7da40b314116cc9da173da20e5fd68785c8ed8dd8a87d02f239545fa296e16552e040ec86b47bfb18283b39447b250c2e76e479bd6ae475bb3
+  languageName: node
+  linkType: hard
+
+"@vue/language-core@npm:2.2.0":
+  version: 2.2.0
+  resolution: "@vue/language-core@npm:2.2.0"
+  dependencies:
+    "@volar/language-core": "npm:~2.4.11"
+    "@vue/compiler-dom": "npm:^3.5.0"
+    "@vue/compiler-vue2": "npm:^2.7.16"
+    "@vue/shared": "npm:^3.5.0"
+    alien-signals: "npm:^0.4.9"
+    minimatch: "npm:^9.0.3"
+    muggle-string: "npm:^0.4.1"
+    path-browserify: "npm:^1.0.1"
+  peerDependencies:
+    typescript: "*"
+  peerDependenciesMeta:
+    typescript:
+      optional: true
+  checksum: 10c0/1c44cc4067266bbc825af358a867aed455963a08c160cd9df9a47571fd917a87d9de9bdea6149877e0c8309a6cf39f263e7cf2fbadeceba47a5a158f392151b2
+  languageName: node
+  linkType: hard
+
+"@vue/shared@npm:3.5.22, @vue/shared@npm:^3.5.0":
+  version: 3.5.22
+  resolution: "@vue/shared@npm:3.5.22"
+  checksum: 10c0/5866eab1dd6caa949f4ae2da2a7bac69612b35e316a298785279fb4de101bfe89a3572db56448aa35023b01d069b80a664be4fe22847ce5e5fbc1990e5970ec5
+  languageName: node
+  linkType: hard
+
+"@webgpu/types@npm:^0.1.54":
+  version: 0.1.65
+  resolution: "@webgpu/types@npm:0.1.65"
+  checksum: 10c0/cc9de41ae18432f292b5e41b1ef1198d200317fd3af424893a75b861fdcff272083e7cb2d51ba79b4deee4d1e93ecec8063d9e6f87d57c69217b48505971c858
+  languageName: node
+  linkType: hard
+
+"abbrev@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "abbrev@npm:2.0.0"
+  checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372
+  languageName: node
+  linkType: hard
+
+"abbrev@npm:^3.0.0":
+  version: 3.0.1
+  resolution: "abbrev@npm:3.0.1"
+  checksum: 10c0/21ba8f574ea57a3106d6d35623f2c4a9111d9ee3e9a5be47baed46ec2457d2eac46e07a5c4a60186f88cb98abbe3e24f2d4cca70bc2b12f1692523e2209a9ccf
+  languageName: node
+  linkType: hard
+
+"acorn-walk@npm:^8.1.1":
+  version: 8.3.4
+  resolution: "acorn-walk@npm:8.3.4"
+  dependencies:
+    acorn: "npm:^8.11.0"
+  checksum: 10c0/76537ac5fb2c37a64560feaf3342023dadc086c46da57da363e64c6148dc21b57d49ace26f949e225063acb6fb441eabffd89f7a3066de5ad37ab3e328927c62
+  languageName: node
+  linkType: hard
+
+"acorn@npm:8.14.0":
+  version: 8.14.0
+  resolution: "acorn@npm:8.14.0"
+  bin:
+    acorn: bin/acorn
+  checksum: 10c0/6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7
+  languageName: node
+  linkType: hard
+
+"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1":
+  version: 8.15.0
+  resolution: "acorn@npm:8.15.0"
+  bin:
+    acorn: bin/acorn
+  checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec
+  languageName: node
+  linkType: hard
+
+"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2":
+  version: 7.1.4
+  resolution: "agent-base@npm:7.1.4"
+  checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe
+  languageName: node
+  linkType: hard
+
+"aggregate-error@npm:^3.0.0":
+  version: 3.1.0
+  resolution: "aggregate-error@npm:3.1.0"
+  dependencies:
+    clean-stack: "npm:^2.0.0"
+    indent-string: "npm:^4.0.0"
+  checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039
+  languageName: node
+  linkType: hard
+
+"ajv-draft-04@npm:~1.0.0":
+  version: 1.0.0
+  resolution: "ajv-draft-04@npm:1.0.0"
+  peerDependencies:
+    ajv: ^8.5.0
+  peerDependenciesMeta:
+    ajv:
+      optional: true
+  checksum: 10c0/6044310bd38c17d77549fd326bd40ce1506fa10b0794540aa130180808bf94117fac8c9b448c621512bea60e4a947278f6a978e87f10d342950c15b33ddd9271
+  languageName: node
+  linkType: hard
+
+"ajv-formats@npm:~3.0.1":
+  version: 3.0.1
+  resolution: "ajv-formats@npm:3.0.1"
+  dependencies:
+    ajv: "npm:^8.0.0"
+  peerDependencies:
+    ajv: ^8.0.0
+  peerDependenciesMeta:
+    ajv:
+      optional: true
+  checksum: 10c0/168d6bca1ea9f163b41c8147bae537e67bd963357a5488a1eaf3abe8baa8eec806d4e45f15b10767e6020679315c7e1e5e6803088dfb84efa2b4e9353b83dd0a
+  languageName: node
+  linkType: hard
+
+"ajv@npm:^8.0.0":
+  version: 8.17.1
+  resolution: "ajv@npm:8.17.1"
+  dependencies:
+    fast-deep-equal: "npm:^3.1.3"
+    fast-uri: "npm:^3.0.1"
+    json-schema-traverse: "npm:^1.0.0"
+    require-from-string: "npm:^2.0.2"
+  checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35
+  languageName: node
+  linkType: hard
+
+"ajv@npm:~8.12.0":
+  version: 8.12.0
+  resolution: "ajv@npm:8.12.0"
+  dependencies:
+    fast-deep-equal: "npm:^3.1.1"
+    json-schema-traverse: "npm:^1.0.0"
+    require-from-string: "npm:^2.0.2"
+    uri-js: "npm:^4.2.2"
+  checksum: 10c0/ac4f72adf727ee425e049bc9d8b31d4a57e1c90da8d28bcd23d60781b12fcd6fc3d68db5df16994c57b78b94eed7988f5a6b482fd376dc5b084125e20a0a622e
+  languageName: node
+  linkType: hard
+
+"ajv@npm:~8.13.0":
+  version: 8.13.0
+  resolution: "ajv@npm:8.13.0"
+  dependencies:
+    fast-deep-equal: "npm:^3.1.3"
+    json-schema-traverse: "npm:^1.0.0"
+    require-from-string: "npm:^2.0.2"
+    uri-js: "npm:^4.4.1"
+  checksum: 10c0/14c6497b6f72843986d7344175a1aa0e2c35b1e7f7475e55bc582cddb765fca7e6bf950f465dc7846f817776d9541b706f4b5b3fbedd8dfdeb5fce6f22864264
+  languageName: node
+  linkType: hard
+
+"alien-signals@npm:^0.4.9":
+  version: 0.4.14
+  resolution: "alien-signals@npm:0.4.14"
+  checksum: 10c0/5abb3377bcaf6b3819e950084b3ebd022ad90210105afb450c89dc347e80e28da441bf34858a57ea122abe7603e552ddbad80dc597c8f02a0a5206c5fb9c20cb
+  languageName: node
+  linkType: hard
+
+"ansi-escapes@npm:^4.3.2":
+  version: 4.3.2
+  resolution: "ansi-escapes@npm:4.3.2"
+  dependencies:
+    type-fest: "npm:^0.21.3"
+  checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50
+  languageName: node
+  linkType: hard
+
+"ansi-regex@npm:^5.0.1":
+  version: 5.0.1
+  resolution: "ansi-regex@npm:5.0.1"
+  checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737
+  languageName: node
+  linkType: hard
+
+"ansi-regex@npm:^6.0.1":
+  version: 6.2.2
+  resolution: "ansi-regex@npm:6.2.2"
+  checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f
+  languageName: node
+  linkType: hard
+
+"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0":
+  version: 4.3.0
+  resolution: "ansi-styles@npm:4.3.0"
+  dependencies:
+    color-convert: "npm:^2.0.1"
+  checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041
+  languageName: node
+  linkType: hard
+
+"ansi-styles@npm:^5.2.0":
+  version: 5.2.0
+  resolution: "ansi-styles@npm:5.2.0"
+  checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df
+  languageName: node
+  linkType: hard
+
+"ansi-styles@npm:^6.1.0":
+  version: 6.2.3
+  resolution: "ansi-styles@npm:6.2.3"
+  checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868
+  languageName: node
+  linkType: hard
+
+"anymatch@npm:^3.1.3":
+  version: 3.1.3
+  resolution: "anymatch@npm:3.1.3"
+  dependencies:
+    normalize-path: "npm:^3.0.0"
+    picomatch: "npm:^2.0.4"
+  checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac
+  languageName: node
+  linkType: hard
+
+"arg@npm:^4.1.0":
+  version: 4.1.3
+  resolution: "arg@npm:4.1.3"
+  checksum: 10c0/070ff801a9d236a6caa647507bdcc7034530604844d64408149a26b9e87c2f97650055c0f049abd1efc024b334635c01f29e0b632b371ac3f26130f4cf65997a
+  languageName: node
+  linkType: hard
+
+"argparse@npm:^1.0.7, argparse@npm:~1.0.9":
+  version: 1.0.10
+  resolution: "argparse@npm:1.0.10"
+  dependencies:
+    sprintf-js: "npm:~1.0.2"
+  checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de
+  languageName: node
+  linkType: hard
+
+"b4a@npm:^1.6.4":
+  version: 1.7.3
+  resolution: "b4a@npm:1.7.3"
+  peerDependencies:
+    react-native-b4a: "*"
+  peerDependenciesMeta:
+    react-native-b4a:
+      optional: true
+  checksum: 10c0/ac16d186e00fa0d16de1f1a4af413953bc762d50d5a0e382aaa744a13886600313b7293403ad77fc83f6b1489c3fc2610494d1026754a51d1b7cdac2115a7598
+  languageName: node
+  linkType: hard
+
+"babel-jest@npm:30.2.0":
+  version: 30.2.0
+  resolution: "babel-jest@npm:30.2.0"
+  dependencies:
+    "@jest/transform": "npm:30.2.0"
+    "@types/babel__core": "npm:^7.20.5"
+    babel-plugin-istanbul: "npm:^7.0.1"
+    babel-preset-jest: "npm:30.2.0"
+    chalk: "npm:^4.1.2"
+    graceful-fs: "npm:^4.2.11"
+    slash: "npm:^3.0.0"
+  peerDependencies:
+    "@babel/core": ^7.11.0 || ^8.0.0-0
+  checksum: 10c0/673b8c87e5aec97c4f7372319c005d1e2b018e2f2e973378c7fb0a4f1e111f89872e6f1e49dd50aff6290cd881c865117ade67f2c78a356a8275ab21af47340d
+  languageName: node
+  linkType: hard
+
+"babel-plugin-istanbul@npm:^7.0.1":
+  version: 7.0.1
+  resolution: "babel-plugin-istanbul@npm:7.0.1"
+  dependencies:
+    "@babel/helper-plugin-utils": "npm:^7.0.0"
+    "@istanbuljs/load-nyc-config": "npm:^1.0.0"
+    "@istanbuljs/schema": "npm:^0.1.3"
+    istanbul-lib-instrument: "npm:^6.0.2"
+    test-exclude: "npm:^6.0.0"
+  checksum: 10c0/92975e3df12503b168695463b451468da0c20e117807221652eb8e33a26c160f3b9d4c5c4e65495657420e871c6a54e5e31f539e2e1da37ef2261d7ddd4b1dfd
+  languageName: node
+  linkType: hard
+
+"babel-plugin-jest-hoist@npm:30.2.0":
+  version: 30.2.0
+  resolution: "babel-plugin-jest-hoist@npm:30.2.0"
+  dependencies:
+    "@types/babel__core": "npm:^7.20.5"
+  checksum: 10c0/a2bd862aaa4875127c02e6020d3da67556a8f25981060252668dda65cf9a146202937ae80d2e8612c3c47afe19ac85577647b8cc216faa98567c685525a3f203
+  languageName: node
+  linkType: hard
+
+"babel-preset-current-node-syntax@npm:^1.2.0":
+  version: 1.2.0
+  resolution: "babel-preset-current-node-syntax@npm:1.2.0"
+  dependencies:
+    "@babel/plugin-syntax-async-generators": "npm:^7.8.4"
+    "@babel/plugin-syntax-bigint": "npm:^7.8.3"
+    "@babel/plugin-syntax-class-properties": "npm:^7.12.13"
+    "@babel/plugin-syntax-class-static-block": "npm:^7.14.5"
+    "@babel/plugin-syntax-import-attributes": "npm:^7.24.7"
+    "@babel/plugin-syntax-import-meta": "npm:^7.10.4"
+    "@babel/plugin-syntax-json-strings": "npm:^7.8.3"
+    "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4"
+    "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3"
+    "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4"
+    "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3"
+    "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3"
+    "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3"
+    "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5"
+    "@babel/plugin-syntax-top-level-await": "npm:^7.14.5"
+  peerDependencies:
+    "@babel/core": ^7.0.0 || ^8.0.0-0
+  checksum: 10c0/94a4f81cddf9b051045d08489e4fff7336292016301664c138cfa3d9ffe3fe2ba10a24ad6ae589fd95af1ac72ba0216e1653555c187e694d7b17be0c002bea10
+  languageName: node
+  linkType: hard
+
+"babel-preset-jest@npm:30.2.0":
+  version: 30.2.0
+  resolution: "babel-preset-jest@npm:30.2.0"
+  dependencies:
+    babel-plugin-jest-hoist: "npm:30.2.0"
+    babel-preset-current-node-syntax: "npm:^1.2.0"
+  peerDependencies:
+    "@babel/core": ^7.11.0 || ^8.0.0-beta.1
+  checksum: 10c0/fb2727bad450256146d63b5231b83a7638e73b96c9612296a20afd65fb8c76678ef9bc6fa56e81d1303109258aeb4fccea5b96568744059e47d3c6e3ebc98bd9
+  languageName: node
+  linkType: hard
+
+"balanced-match@npm:^1.0.0":
+  version: 1.0.2
+  resolution: "balanced-match@npm:1.0.2"
+  checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee
+  languageName: node
+  linkType: hard
+
+"bare-events@npm:^2.7.0":
+  version: 2.7.0
+  resolution: "bare-events@npm:2.7.0"
+  checksum: 10c0/0057d26ee21c60bb304cae689dad343e2b3be2a17af26ec26d995c440b6f2c544aab294276626ced1dac9d35b4c5653d0a076a759190c69e1923dbd3e60f5e99
+  languageName: node
+  linkType: hard
+
+"base64-js@npm:^1.3.1":
+  version: 1.5.1
+  resolution: "base64-js@npm:1.5.1"
+  checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf
+  languageName: node
+  linkType: hard
+
+"baseline-browser-mapping@npm:^2.8.9":
+  version: 2.8.11
+  resolution: "baseline-browser-mapping@npm:2.8.11"
+  bin:
+    baseline-browser-mapping: dist/cli.js
+  checksum: 10c0/9c345d41152782c20cc11ad0aff273d252d6063efdfc45a602abd8798b50d81deeb89aa3ab6eedd33dce2ad714d16de96783e248f850e95b6063e81cd2ea62ba
+  languageName: node
+  linkType: hard
+
+"bindings@npm:^1.5.0":
+  version: 1.5.0
+  resolution: "bindings@npm:1.5.0"
+  dependencies:
+    file-uri-to-path: "npm:1.0.0"
+  checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba
+  languageName: node
+  linkType: hard
+
+"bit-twiddle@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "bit-twiddle@npm:1.0.2"
+  checksum: 10c0/edd86fdaeb27fb5acb9dbde247a71e511ebb6c5406ed645038974203dce8c87ef0359f5d5b60212c2a54d0a52ab16a27c4cc3b1cd4e06256a33881ed77f03d7a
+  languageName: node
+  linkType: hard
+
+"bl@npm:^4.0.3":
+  version: 4.1.0
+  resolution: "bl@npm:4.1.0"
+  dependencies:
+    buffer: "npm:^5.5.0"
+    inherits: "npm:^2.0.4"
+    readable-stream: "npm:^3.4.0"
+  checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f
+  languageName: node
+  linkType: hard
+
+"brace-expansion@npm:^1.1.7":
+  version: 1.1.12
+  resolution: "brace-expansion@npm:1.1.12"
+  dependencies:
+    balanced-match: "npm:^1.0.0"
+    concat-map: "npm:0.0.1"
+  checksum: 10c0/975fecac2bb7758c062c20d0b3b6288c7cc895219ee25f0a64a9de662dbac981ff0b6e89909c3897c1f84fa353113a721923afdec5f8b2350255b097f12b1f73
+  languageName: node
+  linkType: hard
+
+"brace-expansion@npm:^2.0.1":
+  version: 2.0.2
+  resolution: "brace-expansion@npm:2.0.2"
+  dependencies:
+    balanced-match: "npm:^1.0.0"
+  checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf
+  languageName: node
+  linkType: hard
+
+"braces@npm:^3.0.3":
+  version: 3.0.3
+  resolution: "braces@npm:3.0.3"
+  dependencies:
+    fill-range: "npm:^7.1.1"
+  checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04
+  languageName: node
+  linkType: hard
+
+"browserslist@npm:^4.24.0":
+  version: 4.26.3
+  resolution: "browserslist@npm:4.26.3"
+  dependencies:
+    baseline-browser-mapping: "npm:^2.8.9"
+    caniuse-lite: "npm:^1.0.30001746"
+    electron-to-chromium: "npm:^1.5.227"
+    node-releases: "npm:^2.0.21"
+    update-browserslist-db: "npm:^1.1.3"
+  bin:
+    browserslist: cli.js
+  checksum: 10c0/3899ee3b7fd205ece4ffe4392697c3f2b120b68f3741ef1789212b4971771aee3f66cf37c5c3accf86ce59c0605b5980c0f132711abbcc9e62c132e6e0ee45f3
+  languageName: node
+  linkType: hard
+
+"bs-logger@npm:^0.2.6":
+  version: 0.2.6
+  resolution: "bs-logger@npm:0.2.6"
+  dependencies:
+    fast-json-stable-stringify: "npm:2.x"
+  checksum: 10c0/80e89aaaed4b68e3374ce936f2eb097456a0dddbf11f75238dbd53140b1e39259f0d248a5089ed456f1158984f22191c3658d54a713982f676709fbe1a6fa5a0
+  languageName: node
+  linkType: hard
+
+"bser@npm:2.1.1":
+  version: 2.1.1
+  resolution: "bser@npm:2.1.1"
+  dependencies:
+    node-int64: "npm:^0.4.0"
+  checksum: 10c0/24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227
+  languageName: node
+  linkType: hard
+
+"buffer-from@npm:^1.0.0":
+  version: 1.1.2
+  resolution: "buffer-from@npm:1.1.2"
+  checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34
+  languageName: node
+  linkType: hard
+
+"buffer@npm:^5.5.0":
+  version: 5.7.1
+  resolution: "buffer@npm:5.7.1"
+  dependencies:
+    base64-js: "npm:^1.3.1"
+    ieee754: "npm:^1.1.13"
+  checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e
+  languageName: node
+  linkType: hard
+
+"cacache@npm:^18.0.0":
+  version: 18.0.4
+  resolution: "cacache@npm:18.0.4"
+  dependencies:
+    "@npmcli/fs": "npm:^3.1.0"
+    fs-minipass: "npm:^3.0.0"
+    glob: "npm:^10.2.2"
+    lru-cache: "npm:^10.0.1"
+    minipass: "npm:^7.0.3"
+    minipass-collect: "npm:^2.0.1"
+    minipass-flush: "npm:^1.0.5"
+    minipass-pipeline: "npm:^1.2.4"
+    p-map: "npm:^4.0.0"
+    ssri: "npm:^10.0.0"
+    tar: "npm:^6.1.11"
+    unique-filename: "npm:^3.0.0"
+  checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f
+  languageName: node
+  linkType: hard
+
+"cacache@npm:^19.0.1":
+  version: 19.0.1
+  resolution: "cacache@npm:19.0.1"
+  dependencies:
+    "@npmcli/fs": "npm:^4.0.0"
+    fs-minipass: "npm:^3.0.0"
+    glob: "npm:^10.2.2"
+    lru-cache: "npm:^10.0.1"
+    minipass: "npm:^7.0.3"
+    minipass-collect: "npm:^2.0.1"
+    minipass-flush: "npm:^1.0.5"
+    minipass-pipeline: "npm:^1.2.4"
+    p-map: "npm:^7.0.2"
+    ssri: "npm:^12.0.0"
+    tar: "npm:^7.4.3"
+    unique-filename: "npm:^4.0.0"
+  checksum: 10c0/01f2134e1bd7d3ab68be851df96c8d63b492b1853b67f2eecb2c37bb682d37cb70bb858a16f2f0554d3c0071be6dfe21456a1ff6fa4b7eed996570d6a25ffe9c
+  languageName: node
+  linkType: hard
+
+"callsites@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "callsites@npm:3.1.0"
+  checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301
+  languageName: node
+  linkType: hard
+
+"camelcase@npm:^5.3.1":
+  version: 5.3.1
+  resolution: "camelcase@npm:5.3.1"
+  checksum: 10c0/92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23
+  languageName: node
+  linkType: hard
+
+"camelcase@npm:^6.3.0":
+  version: 6.3.0
+  resolution: "camelcase@npm:6.3.0"
+  checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710
+  languageName: node
+  linkType: hard
+
+"caniuse-lite@npm:^1.0.30001746":
+  version: 1.0.30001747
+  resolution: "caniuse-lite@npm:1.0.30001747"
+  checksum: 10c0/cef0c7fff34d4c0ac3edc33660f07785301c98858bb4a6b8702b7b09ca2b0fd5457a7772af7b9fc3591fdd13862f649e57eed824f4cb6cf4aedf563e58fc7d0c
+  languageName: node
+  linkType: hard
+
+"chalk@npm:^4.1.2":
+  version: 4.1.2
+  resolution: "chalk@npm:4.1.2"
+  dependencies:
+    ansi-styles: "npm:^4.1.0"
+    supports-color: "npm:^7.1.0"
+  checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880
+  languageName: node
+  linkType: hard
+
+"char-regex@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "char-regex@npm:1.0.2"
+  checksum: 10c0/57a09a86371331e0be35d9083ba429e86c4f4648ecbe27455dbfb343037c16ee6fdc7f6b61f433a57cc5ded5561d71c56a150e018f40c2ffb7bc93a26dae341e
+  languageName: node
+  linkType: hard
+
+"chownr@npm:^1.1.1":
+  version: 1.1.4
+  resolution: "chownr@npm:1.1.4"
+  checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db
+  languageName: node
+  linkType: hard
+
+"chownr@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "chownr@npm:2.0.0"
+  checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6
+  languageName: node
+  linkType: hard
+
+"chownr@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "chownr@npm:3.0.0"
+  checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10
+  languageName: node
+  linkType: hard
+
+"ci-info@npm:^4.2.0":
+  version: 4.3.0
+  resolution: "ci-info@npm:4.3.0"
+  checksum: 10c0/60d3dfe95d75c01454ec1cfd5108617dd598a28a2a3e148bd7e1523c1c208b5f5a3007cafcbe293e6fd0a5a310cc32217c5dc54743eeabc0a2bec80072fc055c
+  languageName: node
+  linkType: hard
+
+"cjs-module-lexer@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "cjs-module-lexer@npm:2.1.0"
+  checksum: 10c0/91cf28686dc3948e4a06dfa03a2fccb14b7a97471ffe7ae0124f62060ddf2de28e8e997f60007babe6e122b1b06a47c01a1b72cc015f185824d9cac3ccfa5533
+  languageName: node
+  linkType: hard
+
+"clean-stack@npm:^2.0.0":
+  version: 2.2.0
+  resolution: "clean-stack@npm:2.2.0"
+  checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1
+  languageName: node
+  linkType: hard
+
+"cliui@npm:^8.0.1":
+  version: 8.0.1
+  resolution: "cliui@npm:8.0.1"
+  dependencies:
+    string-width: "npm:^4.2.0"
+    strip-ansi: "npm:^6.0.1"
+    wrap-ansi: "npm:^7.0.0"
+  checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5
+  languageName: node
+  linkType: hard
+
+"co@npm:^4.6.0":
+  version: 4.6.0
+  resolution: "co@npm:4.6.0"
+  checksum: 10c0/c0e85ea0ca8bf0a50cbdca82efc5af0301240ca88ebe3644a6ffb8ffe911f34d40f8fbcf8f1d52c5ddd66706abd4d3bfcd64259f1e8e2371d4f47573b0dc8c28
+  languageName: node
+  linkType: hard
+
+"collect-v8-coverage@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "collect-v8-coverage@npm:1.0.2"
+  checksum: 10c0/ed7008e2e8b6852c5483b444a3ae6e976e088d4335a85aa0a9db2861c5f1d31bd2d7ff97a60469b3388deeba661a619753afbe201279fb159b4b9548ab8269a1
+  languageName: node
+  linkType: hard
+
+"color-convert@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "color-convert@npm:2.0.1"
+  dependencies:
+    color-name: "npm:~1.1.4"
+  checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7
+  languageName: node
+  linkType: hard
+
+"color-name@npm:~1.1.4":
+  version: 1.1.4
+  resolution: "color-name@npm:1.1.4"
+  checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95
+  languageName: node
+  linkType: hard
+
+"compare-versions@npm:^6.1.1":
+  version: 6.1.1
+  resolution: "compare-versions@npm:6.1.1"
+  checksum: 10c0/415205c7627f9e4f358f571266422980c9fe2d99086be0c9a48008ef7c771f32b0fbe8e97a441ffedc3910872f917a0675fe0fe3c3b6d331cda6d8690be06338
+  languageName: node
+  linkType: hard
+
+"concat-map@npm:0.0.1":
+  version: 0.0.1
+  resolution: "concat-map@npm:0.0.1"
+  checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f
+  languageName: node
+  linkType: hard
+
+"confbox@npm:^0.1.8":
+  version: 0.1.8
+  resolution: "confbox@npm:0.1.8"
+  checksum: 10c0/fc2c68d97cb54d885b10b63e45bd8da83a8a71459d3ecf1825143dd4c7f9f1b696b3283e07d9d12a144c1301c2ebc7842380bdf0014e55acc4ae1c9550102418
+  languageName: node
+  linkType: hard
+
+"confbox@npm:^0.2.2":
+  version: 0.2.2
+  resolution: "confbox@npm:0.2.2"
+  checksum: 10c0/7c246588d533d31e8cdf66cb4701dff6de60f9be77ab54c0d0338e7988750ac56863cc0aca1b3f2046f45ff223a765d3e5d4977a7674485afcd37b6edf3fd129
+  languageName: node
+  linkType: hard
+
+"convert-source-map@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "convert-source-map@npm:2.0.0"
+  checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b
+  languageName: node
+  linkType: hard
+
+"core-util-is@npm:~1.0.0":
+  version: 1.0.3
+  resolution: "core-util-is@npm:1.0.3"
+  checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9
+  languageName: node
+  linkType: hard
+
+"create-require@npm:^1.1.0":
+  version: 1.1.1
+  resolution: "create-require@npm:1.1.1"
+  checksum: 10c0/157cbc59b2430ae9a90034a5f3a1b398b6738bf510f713edc4d4e45e169bc514d3d99dd34d8d01ca7ae7830b5b8b537e46ae8f3c8f932371b0875c0151d7ec91
+  languageName: node
+  linkType: hard
+
+"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
+  version: 7.0.6
+  resolution: "cross-spawn@npm:7.0.6"
+  dependencies:
+    path-key: "npm:^3.1.0"
+    shebang-command: "npm:^2.0.0"
+    which: "npm:^2.0.1"
+  checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1
+  languageName: node
+  linkType: hard
+
+"de-indent@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "de-indent@npm:1.0.2"
+  checksum: 10c0/7058ce58abd6dfc123dd204e36be3797abd419b59482a634605420f47ae97639d0c183ec5d1b904f308a01033f473673897afc2bd59bc620ebf1658763ef4291
+  languageName: node
+  linkType: hard
+
+"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:^4.4.0":
+  version: 4.4.3
+  resolution: "debug@npm:4.4.3"
+  dependencies:
+    ms: "npm:^2.1.3"
+  peerDependenciesMeta:
+    supports-color:
+      optional: true
+  checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6
+  languageName: node
+  linkType: hard
+
+"decompress-response@npm:^6.0.0":
+  version: 6.0.0
+  resolution: "decompress-response@npm:6.0.0"
+  dependencies:
+    mimic-response: "npm:^3.1.0"
+  checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e
+  languageName: node
+  linkType: hard
+
+"dedent@npm:^1.6.0":
+  version: 1.7.0
+  resolution: "dedent@npm:1.7.0"
+  peerDependencies:
+    babel-plugin-macros: ^3.1.0
+  peerDependenciesMeta:
+    babel-plugin-macros:
+      optional: true
+  checksum: 10c0/c5e8a8beb5072bd5e520cb64b27a82d7ec3c2a63ee5ce47dbc2a05d5b7700cefd77a992a752cd0a8b1d979c1db06b14fb9486e805f3ad6088eda6e07cd9bf2d5
+  languageName: node
+  linkType: hard
+
+"deep-extend@npm:^0.6.0":
+  version: 0.6.0
+  resolution: "deep-extend@npm:0.6.0"
+  checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566
+  languageName: node
+  linkType: hard
+
+"deepmerge@npm:^4.3.1":
+  version: 4.3.1
+  resolution: "deepmerge@npm:4.3.1"
+  checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044
+  languageName: node
+  linkType: hard
+
+"detect-libc@npm:^2.0.0":
+  version: 2.1.1
+  resolution: "detect-libc@npm:2.1.1"
+  checksum: 10c0/97053299c1f68c7c4adf7b78c8d506e1d5f3a3fbc775920aaa0ecf7f8fcc6dfa46338a6ca82fe4500b4a51937def314584265a4ec9d565577485c4496aa7d64e
+  languageName: node
+  linkType: hard
+
+"detect-newline@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "detect-newline@npm:3.1.0"
+  checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d
+  languageName: node
+  linkType: hard
+
+"diff@npm:^4.0.1":
+  version: 4.0.2
+  resolution: "diff@npm:4.0.2"
+  checksum: 10c0/81b91f9d39c4eaca068eb0c1eb0e4afbdc5bb2941d197f513dd596b820b956fef43485876226d65d497bebc15666aa2aa82c679e84f65d5f2bfbf14ee46e32c1
+  languageName: node
+  linkType: hard
+
+"eastasianwidth@npm:^0.2.0":
+  version: 0.2.0
+  resolution: "eastasianwidth@npm:0.2.0"
+  checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39
+  languageName: node
+  linkType: hard
+
+"electron-to-chromium@npm:^1.5.227":
+  version: 1.5.230
+  resolution: "electron-to-chromium@npm:1.5.230"
+  checksum: 10c0/b8bf382868b2780fa0c7ba3bce0644e94ec21af8f9b199ee094273904a575b46c8705fa4c10a22a0ed90e42dbbf72efbc3089bbecf8324a9db099c8c6c1c1101
+  languageName: node
+  linkType: hard
+
+"emittery@npm:^0.13.1":
+  version: 0.13.1
+  resolution: "emittery@npm:0.13.1"
+  checksum: 10c0/1573d0ae29ab34661b6c63251ff8f5facd24ccf6a823f19417ae8ba8c88ea450325788c67f16c99edec8de4b52ce93a10fe441ece389fd156e88ee7dab9bfa35
+  languageName: node
+  linkType: hard
+
+"emoji-regex@npm:^8.0.0":
+  version: 8.0.0
+  resolution: "emoji-regex@npm:8.0.0"
+  checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010
+  languageName: node
+  linkType: hard
+
+"emoji-regex@npm:^9.2.2":
+  version: 9.2.2
+  resolution: "emoji-regex@npm:9.2.2"
+  checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639
+  languageName: node
+  linkType: hard
+
+"encoding@npm:^0.1.13":
+  version: 0.1.13
+  resolution: "encoding@npm:0.1.13"
+  dependencies:
+    iconv-lite: "npm:^0.6.2"
+  checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039
+  languageName: node
+  linkType: hard
+
+"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1":
+  version: 1.4.5
+  resolution: "end-of-stream@npm:1.4.5"
+  dependencies:
+    once: "npm:^1.4.0"
+  checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8
+  languageName: node
+  linkType: hard
+
+"entities@npm:^4.5.0":
+  version: 4.5.0
+  resolution: "entities@npm:4.5.0"
+  checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250
+  languageName: node
+  linkType: hard
+
+"env-paths@npm:^2.2.0":
+  version: 2.2.1
+  resolution: "env-paths@npm:2.2.1"
+  checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4
+  languageName: node
+  linkType: hard
+
+"err-code@npm:^2.0.2":
+  version: 2.0.3
+  resolution: "err-code@npm:2.0.3"
+  checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66
+  languageName: node
+  linkType: hard
+
+"error-ex@npm:^1.3.1":
+  version: 1.3.4
+  resolution: "error-ex@npm:1.3.4"
+  dependencies:
+    is-arrayish: "npm:^0.2.1"
+  checksum: 10c0/b9e34ff4778b8f3b31a8377e1c654456f4c41aeaa3d10a1138c3b7635d8b7b2e03eb2475d46d8ae055c1f180a1063e100bffabf64ea7e7388b37735df5328664
+  languageName: node
+  linkType: hard
+
+"esbuild@npm:^0.25.0":
+  version: 0.25.10
+  resolution: "esbuild@npm:0.25.10"
+  dependencies:
+    "@esbuild/aix-ppc64": "npm:0.25.10"
+    "@esbuild/android-arm": "npm:0.25.10"
+    "@esbuild/android-arm64": "npm:0.25.10"
+    "@esbuild/android-x64": "npm:0.25.10"
+    "@esbuild/darwin-arm64": "npm:0.25.10"
+    "@esbuild/darwin-x64": "npm:0.25.10"
+    "@esbuild/freebsd-arm64": "npm:0.25.10"
+    "@esbuild/freebsd-x64": "npm:0.25.10"
+    "@esbuild/linux-arm": "npm:0.25.10"
+    "@esbuild/linux-arm64": "npm:0.25.10"
+    "@esbuild/linux-ia32": "npm:0.25.10"
+    "@esbuild/linux-loong64": "npm:0.25.10"
+    "@esbuild/linux-mips64el": "npm:0.25.10"
+    "@esbuild/linux-ppc64": "npm:0.25.10"
+    "@esbuild/linux-riscv64": "npm:0.25.10"
+    "@esbuild/linux-s390x": "npm:0.25.10"
+    "@esbuild/linux-x64": "npm:0.25.10"
+    "@esbuild/netbsd-arm64": "npm:0.25.10"
+    "@esbuild/netbsd-x64": "npm:0.25.10"
+    "@esbuild/openbsd-arm64": "npm:0.25.10"
+    "@esbuild/openbsd-x64": "npm:0.25.10"
+    "@esbuild/openharmony-arm64": "npm:0.25.10"
+    "@esbuild/sunos-x64": "npm:0.25.10"
+    "@esbuild/win32-arm64": "npm:0.25.10"
+    "@esbuild/win32-ia32": "npm:0.25.10"
+    "@esbuild/win32-x64": "npm:0.25.10"
+  dependenciesMeta:
+    "@esbuild/aix-ppc64":
+      optional: true
+    "@esbuild/android-arm":
+      optional: true
+    "@esbuild/android-arm64":
+      optional: true
+    "@esbuild/android-x64":
+      optional: true
+    "@esbuild/darwin-arm64":
+      optional: true
+    "@esbuild/darwin-x64":
+      optional: true
+    "@esbuild/freebsd-arm64":
+      optional: true
+    "@esbuild/freebsd-x64":
+      optional: true
+    "@esbuild/linux-arm":
+      optional: true
+    "@esbuild/linux-arm64":
+      optional: true
+    "@esbuild/linux-ia32":
+      optional: true
+    "@esbuild/linux-loong64":
+      optional: true
+    "@esbuild/linux-mips64el":
+      optional: true
+    "@esbuild/linux-ppc64":
+      optional: true
+    "@esbuild/linux-riscv64":
+      optional: true
+    "@esbuild/linux-s390x":
+      optional: true
+    "@esbuild/linux-x64":
+      optional: true
+    "@esbuild/netbsd-arm64":
+      optional: true
+    "@esbuild/netbsd-x64":
+      optional: true
+    "@esbuild/openbsd-arm64":
+      optional: true
+    "@esbuild/openbsd-x64":
+      optional: true
+    "@esbuild/openharmony-arm64":
+      optional: true
+    "@esbuild/sunos-x64":
+      optional: true
+    "@esbuild/win32-arm64":
+      optional: true
+    "@esbuild/win32-ia32":
+      optional: true
+    "@esbuild/win32-x64":
+      optional: true
+  bin:
+    esbuild: bin/esbuild
+  checksum: 10c0/8ee5fdd43ed0d4092ce7f41577c63147f54049d5617763f0549c638bbe939e8adaa8f1a2728adb63417eb11df51956b7b0d8eb88ee08c27ad1d42960256158fa
+  languageName: node
+  linkType: hard
+
+"escalade@npm:^3.1.1, escalade@npm:^3.2.0":
+  version: 3.2.0
+  resolution: "escalade@npm:3.2.0"
+  checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65
+  languageName: node
+  linkType: hard
+
+"escape-string-regexp@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "escape-string-regexp@npm:2.0.0"
+  checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507
+  languageName: node
+  linkType: hard
+
+"esprima@npm:^4.0.0":
+  version: 4.0.1
+  resolution: "esprima@npm:4.0.1"
+  bin:
+    esparse: ./bin/esparse.js
+    esvalidate: ./bin/esvalidate.js
+  checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3
+  languageName: node
+  linkType: hard
+
+"estree-walker@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "estree-walker@npm:2.0.2"
+  checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af
+  languageName: node
+  linkType: hard
+
+"events-universal@npm:^1.0.0":
+  version: 1.0.1
+  resolution: "events-universal@npm:1.0.1"
+  dependencies:
+    bare-events: "npm:^2.7.0"
+  checksum: 10c0/a1d9a5e9f95843650f8ec240dd1221454c110189a9813f32cdf7185759b43f1f964367ac7dca4ebc69150b59043f2d77c7e122b0d03abf7c25477ea5494785a5
+  languageName: node
+  linkType: hard
+
+"execa@npm:^5.1.1":
+  version: 5.1.1
+  resolution: "execa@npm:5.1.1"
+  dependencies:
+    cross-spawn: "npm:^7.0.3"
+    get-stream: "npm:^6.0.0"
+    human-signals: "npm:^2.1.0"
+    is-stream: "npm:^2.0.0"
+    merge-stream: "npm:^2.0.0"
+    npm-run-path: "npm:^4.0.1"
+    onetime: "npm:^5.1.2"
+    signal-exit: "npm:^3.0.3"
+    strip-final-newline: "npm:^2.0.0"
+  checksum: 10c0/c8e615235e8de4c5addf2fa4c3da3e3aa59ce975a3e83533b4f6a71750fb816a2e79610dc5f1799b6e28976c9ae86747a36a606655bf8cb414a74d8d507b304f
+  languageName: node
+  linkType: hard
+
+"exit-x@npm:^0.2.2":
+  version: 0.2.2
+  resolution: "exit-x@npm:0.2.2"
+  checksum: 10c0/212a7a095ca5540e9581f1ef2d1d6a40df7a6027c8cc96e78ce1d16b86d1a88326d4a0eff8dff2b5ec1e68bb0c1edd5d0dfdde87df1869bf7514d4bc6a5cbd72
+  languageName: node
+  linkType: hard
+
+"expand-template@npm:^2.0.3":
+  version: 2.0.3
+  resolution: "expand-template@npm:2.0.3"
+  checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51
+  languageName: node
+  linkType: hard
+
+"expect@npm:30.2.0, expect@npm:^30.0.0":
+  version: 30.2.0
+  resolution: "expect@npm:30.2.0"
+  dependencies:
+    "@jest/expect-utils": "npm:30.2.0"
+    "@jest/get-type": "npm:30.1.0"
+    jest-matcher-utils: "npm:30.2.0"
+    jest-message-util: "npm:30.2.0"
+    jest-mock: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+  checksum: 10c0/fe440b3a036e2de1a3ede84bc6a699925328056e74324fbd2fdd9ce7b7358d03e515ac8db559c33828bcb0b7887b493dbaaece565e67d88748685850da5d9209
+  languageName: node
+  linkType: hard
+
+"exponential-backoff@npm:^3.1.1":
+  version: 3.1.2
+  resolution: "exponential-backoff@npm:3.1.2"
+  checksum: 10c0/d9d3e1eafa21b78464297df91f1776f7fbaa3d5e3f7f0995648ca5b89c069d17055033817348d9f4a43d1c20b0eab84f75af6991751e839df53e4dfd6f22e844
+  languageName: node
+  linkType: hard
+
+"exsolve@npm:^1.0.7":
+  version: 1.0.7
+  resolution: "exsolve@npm:1.0.7"
+  checksum: 10c0/4479369d0bd84bb7e0b4f5d9bc18d26a89b6dbbbccd73f9d383d14892ef78ddbe159e01781055342f83dc00ebe90044036daf17ddf55cc21e2cac6609aa15631
+  languageName: node
+  linkType: hard
+
+"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
+  version: 3.1.3
+  resolution: "fast-deep-equal@npm:3.1.3"
+  checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0
+  languageName: node
+  linkType: hard
+
+"fast-fifo@npm:^1.3.2":
+  version: 1.3.2
+  resolution: "fast-fifo@npm:1.3.2"
+  checksum: 10c0/d53f6f786875e8b0529f784b59b4b05d4b5c31c651710496440006a398389a579c8dbcd2081311478b5bf77f4b0b21de69109c5a4eabea9d8e8783d1eb864e4c
+  languageName: node
+  linkType: hard
+
+"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "fast-json-stable-stringify@npm:2.1.0"
+  checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b
+  languageName: node
+  linkType: hard
+
+"fast-uri@npm:^3.0.1":
+  version: 3.1.0
+  resolution: "fast-uri@npm:3.1.0"
+  checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7
+  languageName: node
+  linkType: hard
+
+"fb-watchman@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "fb-watchman@npm:2.0.2"
+  dependencies:
+    bser: "npm:2.1.1"
+  checksum: 10c0/feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581
+  languageName: node
+  linkType: hard
+
+"fdir@npm:^6.5.0":
+  version: 6.5.0
+  resolution: "fdir@npm:6.5.0"
+  peerDependencies:
+    picomatch: ^3 || ^4
+  peerDependenciesMeta:
+    picomatch:
+      optional: true
+  checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f
+  languageName: node
+  linkType: hard
+
+"file-uri-to-path@npm:1.0.0":
+  version: 1.0.0
+  resolution: "file-uri-to-path@npm:1.0.0"
+  checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519
+  languageName: node
+  linkType: hard
+
+"fill-range@npm:^7.1.1":
+  version: 7.1.1
+  resolution: "fill-range@npm:7.1.1"
+  dependencies:
+    to-regex-range: "npm:^5.0.1"
+  checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018
+  languageName: node
+  linkType: hard
+
+"find-up@npm:^4.0.0, find-up@npm:^4.1.0":
+  version: 4.1.0
+  resolution: "find-up@npm:4.1.0"
+  dependencies:
+    locate-path: "npm:^5.0.0"
+    path-exists: "npm:^4.0.0"
+  checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1
+  languageName: node
+  linkType: hard
+
+"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1":
+  version: 3.3.1
+  resolution: "foreground-child@npm:3.3.1"
+  dependencies:
+    cross-spawn: "npm:^7.0.6"
+    signal-exit: "npm:^4.0.1"
+  checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3
+  languageName: node
+  linkType: hard
+
+"fs-constants@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "fs-constants@npm:1.0.0"
+  checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8
+  languageName: node
+  linkType: hard
+
+"fs-extra@npm:~11.3.0":
+  version: 11.3.2
+  resolution: "fs-extra@npm:11.3.2"
+  dependencies:
+    graceful-fs: "npm:^4.2.0"
+    jsonfile: "npm:^6.0.1"
+    universalify: "npm:^2.0.0"
+  checksum: 10c0/f5d629e1bb646d5dedb4d8b24c5aad3deb8cc1d5438979d6f237146cd10e113b49a949ae1b54212c2fbc98e2d0995f38009a9a1d0520f0287943335e65fe919b
+  languageName: node
+  linkType: hard
+
+"fs-minipass@npm:^2.0.0":
+  version: 2.1.0
+  resolution: "fs-minipass@npm:2.1.0"
+  dependencies:
+    minipass: "npm:^3.0.0"
+  checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004
+  languageName: node
+  linkType: hard
+
+"fs-minipass@npm:^3.0.0":
+  version: 3.0.3
+  resolution: "fs-minipass@npm:3.0.3"
+  dependencies:
+    minipass: "npm:^7.0.3"
+  checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94
+  languageName: node
+  linkType: hard
+
+"fs.realpath@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "fs.realpath@npm:1.0.0"
+  checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948
+  languageName: node
+  linkType: hard
+
+"fsevents@npm:^2.3.3, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
+  version: 2.3.3
+  resolution: "fsevents@npm:2.3.3"
+  dependencies:
+    node-gyp: "npm:latest"
+  checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60
+  conditions: os=darwin
+  languageName: node
+  linkType: hard
+
+"fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin":
+  version: 2.3.3
+  resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
+  dependencies:
+    node-gyp: "npm:latest"
+  conditions: os=darwin
+  languageName: node
+  linkType: hard
+
+"function-bind@npm:^1.1.2":
+  version: 1.1.2
+  resolution: "function-bind@npm:1.1.2"
+  checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5
+  languageName: node
+  linkType: hard
+
+"gensync@npm:^1.0.0-beta.2":
+  version: 1.0.0-beta.2
+  resolution: "gensync@npm:1.0.0-beta.2"
+  checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8
+  languageName: node
+  linkType: hard
+
+"get-caller-file@npm:^2.0.5":
+  version: 2.0.5
+  resolution: "get-caller-file@npm:2.0.5"
+  checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde
+  languageName: node
+  linkType: hard
+
+"get-package-type@npm:^0.1.0":
+  version: 0.1.0
+  resolution: "get-package-type@npm:0.1.0"
+  checksum: 10c0/e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be
+  languageName: node
+  linkType: hard
+
+"get-stream@npm:^6.0.0":
+  version: 6.0.1
+  resolution: "get-stream@npm:6.0.1"
+  checksum: 10c0/49825d57d3fd6964228e6200a58169464b8e8970489b3acdc24906c782fb7f01f9f56f8e6653c4a50713771d6658f7cfe051e5eb8c12e334138c9c918b296341
+  languageName: node
+  linkType: hard
+
+"github-from-package@npm:0.0.0":
+  version: 0.0.0
+  resolution: "github-from-package@npm:0.0.0"
+  checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12
+  languageName: node
+  linkType: hard
+
+"gl-wiretap@npm:0.6.2":
+  version: 0.6.2
+  resolution: "gl-wiretap@npm:0.6.2"
+  checksum: 10c0/bd705d28d8ea9c71cb2dfcb60e344cf343c4c76dd8267df04f6f9ce527c47a633eacd9b0c0b10daa746a4e526c27578a02a8bcdbfd15b3e7254bb14194283424
+  languageName: node
+  linkType: hard
+
+"gl@npm:8.1.6":
+  version: 8.1.6
+  resolution: "gl@npm:8.1.6"
+  dependencies:
+    bindings: "npm:^1.5.0"
+    bit-twiddle: "npm:^1.0.2"
+    glsl-tokenizer: "npm:^2.1.5"
+    nan: "npm:^2.22.0"
+    node-abi: "npm:^3.71.0"
+    node-gyp: "npm:^10.2.0"
+    prebuild-install: "npm:^7.1.2"
+  checksum: 10c0/4df83359eaf26bd55e319673733806ff7e338317a88846ce3b360e726cf0310b71a40bffa29f47c0ee03a40cb8001aab7a1b74b416e7c5d0c3f35107baf77377
+  languageName: node
+  linkType: hard
+
+"glob@npm:^10.2.2, glob@npm:^10.3.10":
+  version: 10.4.5
+  resolution: "glob@npm:10.4.5"
+  dependencies:
+    foreground-child: "npm:^3.1.0"
+    jackspeak: "npm:^3.1.2"
+    minimatch: "npm:^9.0.4"
+    minipass: "npm:^7.1.2"
+    package-json-from-dist: "npm:^1.0.0"
+    path-scurry: "npm:^1.11.1"
+  bin:
+    glob: dist/esm/bin.mjs
+  checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e
+  languageName: node
+  linkType: hard
+
+"glob@npm:^11.0.0":
+  version: 11.0.3
+  resolution: "glob@npm:11.0.3"
+  dependencies:
+    foreground-child: "npm:^3.3.1"
+    jackspeak: "npm:^4.1.1"
+    minimatch: "npm:^10.0.3"
+    minipass: "npm:^7.1.2"
+    package-json-from-dist: "npm:^1.0.0"
+    path-scurry: "npm:^2.0.0"
+  bin:
+    glob: dist/esm/bin.mjs
+  checksum: 10c0/7d24457549ec2903920dfa3d8e76850e7c02aa709122f0164b240c712f5455c0b457e6f2a1eee39344c6148e39895be8094ae8cfef7ccc3296ed30bce250c661
+  languageName: node
+  linkType: hard
+
+"glob@npm:^7.1.4":
+  version: 7.2.3
+  resolution: "glob@npm:7.2.3"
+  dependencies:
+    fs.realpath: "npm:^1.0.0"
+    inflight: "npm:^1.0.4"
+    inherits: "npm:2"
+    minimatch: "npm:^3.1.1"
+    once: "npm:^1.3.0"
+    path-is-absolute: "npm:^1.0.0"
+  checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe
+  languageName: node
+  linkType: hard
+
+"glsl-tokenizer@npm:^2.1.5":
+  version: 2.1.5
+  resolution: "glsl-tokenizer@npm:2.1.5"
+  dependencies:
+    through2: "npm:^0.6.3"
+  checksum: 10c0/5bcc4491afb0b09032702af83f0afa8acadfa0f5c94a7a0d7c3498396cc35722e1915c976c8efef80a1a9ef0976ecb8ce4e044a34b16d7d537ae4c80f346ad19
+  languageName: node
+  linkType: hard
+
+"gpu-mock.js@github:weagle08/gpu-mock.js":
+  version: 1.3.1
+  resolution: "gpu-mock.js@https://github.com/weagle08/gpu-mock.js.git#commit=7f3d7a75d29e34c5098d6102fce006c53b5df50d"
+  checksum: 10c0/dcf15092047ce622701b10ebe3088afcb3be9d59142d82f8e79ec3e82a0b797a8fe24b48515ac615106e3b7d3d5b048afcac62cf9a9a896c5919d47bfedf17fa
+  languageName: node
+  linkType: hard
+
+"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6":
+  version: 4.2.11
+  resolution: "graceful-fs@npm:4.2.11"
+  checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
+  languageName: node
+  linkType: hard
+
+"handlebars@npm:^4.7.8":
+  version: 4.7.8
+  resolution: "handlebars@npm:4.7.8"
+  dependencies:
+    minimist: "npm:^1.2.5"
+    neo-async: "npm:^2.6.2"
+    source-map: "npm:^0.6.1"
+    uglify-js: "npm:^3.1.4"
+    wordwrap: "npm:^1.0.0"
+  dependenciesMeta:
+    uglify-js:
+      optional: true
+  bin:
+    handlebars: bin/handlebars
+  checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d
+  languageName: node
+  linkType: hard
+
+"has-flag@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "has-flag@npm:4.0.0"
+  checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1
+  languageName: node
+  linkType: hard
+
+"hasown@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "hasown@npm:2.0.2"
+  dependencies:
+    function-bind: "npm:^1.1.2"
+  checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9
+  languageName: node
+  linkType: hard
+
+"he@npm:^1.2.0":
+  version: 1.2.0
+  resolution: "he@npm:1.2.0"
+  bin:
+    he: bin/he
+  checksum: 10c0/a27d478befe3c8192f006cdd0639a66798979dfa6e2125c6ac582a19a5ebfec62ad83e8382e6036170d873f46e4536a7e795bf8b95bf7c247f4cc0825ccc8c17
+  languageName: node
+  linkType: hard
+
+"html-escaper@npm:^2.0.0":
+  version: 2.0.2
+  resolution: "html-escaper@npm:2.0.2"
+  checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0
+  languageName: node
+  linkType: hard
+
+"http-cache-semantics@npm:^4.1.1":
+  version: 4.2.0
+  resolution: "http-cache-semantics@npm:4.2.0"
+  checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37
+  languageName: node
+  linkType: hard
+
+"http-proxy-agent@npm:^7.0.0":
+  version: 7.0.2
+  resolution: "http-proxy-agent@npm:7.0.2"
+  dependencies:
+    agent-base: "npm:^7.1.0"
+    debug: "npm:^4.3.4"
+  checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921
+  languageName: node
+  linkType: hard
+
+"https-proxy-agent@npm:^7.0.1":
+  version: 7.0.6
+  resolution: "https-proxy-agent@npm:7.0.6"
+  dependencies:
+    agent-base: "npm:^7.1.2"
+    debug: "npm:4"
+  checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac
+  languageName: node
+  linkType: hard
+
+"human-signals@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "human-signals@npm:2.1.0"
+  checksum: 10c0/695edb3edfcfe9c8b52a76926cd31b36978782062c0ed9b1192b36bebc75c4c87c82e178dfcb0ed0fc27ca59d434198aac0bd0be18f5781ded775604db22304a
+  languageName: node
+  linkType: hard
+
+"iconv-lite@npm:^0.6.2":
+  version: 0.6.3
+  resolution: "iconv-lite@npm:0.6.3"
+  dependencies:
+    safer-buffer: "npm:>= 2.1.2 < 3.0.0"
+  checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1
+  languageName: node
+  linkType: hard
+
+"ieee754@npm:^1.1.13":
+  version: 1.2.1
+  resolution: "ieee754@npm:1.2.1"
+  checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb
+  languageName: node
+  linkType: hard
+
+"import-lazy@npm:~4.0.0":
+  version: 4.0.0
+  resolution: "import-lazy@npm:4.0.0"
+  checksum: 10c0/a3520313e2c31f25c0b06aa66d167f329832b68a4f957d7c9daf6e0fa41822b6e84948191648b9b9d8ca82f94740cdf15eecf2401a5b42cd1c33fd84f2225cca
+  languageName: node
+  linkType: hard
+
+"import-local@npm:^3.2.0":
+  version: 3.2.0
+  resolution: "import-local@npm:3.2.0"
+  dependencies:
+    pkg-dir: "npm:^4.2.0"
+    resolve-cwd: "npm:^3.0.0"
+  bin:
+    import-local-fixture: fixtures/cli.js
+  checksum: 10c0/94cd6367a672b7e0cb026970c85b76902d2710a64896fa6de93bd5c571dd03b228c5759308959de205083e3b1c61e799f019c9e36ee8e9c523b993e1057f0433
+  languageName: node
+  linkType: hard
+
+"imurmurhash@npm:^0.1.4":
+  version: 0.1.4
+  resolution: "imurmurhash@npm:0.1.4"
+  checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6
+  languageName: node
+  linkType: hard
+
+"indent-string@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "indent-string@npm:4.0.0"
+  checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f
+  languageName: node
+  linkType: hard
+
+"inflight@npm:^1.0.4":
+  version: 1.0.6
+  resolution: "inflight@npm:1.0.6"
+  dependencies:
+    once: "npm:^1.3.0"
+    wrappy: "npm:1"
+  checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2
+  languageName: node
+  linkType: hard
+
+"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1":
+  version: 2.0.4
+  resolution: "inherits@npm:2.0.4"
+  checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2
+  languageName: node
+  linkType: hard
+
+"ini@npm:~1.3.0":
+  version: 1.3.8
+  resolution: "ini@npm:1.3.8"
+  checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a
+  languageName: node
+  linkType: hard
+
+"ip-address@npm:^10.0.1":
+  version: 10.0.1
+  resolution: "ip-address@npm:10.0.1"
+  checksum: 10c0/1634d79dae18394004775cb6d699dc46b7c23df6d2083164025a2b15240c1164fccde53d0e08bd5ee4fc53913d033ab6b5e395a809ad4b956a940c446e948843
+  languageName: node
+  linkType: hard
+
+"is-arrayish@npm:^0.2.1":
+  version: 0.2.1
+  resolution: "is-arrayish@npm:0.2.1"
+  checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729
+  languageName: node
+  linkType: hard
+
+"is-core-module@npm:^2.16.0":
+  version: 2.16.1
+  resolution: "is-core-module@npm:2.16.1"
+  dependencies:
+    hasown: "npm:^2.0.2"
+  checksum: 10c0/898443c14780a577e807618aaae2b6f745c8538eca5c7bc11388a3f2dc6de82b9902bcc7eb74f07be672b11bbe82dd6a6edded44a00cb3d8f933d0459905eedd
+  languageName: node
+  linkType: hard
+
+"is-fullwidth-code-point@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "is-fullwidth-code-point@npm:3.0.0"
+  checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc
+  languageName: node
+  linkType: hard
+
+"is-generator-fn@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "is-generator-fn@npm:2.1.0"
+  checksum: 10c0/2957cab387997a466cd0bf5c1b6047bd21ecb32bdcfd8996b15747aa01002c1c88731802f1b3d34ac99f4f6874b626418bd118658cf39380fe5fff32a3af9c4d
+  languageName: node
+  linkType: hard
+
+"is-lambda@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "is-lambda@npm:1.0.1"
+  checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d
+  languageName: node
+  linkType: hard
+
+"is-number@npm:^7.0.0":
+  version: 7.0.0
+  resolution: "is-number@npm:7.0.0"
+  checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811
+  languageName: node
+  linkType: hard
+
+"is-stream@npm:^2.0.0":
+  version: 2.0.1
+  resolution: "is-stream@npm:2.0.1"
+  checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5
+  languageName: node
+  linkType: hard
+
+"isarray@npm:0.0.1":
+  version: 0.0.1
+  resolution: "isarray@npm:0.0.1"
+  checksum: 10c0/ed1e62da617f71fe348907c71743b5ed550448b455f8d269f89a7c7ddb8ae6e962de3dab6a74a237b06f5eb7f6ece7a45ada8ce96d87fe972926530f91ae3311
+  languageName: node
+  linkType: hard
+
+"isexe@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "isexe@npm:2.0.0"
+  checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d
+  languageName: node
+  linkType: hard
+
+"isexe@npm:^3.1.1":
+  version: 3.1.1
+  resolution: "isexe@npm:3.1.1"
+  checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7
+  languageName: node
+  linkType: hard
+
+"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0":
+  version: 3.2.2
+  resolution: "istanbul-lib-coverage@npm:3.2.2"
+  checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b
+  languageName: node
+  linkType: hard
+
+"istanbul-lib-instrument@npm:^6.0.0, istanbul-lib-instrument@npm:^6.0.2":
+  version: 6.0.3
+  resolution: "istanbul-lib-instrument@npm:6.0.3"
+  dependencies:
+    "@babel/core": "npm:^7.23.9"
+    "@babel/parser": "npm:^7.23.9"
+    "@istanbuljs/schema": "npm:^0.1.3"
+    istanbul-lib-coverage: "npm:^3.2.0"
+    semver: "npm:^7.5.4"
+  checksum: 10c0/a1894e060dd2a3b9f046ffdc87b44c00a35516f5e6b7baf4910369acca79e506fc5323a816f811ae23d82334b38e3ddeb8b3b331bd2c860540793b59a8689128
+  languageName: node
+  linkType: hard
+
+"istanbul-lib-report@npm:^3.0.0":
+  version: 3.0.1
+  resolution: "istanbul-lib-report@npm:3.0.1"
+  dependencies:
+    istanbul-lib-coverage: "npm:^3.0.0"
+    make-dir: "npm:^4.0.0"
+    supports-color: "npm:^7.1.0"
+  checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7
+  languageName: node
+  linkType: hard
+
+"istanbul-lib-source-maps@npm:^5.0.0":
+  version: 5.0.6
+  resolution: "istanbul-lib-source-maps@npm:5.0.6"
+  dependencies:
+    "@jridgewell/trace-mapping": "npm:^0.3.23"
+    debug: "npm:^4.1.1"
+    istanbul-lib-coverage: "npm:^3.0.0"
+  checksum: 10c0/ffe75d70b303a3621ee4671554f306e0831b16f39ab7f4ab52e54d356a5d33e534d97563e318f1333a6aae1d42f91ec49c76b6cd3f3fb378addcb5c81da0255f
+  languageName: node
+  linkType: hard
+
+"istanbul-reports@npm:^3.1.3":
+  version: 3.2.0
+  resolution: "istanbul-reports@npm:3.2.0"
+  dependencies:
+    html-escaper: "npm:^2.0.0"
+    istanbul-lib-report: "npm:^3.0.0"
+  checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc
+  languageName: node
+  linkType: hard
+
+"jackspeak@npm:^3.1.2":
+  version: 3.4.3
+  resolution: "jackspeak@npm:3.4.3"
+  dependencies:
+    "@isaacs/cliui": "npm:^8.0.2"
+    "@pkgjs/parseargs": "npm:^0.11.0"
+  dependenciesMeta:
+    "@pkgjs/parseargs":
+      optional: true
+  checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9
+  languageName: node
+  linkType: hard
+
+"jackspeak@npm:^4.1.1":
+  version: 4.1.1
+  resolution: "jackspeak@npm:4.1.1"
+  dependencies:
+    "@isaacs/cliui": "npm:^8.0.2"
+  checksum: 10c0/84ec4f8e21d6514db24737d9caf65361511f75e5e424980eebca4199f400874f45e562ac20fa8aeb1dd20ca2f3f81f0788b6e9c3e64d216a5794fd6f30e0e042
+  languageName: node
+  linkType: hard
+
+"jest-changed-files@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-changed-files@npm:30.2.0"
+  dependencies:
+    execa: "npm:^5.1.1"
+    jest-util: "npm:30.2.0"
+    p-limit: "npm:^3.1.0"
+  checksum: 10c0/0ce838f8bffdadcdc19028f4b7a24c04d2f9885ee5c5c1bb4746c205cb96649934090ef6492c3dc45b1be097672b4f8043ad141278bc82f390579fa3ea4c11fe
+  languageName: node
+  linkType: hard
+
+"jest-circus@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-circus@npm:30.2.0"
+  dependencies:
+    "@jest/environment": "npm:30.2.0"
+    "@jest/expect": "npm:30.2.0"
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    chalk: "npm:^4.1.2"
+    co: "npm:^4.6.0"
+    dedent: "npm:^1.6.0"
+    is-generator-fn: "npm:^2.1.0"
+    jest-each: "npm:30.2.0"
+    jest-matcher-utils: "npm:30.2.0"
+    jest-message-util: "npm:30.2.0"
+    jest-runtime: "npm:30.2.0"
+    jest-snapshot: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    p-limit: "npm:^3.1.0"
+    pretty-format: "npm:30.2.0"
+    pure-rand: "npm:^7.0.0"
+    slash: "npm:^3.0.0"
+    stack-utils: "npm:^2.0.6"
+  checksum: 10c0/32fc88e13d3e811a9af5ca02d31f7cc742e726a0128df0b023330d6dff6ac29bf981da09937162f7c0705cf327df8d24e46de84860f6817dbc134438315c2967
+  languageName: node
+  linkType: hard
+
+"jest-cli@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-cli@npm:30.2.0"
+  dependencies:
+    "@jest/core": "npm:30.2.0"
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    chalk: "npm:^4.1.2"
+    exit-x: "npm:^0.2.2"
+    import-local: "npm:^3.2.0"
+    jest-config: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    jest-validate: "npm:30.2.0"
+    yargs: "npm:^17.7.2"
+  peerDependencies:
+    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+  peerDependenciesMeta:
+    node-notifier:
+      optional: true
+  bin:
+    jest: ./bin/jest.js
+  checksum: 10c0/b722a98cdf7b0ff1c273dd4efbaf331d683335f1f338a76a24492574e582a4e5a12a9df66e41bf4c92c7cffe0f51b759818ecd42044cd9bbef67d40359240989
+  languageName: node
+  linkType: hard
+
+"jest-config@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-config@npm:30.2.0"
+  dependencies:
+    "@babel/core": "npm:^7.27.4"
+    "@jest/get-type": "npm:30.1.0"
+    "@jest/pattern": "npm:30.0.1"
+    "@jest/test-sequencer": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    babel-jest: "npm:30.2.0"
+    chalk: "npm:^4.1.2"
+    ci-info: "npm:^4.2.0"
+    deepmerge: "npm:^4.3.1"
+    glob: "npm:^10.3.10"
+    graceful-fs: "npm:^4.2.11"
+    jest-circus: "npm:30.2.0"
+    jest-docblock: "npm:30.2.0"
+    jest-environment-node: "npm:30.2.0"
+    jest-regex-util: "npm:30.0.1"
+    jest-resolve: "npm:30.2.0"
+    jest-runner: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    jest-validate: "npm:30.2.0"
+    micromatch: "npm:^4.0.8"
+    parse-json: "npm:^5.2.0"
+    pretty-format: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+    strip-json-comments: "npm:^3.1.1"
+  peerDependencies:
+    "@types/node": "*"
+    esbuild-register: ">=3.4.0"
+    ts-node: ">=9.0.0"
+  peerDependenciesMeta:
+    "@types/node":
+      optional: true
+    esbuild-register:
+      optional: true
+    ts-node:
+      optional: true
+  checksum: 10c0/f02bb747e3382cdbb5a00abd583e9118a0b4f1d9d4cad01b5cc06b7fab9b817419ec183856cd791b2e9167051cad52b3d22ea34319a28c8f3e70a5ce73d05faa
+  languageName: node
+  linkType: hard
+
+"jest-diff@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-diff@npm:30.2.0"
+  dependencies:
+    "@jest/diff-sequences": "npm:30.0.1"
+    "@jest/get-type": "npm:30.1.0"
+    chalk: "npm:^4.1.2"
+    pretty-format: "npm:30.2.0"
+  checksum: 10c0/5fac2cd89a10b282c5a68fc6206a95dfff9955ed0b758d24ffb0edcb20fb2f98e1fa5045c5c4205d952712ea864c6a086654f80cdd500cce054a2f5daf5b4419
+  languageName: node
+  linkType: hard
+
+"jest-docblock@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-docblock@npm:30.2.0"
+  dependencies:
+    detect-newline: "npm:^3.1.0"
+  checksum: 10c0/2578366604eef1b36d59ffe1fc52a710995571535d437f83d94ff94756a83f78e699c1ba004c38a34c01859d669fd6c64e865c23c5a7d5bf4837cfca4bef3dda
+  languageName: node
+  linkType: hard
+
+"jest-each@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-each@npm:30.2.0"
+  dependencies:
+    "@jest/get-type": "npm:30.1.0"
+    "@jest/types": "npm:30.2.0"
+    chalk: "npm:^4.1.2"
+    jest-util: "npm:30.2.0"
+    pretty-format: "npm:30.2.0"
+  checksum: 10c0/4fa7e88a2741daaebd58cf49f9add8bd6c68657d2c106a170ebe4d7f86082c9eede2b13924304277a92e02b31b59a3c34949877da077bc27712b57913bb88321
+  languageName: node
+  linkType: hard
+
+"jest-environment-node@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-environment-node@npm:30.2.0"
+  dependencies:
+    "@jest/environment": "npm:30.2.0"
+    "@jest/fake-timers": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    jest-mock: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    jest-validate: "npm:30.2.0"
+  checksum: 10c0/866ba2c04ccf003845a8ca1f372081d76923849ae8e06e50cdfed792e41a976b5f953e15f3af17ff51b111b9540cf846f7f582530ca724c2a2abf15d15a99728
+  languageName: node
+  linkType: hard
+
+"jest-haste-map@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-haste-map@npm:30.2.0"
+  dependencies:
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    anymatch: "npm:^3.1.3"
+    fb-watchman: "npm:^2.0.2"
+    fsevents: "npm:^2.3.3"
+    graceful-fs: "npm:^4.2.11"
+    jest-regex-util: "npm:30.0.1"
+    jest-util: "npm:30.2.0"
+    jest-worker: "npm:30.2.0"
+    micromatch: "npm:^4.0.8"
+    walker: "npm:^1.0.8"
+  dependenciesMeta:
+    fsevents:
+      optional: true
+  checksum: 10c0/61b4ad5a59b4dfadac2f903f3d723d9017aada268c49b9222ec1e15c4892fd4c36af59b65f37f026d747d829672ab9679509fea5d4248d07a93b892963e1bb4e
+  languageName: node
+  linkType: hard
+
+"jest-leak-detector@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-leak-detector@npm:30.2.0"
+  dependencies:
+    "@jest/get-type": "npm:30.1.0"
+    pretty-format: "npm:30.2.0"
+  checksum: 10c0/68e2822aabe302983b65a08b19719a2444259af8a23ff20a6e2b6ce7759f55730f51c7cf16c65cb6be930c80a6cc70a4820239c84e8f333c9670a8e3a4a21801
+  languageName: node
+  linkType: hard
+
+"jest-matcher-utils@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-matcher-utils@npm:30.2.0"
+  dependencies:
+    "@jest/get-type": "npm:30.1.0"
+    chalk: "npm:^4.1.2"
+    jest-diff: "npm:30.2.0"
+    pretty-format: "npm:30.2.0"
+  checksum: 10c0/f221c8afa04cee693a2be735482c5db4ec6f845f8ca3a04cb419be34c6257f4531dab89c836251f31d1859318c38997e8e9f34bf7b4cdcc8c7be8ae6e2ecb9f2
+  languageName: node
+  linkType: hard
+
+"jest-message-util@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-message-util@npm:30.2.0"
+  dependencies:
+    "@babel/code-frame": "npm:^7.27.1"
+    "@jest/types": "npm:30.2.0"
+    "@types/stack-utils": "npm:^2.0.3"
+    chalk: "npm:^4.1.2"
+    graceful-fs: "npm:^4.2.11"
+    micromatch: "npm:^4.0.8"
+    pretty-format: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+    stack-utils: "npm:^2.0.6"
+  checksum: 10c0/9c4aae95f9e73a754e5ecababa06e5c00cf549ff1651bbbf9aadc671ee57e688b01606ef0e9932d9dfe3d4b8f4511b6e8d01e131a49d2f82761c820ab93ae519
+  languageName: node
+  linkType: hard
+
+"jest-mock@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-mock@npm:30.2.0"
+  dependencies:
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    jest-util: "npm:30.2.0"
+  checksum: 10c0/dfc8eb87f4075242f1b31d9dcac606f945c4f6a245d2bb67273738d266bea6345e10de3afa675076d545361bc96b754f764cffb0ccc2e99767484bece981b2f8
+  languageName: node
+  linkType: hard
+
+"jest-pnp-resolver@npm:^1.2.3":
+  version: 1.2.3
+  resolution: "jest-pnp-resolver@npm:1.2.3"
+  peerDependencies:
+    jest-resolve: "*"
+  peerDependenciesMeta:
+    jest-resolve:
+      optional: true
+  checksum: 10c0/86eec0c78449a2de733a6d3e316d49461af6a858070e113c97f75fb742a48c2396ea94150cbca44159ffd4a959f743a47a8b37a792ef6fdad2cf0a5cba973fac
+  languageName: node
+  linkType: hard
+
+"jest-regex-util@npm:30.0.1":
+  version: 30.0.1
+  resolution: "jest-regex-util@npm:30.0.1"
+  checksum: 10c0/f30c70524ebde2d1012afe5ffa5691d5d00f7d5ba9e43d588f6460ac6fe96f9e620f2f9b36a02d0d3e7e77bc8efb8b3450ae3b80ac53c8be5099e01bf54f6728
+  languageName: node
+  linkType: hard
+
+"jest-resolve-dependencies@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-resolve-dependencies@npm:30.2.0"
+  dependencies:
+    jest-regex-util: "npm:30.0.1"
+    jest-snapshot: "npm:30.2.0"
+  checksum: 10c0/f98f2187b490f402dd9ed6b15b5d324b1220d250a5768d46b1f1582cef05b830311351532a7d19f1868a2ce0049856ae6c26587f3869995cae7850739088b879
+  languageName: node
+  linkType: hard
+
+"jest-resolve@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-resolve@npm:30.2.0"
+  dependencies:
+    chalk: "npm:^4.1.2"
+    graceful-fs: "npm:^4.2.11"
+    jest-haste-map: "npm:30.2.0"
+    jest-pnp-resolver: "npm:^1.2.3"
+    jest-util: "npm:30.2.0"
+    jest-validate: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+    unrs-resolver: "npm:^1.7.11"
+  checksum: 10c0/149576b81609a79889d08298a95d52920839f796d24f8701beacaf998a4916df205acf86b64d0bc294172a821b88d144facf44ae5a4cb3cfaa03fa06a3fc666d
+  languageName: node
+  linkType: hard
+
+"jest-runner@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-runner@npm:30.2.0"
+  dependencies:
+    "@jest/console": "npm:30.2.0"
+    "@jest/environment": "npm:30.2.0"
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/transform": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    chalk: "npm:^4.1.2"
+    emittery: "npm:^0.13.1"
+    exit-x: "npm:^0.2.2"
+    graceful-fs: "npm:^4.2.11"
+    jest-docblock: "npm:30.2.0"
+    jest-environment-node: "npm:30.2.0"
+    jest-haste-map: "npm:30.2.0"
+    jest-leak-detector: "npm:30.2.0"
+    jest-message-util: "npm:30.2.0"
+    jest-resolve: "npm:30.2.0"
+    jest-runtime: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    jest-watcher: "npm:30.2.0"
+    jest-worker: "npm:30.2.0"
+    p-limit: "npm:^3.1.0"
+    source-map-support: "npm:0.5.13"
+  checksum: 10c0/68cb5eb993b4a02143fc442c245b17567432709879ad5f859fec635ccdf4ad0ef128c9fc6765c1582b3f5136b36cad5c5dd173926081bfc527d490b27406383e
+  languageName: node
+  linkType: hard
+
+"jest-runtime@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-runtime@npm:30.2.0"
+  dependencies:
+    "@jest/environment": "npm:30.2.0"
+    "@jest/fake-timers": "npm:30.2.0"
+    "@jest/globals": "npm:30.2.0"
+    "@jest/source-map": "npm:30.0.1"
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/transform": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    chalk: "npm:^4.1.2"
+    cjs-module-lexer: "npm:^2.1.0"
+    collect-v8-coverage: "npm:^1.0.2"
+    glob: "npm:^10.3.10"
+    graceful-fs: "npm:^4.2.11"
+    jest-haste-map: "npm:30.2.0"
+    jest-message-util: "npm:30.2.0"
+    jest-mock: "npm:30.2.0"
+    jest-regex-util: "npm:30.0.1"
+    jest-resolve: "npm:30.2.0"
+    jest-snapshot: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    slash: "npm:^3.0.0"
+    strip-bom: "npm:^4.0.0"
+  checksum: 10c0/d77b7eb75485f2b4913f635aeffa8e3e1b9baafb7a7f901f3c212195beb31f519e4b03358b5e454caee5cc94a2b9952c962fa7e5b0ff2ed06009a661924fd23e
+  languageName: node
+  linkType: hard
+
+"jest-snapshot@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-snapshot@npm:30.2.0"
+  dependencies:
+    "@babel/core": "npm:^7.27.4"
+    "@babel/generator": "npm:^7.27.5"
+    "@babel/plugin-syntax-jsx": "npm:^7.27.1"
+    "@babel/plugin-syntax-typescript": "npm:^7.27.1"
+    "@babel/types": "npm:^7.27.3"
+    "@jest/expect-utils": "npm:30.2.0"
+    "@jest/get-type": "npm:30.1.0"
+    "@jest/snapshot-utils": "npm:30.2.0"
+    "@jest/transform": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    babel-preset-current-node-syntax: "npm:^1.2.0"
+    chalk: "npm:^4.1.2"
+    expect: "npm:30.2.0"
+    graceful-fs: "npm:^4.2.11"
+    jest-diff: "npm:30.2.0"
+    jest-matcher-utils: "npm:30.2.0"
+    jest-message-util: "npm:30.2.0"
+    jest-util: "npm:30.2.0"
+    pretty-format: "npm:30.2.0"
+    semver: "npm:^7.7.2"
+    synckit: "npm:^0.11.8"
+  checksum: 10c0/961b13a3c9dcf8c533fe2ab8375bcdf441bd8680a7a7878245d8d8a4697432d806f7817cfaa061904e0c6cc939a38f1fe9f5af868b86328e77833a58822b3b63
+  languageName: node
+  linkType: hard
+
+"jest-util@npm:30.2.0, jest-util@npm:^30.2.0":
+  version: 30.2.0
+  resolution: "jest-util@npm:30.2.0"
+  dependencies:
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    chalk: "npm:^4.1.2"
+    ci-info: "npm:^4.2.0"
+    graceful-fs: "npm:^4.2.11"
+    picomatch: "npm:^4.0.2"
+  checksum: 10c0/896d663554b35258a87ec1a0a0fdd8741fdf4f3239d09fc52fdd88fa5c411a5ece7903bbbbd7d5194743fcb69f62afc3287e90f57736a91e7df95ad421937936
+  languageName: node
+  linkType: hard
+
+"jest-validate@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-validate@npm:30.2.0"
+  dependencies:
+    "@jest/get-type": "npm:30.1.0"
+    "@jest/types": "npm:30.2.0"
+    camelcase: "npm:^6.3.0"
+    chalk: "npm:^4.1.2"
+    leven: "npm:^3.1.0"
+    pretty-format: "npm:30.2.0"
+  checksum: 10c0/56566643d79ca07f021fa14cebb62c423ae405757cb8d742113ff0070f0761b80c77f665fac8d89622faaab71fc5452e1471939028187a88c8445303d7976255
+  languageName: node
+  linkType: hard
+
+"jest-watcher@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-watcher@npm:30.2.0"
+  dependencies:
+    "@jest/test-result": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    "@types/node": "npm:*"
+    ansi-escapes: "npm:^4.3.2"
+    chalk: "npm:^4.1.2"
+    emittery: "npm:^0.13.1"
+    jest-util: "npm:30.2.0"
+    string-length: "npm:^4.0.2"
+  checksum: 10c0/51587968fabb5b180383d638a04db253b82d9cc3f53fbba06ba7b0544146178d50becc090aca7931e2d4eb9aa1624bb3fbd1a2571484c9391554404e8b5d8fe7
+  languageName: node
+  linkType: hard
+
+"jest-worker@npm:30.2.0":
+  version: 30.2.0
+  resolution: "jest-worker@npm:30.2.0"
+  dependencies:
+    "@types/node": "npm:*"
+    "@ungap/structured-clone": "npm:^1.3.0"
+    jest-util: "npm:30.2.0"
+    merge-stream: "npm:^2.0.0"
+    supports-color: "npm:^8.1.1"
+  checksum: 10c0/1ea47f6c682ba6cdbd50630544236aabccacf1d88335607206c10871a9777a45b0fc6336c8eb6344e32e69dd7681de17b2199b4d4552b00d48aade303627125c
+  languageName: node
+  linkType: hard
+
+"jest@npm:^30.2.0":
+  version: 30.2.0
+  resolution: "jest@npm:30.2.0"
+  dependencies:
+    "@jest/core": "npm:30.2.0"
+    "@jest/types": "npm:30.2.0"
+    import-local: "npm:^3.2.0"
+    jest-cli: "npm:30.2.0"
+  peerDependencies:
+    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+  peerDependenciesMeta:
+    node-notifier:
+      optional: true
+  bin:
+    jest: ./bin/jest.js
+  checksum: 10c0/af580c6e265d21870c2c98e31f17f2f5cb5c9e6cf9be26b95eaf4fad4140a01579f3b5844d4264cd8357eb24908e95f983ea84d20b8afef46e62aed3dd9452eb
+  languageName: node
+  linkType: hard
+
+"jju@npm:~1.4.0":
+  version: 1.4.0
+  resolution: "jju@npm:1.4.0"
+  checksum: 10c0/f3f444557e4364cfc06b1abf8331bf3778b26c0c8552ca54429bc0092652172fdea26cbffe33e1017b303d5aa506f7ede8571857400efe459cb7439180e2acad
+  languageName: node
+  linkType: hard
+
+"js-tokens@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "js-tokens@npm:4.0.0"
+  checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed
+  languageName: node
+  linkType: hard
+
+"js-yaml@npm:^3.13.1":
+  version: 3.14.1
+  resolution: "js-yaml@npm:3.14.1"
+  dependencies:
+    argparse: "npm:^1.0.7"
+    esprima: "npm:^4.0.0"
+  bin:
+    js-yaml: bin/js-yaml.js
+  checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b
+  languageName: node
+  linkType: hard
+
+"jsesc@npm:^3.0.2":
+  version: 3.1.0
+  resolution: "jsesc@npm:3.1.0"
+  bin:
+    jsesc: bin/jsesc
+  checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1
+  languageName: node
+  linkType: hard
+
+"json-parse-even-better-errors@npm:^2.3.0":
+  version: 2.3.1
+  resolution: "json-parse-even-better-errors@npm:2.3.1"
+  checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3
+  languageName: node
+  linkType: hard
+
+"json-schema-traverse@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "json-schema-traverse@npm:1.0.0"
+  checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6
+  languageName: node
+  linkType: hard
+
+"json5@npm:^2.2.3":
+  version: 2.2.3
+  resolution: "json5@npm:2.2.3"
+  bin:
+    json5: lib/cli.js
+  checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c
+  languageName: node
+  linkType: hard
+
+"jsonfile@npm:^6.0.1":
+  version: 6.2.0
+  resolution: "jsonfile@npm:6.2.0"
+  dependencies:
+    graceful-fs: "npm:^4.1.6"
+    universalify: "npm:^2.0.0"
+  dependenciesMeta:
+    graceful-fs:
+      optional: true
+  checksum: 10c0/7f4f43b08d1869ded8a6822213d13ae3b99d651151d77efd1557ced0889c466296a7d9684e397bd126acf5eb2cfcb605808c3e681d0fdccd2fe5a04b47e76c0d
+  languageName: node
+  linkType: hard
+
+"kolorist@npm:^1.8.0":
+  version: 1.8.0
+  resolution: "kolorist@npm:1.8.0"
+  checksum: 10c0/73075db44a692bf6c34a649f3b4b3aea4993b84f6b754cbf7a8577e7c7db44c0bad87752bd23b0ce533f49de2244ce2ce03b7b1b667a85ae170a94782cc50f9b
+  languageName: node
+  linkType: hard
+
+"leven@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "leven@npm:3.1.0"
+  checksum: 10c0/cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df
+  languageName: node
+  linkType: hard
+
+"lines-and-columns@npm:^1.1.6":
+  version: 1.2.4
+  resolution: "lines-and-columns@npm:1.2.4"
+  checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d
+  languageName: node
+  linkType: hard
+
+"local-pkg@npm:^1.0.0":
+  version: 1.1.2
+  resolution: "local-pkg@npm:1.1.2"
+  dependencies:
+    mlly: "npm:^1.7.4"
+    pkg-types: "npm:^2.3.0"
+    quansync: "npm:^0.2.11"
+  checksum: 10c0/1bcfcc5528dea95cba3caa478126a348d3985aad9f69ecf7802c13efef90897e1c5ff7851974332c5e6d4a4698efe610fef758a068c8bc3feb5322aeb35d5993
+  languageName: node
+  linkType: hard
+
+"locate-path@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "locate-path@npm:5.0.0"
+  dependencies:
+    p-locate: "npm:^4.1.0"
+  checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59
+  languageName: node
+  linkType: hard
+
+"lodash.memoize@npm:^4.1.2":
+  version: 4.1.2
+  resolution: "lodash.memoize@npm:4.1.2"
+  checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8
+  languageName: node
+  linkType: hard
+
+"lodash@npm:~4.17.15":
+  version: 4.17.21
+  resolution: "lodash@npm:4.17.21"
+  checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c
+  languageName: node
+  linkType: hard
+
+"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0":
+  version: 10.4.3
+  resolution: "lru-cache@npm:10.4.3"
+  checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb
+  languageName: node
+  linkType: hard
+
+"lru-cache@npm:^11.0.0":
+  version: 11.2.2
+  resolution: "lru-cache@npm:11.2.2"
+  checksum: 10c0/72d7831bbebc85e2bdefe01047ee5584db69d641c48d7a509e86f66f6ee111b30af7ec3bd68a967d47b69a4b1fa8bbf3872630bd06a63b6735e6f0a5f1c8e83d
+  languageName: node
+  linkType: hard
+
+"lru-cache@npm:^5.1.1":
+  version: 5.1.1
+  resolution: "lru-cache@npm:5.1.1"
+  dependencies:
+    yallist: "npm:^3.0.2"
+  checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482
+  languageName: node
+  linkType: hard
+
+"lru-cache@npm:^6.0.0":
+  version: 6.0.0
+  resolution: "lru-cache@npm:6.0.0"
+  dependencies:
+    yallist: "npm:^4.0.0"
+  checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9
+  languageName: node
+  linkType: hard
+
+"magic-string@npm:^0.30.17":
+  version: 0.30.19
+  resolution: "magic-string@npm:0.30.19"
+  dependencies:
+    "@jridgewell/sourcemap-codec": "npm:^1.5.5"
+  checksum: 10c0/db23fd2e2ee98a1aeb88a4cdb2353137fcf05819b883c856dd79e4c7dfb25151e2a5a4d5dbd88add5e30ed8ae5c51bcf4accbc6becb75249d924ec7b4fbcae27
+  languageName: node
+  linkType: hard
+
+"make-dir@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "make-dir@npm:4.0.0"
+  dependencies:
+    semver: "npm:^7.5.3"
+  checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68
+  languageName: node
+  linkType: hard
+
+"make-error@npm:^1.1.1, make-error@npm:^1.3.6":
+  version: 1.3.6
+  resolution: "make-error@npm:1.3.6"
+  checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f
+  languageName: node
+  linkType: hard
+
+"make-fetch-happen@npm:^13.0.0":
+  version: 13.0.1
+  resolution: "make-fetch-happen@npm:13.0.1"
+  dependencies:
+    "@npmcli/agent": "npm:^2.0.0"
+    cacache: "npm:^18.0.0"
+    http-cache-semantics: "npm:^4.1.1"
+    is-lambda: "npm:^1.0.1"
+    minipass: "npm:^7.0.2"
+    minipass-fetch: "npm:^3.0.0"
+    minipass-flush: "npm:^1.0.5"
+    minipass-pipeline: "npm:^1.2.4"
+    negotiator: "npm:^0.6.3"
+    proc-log: "npm:^4.2.0"
+    promise-retry: "npm:^2.0.1"
+    ssri: "npm:^10.0.0"
+  checksum: 10c0/df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e
+  languageName: node
+  linkType: hard
+
+"make-fetch-happen@npm:^14.0.3":
+  version: 14.0.3
+  resolution: "make-fetch-happen@npm:14.0.3"
+  dependencies:
+    "@npmcli/agent": "npm:^3.0.0"
+    cacache: "npm:^19.0.1"
+    http-cache-semantics: "npm:^4.1.1"
+    minipass: "npm:^7.0.2"
+    minipass-fetch: "npm:^4.0.0"
+    minipass-flush: "npm:^1.0.5"
+    minipass-pipeline: "npm:^1.2.4"
+    negotiator: "npm:^1.0.0"
+    proc-log: "npm:^5.0.0"
+    promise-retry: "npm:^2.0.1"
+    ssri: "npm:^12.0.0"
+  checksum: 10c0/c40efb5e5296e7feb8e37155bde8eb70bc57d731b1f7d90e35a092fde403d7697c56fb49334d92d330d6f1ca29a98142036d6480a12681133a0a1453164cb2f0
+  languageName: node
+  linkType: hard
+
+"makeerror@npm:1.0.12":
+  version: 1.0.12
+  resolution: "makeerror@npm:1.0.12"
+  dependencies:
+    tmpl: "npm:1.0.5"
+  checksum: 10c0/b0e6e599780ce6bab49cc413eba822f7d1f0dfebd1c103eaa3785c59e43e22c59018323cf9e1708f0ef5329e94a745d163fcbb6bff8e4c6742f9be9e86f3500c
+  languageName: node
+  linkType: hard
+
+"merge-stream@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "merge-stream@npm:2.0.0"
+  checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5
+  languageName: node
+  linkType: hard
+
+"micromatch@npm:^4.0.8":
+  version: 4.0.8
+  resolution: "micromatch@npm:4.0.8"
+  dependencies:
+    braces: "npm:^3.0.3"
+    picomatch: "npm:^2.3.1"
+  checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8
+  languageName: node
+  linkType: hard
+
+"mimic-fn@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "mimic-fn@npm:2.1.0"
+  checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4
+  languageName: node
+  linkType: hard
+
+"mimic-response@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "mimic-response@npm:3.1.0"
+  checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362
+  languageName: node
+  linkType: hard
+
+"minimatch@npm:10.0.3, minimatch@npm:^10.0.3":
+  version: 10.0.3
+  resolution: "minimatch@npm:10.0.3"
+  dependencies:
+    "@isaacs/brace-expansion": "npm:^5.0.0"
+  checksum: 10c0/e43e4a905c5d70ac4cec8530ceaeccb9c544b1ba8ac45238e2a78121a01c17ff0c373346472d221872563204eabe929ad02669bb575cb1f0cc30facab369f70f
+  languageName: node
+  linkType: hard
+
+"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1":
+  version: 3.1.2
+  resolution: "minimatch@npm:3.1.2"
+  dependencies:
+    brace-expansion: "npm:^1.1.7"
+  checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311
+  languageName: node
+  linkType: hard
+
+"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4":
+  version: 9.0.5
+  resolution: "minimatch@npm:9.0.5"
+  dependencies:
+    brace-expansion: "npm:^2.0.1"
+  checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed
+  languageName: node
+  linkType: hard
+
+"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5":
+  version: 1.2.8
+  resolution: "minimist@npm:1.2.8"
+  checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
+  languageName: node
+  linkType: hard
+
+"minipass-collect@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "minipass-collect@npm:2.0.1"
+  dependencies:
+    minipass: "npm:^7.0.3"
+  checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e
+  languageName: node
+  linkType: hard
+
+"minipass-fetch@npm:^3.0.0":
+  version: 3.0.5
+  resolution: "minipass-fetch@npm:3.0.5"
+  dependencies:
+    encoding: "npm:^0.1.13"
+    minipass: "npm:^7.0.3"
+    minipass-sized: "npm:^1.0.3"
+    minizlib: "npm:^2.1.2"
+  dependenciesMeta:
+    encoding:
+      optional: true
+  checksum: 10c0/9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b
+  languageName: node
+  linkType: hard
+
+"minipass-fetch@npm:^4.0.0":
+  version: 4.0.1
+  resolution: "minipass-fetch@npm:4.0.1"
+  dependencies:
+    encoding: "npm:^0.1.13"
+    minipass: "npm:^7.0.3"
+    minipass-sized: "npm:^1.0.3"
+    minizlib: "npm:^3.0.1"
+  dependenciesMeta:
+    encoding:
+      optional: true
+  checksum: 10c0/a3147b2efe8e078c9bf9d024a0059339c5a09c5b1dded6900a219c218cc8b1b78510b62dae556b507304af226b18c3f1aeb1d48660283602d5b6586c399eed5c
+  languageName: node
+  linkType: hard
+
+"minipass-flush@npm:^1.0.5":
+  version: 1.0.5
+  resolution: "minipass-flush@npm:1.0.5"
+  dependencies:
+    minipass: "npm:^3.0.0"
+  checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd
+  languageName: node
+  linkType: hard
+
+"minipass-pipeline@npm:^1.2.4":
+  version: 1.2.4
+  resolution: "minipass-pipeline@npm:1.2.4"
+  dependencies:
+    minipass: "npm:^3.0.0"
+  checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2
+  languageName: node
+  linkType: hard
+
+"minipass-sized@npm:^1.0.3":
+  version: 1.0.3
+  resolution: "minipass-sized@npm:1.0.3"
+  dependencies:
+    minipass: "npm:^3.0.0"
+  checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb
+  languageName: node
+  linkType: hard
+
+"minipass@npm:^3.0.0":
+  version: 3.3.6
+  resolution: "minipass@npm:3.3.6"
+  dependencies:
+    yallist: "npm:^4.0.0"
+  checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c
+  languageName: node
+  linkType: hard
+
+"minipass@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "minipass@npm:5.0.0"
+  checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462
+  languageName: node
+  linkType: hard
+
+"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2":
+  version: 7.1.2
+  resolution: "minipass@npm:7.1.2"
+  checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557
+  languageName: node
+  linkType: hard
+
+"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2":
+  version: 2.1.2
+  resolution: "minizlib@npm:2.1.2"
+  dependencies:
+    minipass: "npm:^3.0.0"
+    yallist: "npm:^4.0.0"
+  checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78
+  languageName: node
+  linkType: hard
+
+"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "minizlib@npm:3.1.0"
+  dependencies:
+    minipass: "npm:^7.1.2"
+  checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec
+  languageName: node
+  linkType: hard
+
+"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3":
+  version: 0.5.3
+  resolution: "mkdirp-classic@npm:0.5.3"
+  checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168
+  languageName: node
+  linkType: hard
+
+"mkdirp@npm:^1.0.3":
+  version: 1.0.4
+  resolution: "mkdirp@npm:1.0.4"
+  bin:
+    mkdirp: bin/cmd.js
+  checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf
+  languageName: node
+  linkType: hard
+
+"mlly@npm:^1.7.4":
+  version: 1.8.0
+  resolution: "mlly@npm:1.8.0"
+  dependencies:
+    acorn: "npm:^8.15.0"
+    pathe: "npm:^2.0.3"
+    pkg-types: "npm:^1.3.1"
+    ufo: "npm:^1.6.1"
+  checksum: 10c0/f174b844ae066c71e9b128046677868e2e28694f0bbeeffbe760b2a9d8ff24de0748d0fde6fabe706700c1d2e11d3c0d7a53071b5ea99671592fac03364604ab
+  languageName: node
+  linkType: hard
+
+"ms@npm:^2.1.3":
+  version: 2.1.3
+  resolution: "ms@npm:2.1.3"
+  checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
+  languageName: node
+  linkType: hard
+
+"muggle-string@npm:^0.4.1":
+  version: 0.4.1
+  resolution: "muggle-string@npm:0.4.1"
+  checksum: 10c0/e914b63e24cd23f97e18376ec47e4ba3aa24365e4776212b666add2e47bb158003212980d732c49abf3719568900af7861873844a6e2d3a7ca7e86952c0e99e9
+  languageName: node
+  linkType: hard
+
+"nan@npm:^2.22.0":
+  version: 2.23.0
+  resolution: "nan@npm:2.23.0"
+  dependencies:
+    node-gyp: "npm:latest"
+  checksum: 10c0/b986dd257dca53ab43a3b6ca6d0eafde697b69e1d63b242fa4aece50ce97eb169f9c4a5d8eb0eb5f58d118a9595fee11f3198fa210f023440053bb6f54109e73
+  languageName: node
+  linkType: hard
+
+"nanoid@npm:^3.3.11":
+  version: 3.3.11
+  resolution: "nanoid@npm:3.3.11"
+  bin:
+    nanoid: bin/nanoid.cjs
+  checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b
+  languageName: node
+  linkType: hard
+
+"napi-build-utils@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "napi-build-utils@npm:2.0.0"
+  checksum: 10c0/5833aaeb5cc5c173da47a102efa4680a95842c13e0d9cc70428bd3ee8d96bb2172f8860d2811799b5daa5cbeda779933601492a2028a6a5351c6d0fcf6de83db
+  languageName: node
+  linkType: hard
+
+"napi-postinstall@npm:^0.3.0":
+  version: 0.3.3
+  resolution: "napi-postinstall@npm:0.3.3"
+  bin:
+    napi-postinstall: lib/cli.js
+  checksum: 10c0/3f3297c002abd1f1c64730c442e9047e4b50335666bd2821e990e0546ab917f9cd000d3837930a81dbe89075495e884ed526918a85667abeef0654f659217cea
+  languageName: node
+  linkType: hard
+
+"natural-compare@npm:^1.4.0":
+  version: 1.4.0
+  resolution: "natural-compare@npm:1.4.0"
+  checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447
+  languageName: node
+  linkType: hard
+
+"negotiator@npm:^0.6.3":
+  version: 0.6.4
+  resolution: "negotiator@npm:0.6.4"
+  checksum: 10c0/3e677139c7fb7628a6f36335bf11a885a62c21d5390204590a1a214a5631fcbe5ea74ef6a610b60afe84b4d975cbe0566a23f20ee17c77c73e74b80032108dea
+  languageName: node
+  linkType: hard
+
+"negotiator@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "negotiator@npm:1.0.0"
+  checksum: 10c0/4c559dd52669ea48e1914f9d634227c561221dd54734070791f999c52ed0ff36e437b2e07d5c1f6e32909fc625fe46491c16e4a8f0572567d4dd15c3a4fda04b
+  languageName: node
+  linkType: hard
+
+"neo-async@npm:^2.6.2":
+  version: 2.6.2
+  resolution: "neo-async@npm:2.6.2"
+  checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d
+  languageName: node
+  linkType: hard
+
+"node-abi@npm:^3.3.0, node-abi@npm:^3.71.0":
+  version: 3.77.0
+  resolution: "node-abi@npm:3.77.0"
+  dependencies:
+    semver: "npm:^7.3.5"
+  checksum: 10c0/3354289ccca052538f653968ead73d00785e5ab159ce3a575dbff465724dac749821e7c327ae6c4774f29994f94c402fbafc8799b172aabf4aa8a082a070b00a
+  languageName: node
+  linkType: hard
+
+"node-gyp@npm:^10.2.0":
+  version: 10.3.1
+  resolution: "node-gyp@npm:10.3.1"
+  dependencies:
+    env-paths: "npm:^2.2.0"
+    exponential-backoff: "npm:^3.1.1"
+    glob: "npm:^10.3.10"
+    graceful-fs: "npm:^4.2.6"
+    make-fetch-happen: "npm:^13.0.0"
+    nopt: "npm:^7.0.0"
+    proc-log: "npm:^4.1.0"
+    semver: "npm:^7.3.5"
+    tar: "npm:^6.2.1"
+    which: "npm:^4.0.0"
+  bin:
+    node-gyp: bin/node-gyp.js
+  checksum: 10c0/87c3b50e1f6f5256b5d2879a8c064eefa53ed444bad2a20870be43bc189db7cbffe22c30af056046c6d904181d73881b1726fd391d2f6f79f89b991019f195ea
+  languageName: node
+  linkType: hard
+
+"node-gyp@npm:latest":
+  version: 11.4.2
+  resolution: "node-gyp@npm:11.4.2"
+  dependencies:
+    env-paths: "npm:^2.2.0"
+    exponential-backoff: "npm:^3.1.1"
+    graceful-fs: "npm:^4.2.6"
+    make-fetch-happen: "npm:^14.0.3"
+    nopt: "npm:^8.0.0"
+    proc-log: "npm:^5.0.0"
+    semver: "npm:^7.3.5"
+    tar: "npm:^7.4.3"
+    tinyglobby: "npm:^0.2.12"
+    which: "npm:^5.0.0"
+  bin:
+    node-gyp: bin/node-gyp.js
+  checksum: 10c0/0bfd3e96770ed70f07798d881dd37b4267708966d868a0e585986baac487d9cf5831285579fd629a83dc4e434f53e6416ce301097f2ee464cb74d377e4d8bdbe
+  languageName: node
+  linkType: hard
+
+"node-int64@npm:^0.4.0":
+  version: 0.4.0
+  resolution: "node-int64@npm:0.4.0"
+  checksum: 10c0/a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a
+  languageName: node
+  linkType: hard
+
+"node-releases@npm:^2.0.21":
+  version: 2.0.23
+  resolution: "node-releases@npm:2.0.23"
+  checksum: 10c0/3fdcddb574a9d56c050469b027f3fd2b8830fd321edd12f34b862969b67d0a3d6713eb2af8916f91618d555354f6c7bd33ae39e3b37117b1e7ddf2e42bc3f4be
+  languageName: node
+  linkType: hard
+
+"nopt@npm:^7.0.0":
+  version: 7.2.1
+  resolution: "nopt@npm:7.2.1"
+  dependencies:
+    abbrev: "npm:^2.0.0"
+  bin:
+    nopt: bin/nopt.js
+  checksum: 10c0/a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81
+  languageName: node
+  linkType: hard
+
+"nopt@npm:^8.0.0":
+  version: 8.1.0
+  resolution: "nopt@npm:8.1.0"
+  dependencies:
+    abbrev: "npm:^3.0.0"
+  bin:
+    nopt: bin/nopt.js
+  checksum: 10c0/62e9ea70c7a3eb91d162d2c706b6606c041e4e7b547cbbb48f8b3695af457dd6479904d7ace600856bf923dd8d1ed0696f06195c8c20f02ac87c1da0e1d315ef
+  languageName: node
+  linkType: hard
+
+"normalize-path@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "normalize-path@npm:3.0.0"
+  checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046
+  languageName: node
+  linkType: hard
+
+"npm-run-path@npm:^4.0.1":
+  version: 4.0.1
+  resolution: "npm-run-path@npm:4.0.1"
+  dependencies:
+    path-key: "npm:^3.0.0"
+  checksum: 10c0/6f9353a95288f8455cf64cbeb707b28826a7f29690244c1e4bb61ec573256e021b6ad6651b394eb1ccfd00d6ec50147253aba2c5fe58a57ceb111fad62c519ac
+  languageName: node
+  linkType: hard
+
+"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
+  version: 1.4.0
+  resolution: "once@npm:1.4.0"
+  dependencies:
+    wrappy: "npm:1"
+  checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0
+  languageName: node
+  linkType: hard
+
+"onetime@npm:^5.1.2":
+  version: 5.1.2
+  resolution: "onetime@npm:5.1.2"
+  dependencies:
+    mimic-fn: "npm:^2.1.0"
+  checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f
+  languageName: node
+  linkType: hard
+
+"ordered-read-streams@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "ordered-read-streams@npm:2.0.0"
+  dependencies:
+    streamx: "npm:^2.12.5"
+  checksum: 10c0/4fa598c43cd2f6e9d49b8455955f0a2c29adff08ae3f982383439fd6a85700d8769c74b9ef88da52c6a1a1e73ae9601ea43afd039b9be37249600f4b8ada16c5
+  languageName: node
+  linkType: hard
+
+"p-limit@npm:^2.2.0":
+  version: 2.3.0
+  resolution: "p-limit@npm:2.3.0"
+  dependencies:
+    p-try: "npm:^2.0.0"
+  checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12
+  languageName: node
+  linkType: hard
+
+"p-limit@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "p-limit@npm:3.1.0"
+  dependencies:
+    yocto-queue: "npm:^0.1.0"
+  checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a
+  languageName: node
+  linkType: hard
+
+"p-locate@npm:^4.1.0":
+  version: 4.1.0
+  resolution: "p-locate@npm:4.1.0"
+  dependencies:
+    p-limit: "npm:^2.2.0"
+  checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9
+  languageName: node
+  linkType: hard
+
+"p-map@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "p-map@npm:4.0.0"
+  dependencies:
+    aggregate-error: "npm:^3.0.0"
+  checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75
+  languageName: node
+  linkType: hard
+
+"p-map@npm:^7.0.2":
+  version: 7.0.3
+  resolution: "p-map@npm:7.0.3"
+  checksum: 10c0/46091610da2b38ce47bcd1d8b4835a6fa4e832848a6682cf1652bc93915770f4617afc844c10a77d1b3e56d2472bb2d5622353fa3ead01a7f42b04fc8e744a5c
+  languageName: node
+  linkType: hard
+
+"p-try@npm:^2.0.0":
+  version: 2.2.0
+  resolution: "p-try@npm:2.2.0"
+  checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f
+  languageName: node
+  linkType: hard
+
+"package-json-from-dist@npm:^1.0.0":
+  version: 1.0.1
+  resolution: "package-json-from-dist@npm:1.0.1"
+  checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b
+  languageName: node
+  linkType: hard
+
+"parse-json@npm:^5.2.0":
+  version: 5.2.0
+  resolution: "parse-json@npm:5.2.0"
+  dependencies:
+    "@babel/code-frame": "npm:^7.0.0"
+    error-ex: "npm:^1.3.1"
+    json-parse-even-better-errors: "npm:^2.3.0"
+    lines-and-columns: "npm:^1.1.6"
+  checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585
+  languageName: node
+  linkType: hard
+
+"path-browserify@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "path-browserify@npm:1.0.1"
+  checksum: 10c0/8b8c3fd5c66bd340272180590ae4ff139769e9ab79522e2eb82e3d571a89b8117c04147f65ad066dccfb42fcad902e5b7d794b3d35e0fd840491a8ddbedf8c66
+  languageName: node
+  linkType: hard
+
+"path-exists@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "path-exists@npm:4.0.0"
+  checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b
+  languageName: node
+  linkType: hard
+
+"path-is-absolute@npm:^1.0.0":
+  version: 1.0.1
+  resolution: "path-is-absolute@npm:1.0.1"
+  checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078
+  languageName: node
+  linkType: hard
+
+"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
+  version: 3.1.1
+  resolution: "path-key@npm:3.1.1"
+  checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c
+  languageName: node
+  linkType: hard
+
+"path-parse@npm:^1.0.7":
+  version: 1.0.7
+  resolution: "path-parse@npm:1.0.7"
+  checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1
+  languageName: node
+  linkType: hard
+
+"path-scurry@npm:^1.11.1":
+  version: 1.11.1
+  resolution: "path-scurry@npm:1.11.1"
+  dependencies:
+    lru-cache: "npm:^10.2.0"
+    minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0"
+  checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d
+  languageName: node
+  linkType: hard
+
+"path-scurry@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "path-scurry@npm:2.0.0"
+  dependencies:
+    lru-cache: "npm:^11.0.0"
+    minipass: "npm:^7.1.2"
+  checksum: 10c0/3da4adedaa8e7ef8d6dc4f35a0ff8f05a9b4d8365f2b28047752b62d4c1ad73eec21e37b1579ef2d075920157856a3b52ae8309c480a6f1a8bbe06ff8e52b33c
+  languageName: node
+  linkType: hard
+
+"pathe@npm:^2.0.1, pathe@npm:^2.0.3":
+  version: 2.0.3
+  resolution: "pathe@npm:2.0.3"
+  checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1
+  languageName: node
+  linkType: hard
+
+"picocolors@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "picocolors@npm:1.1.1"
+  checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
+  languageName: node
+  linkType: hard
+
+"picomatch@npm:^2.0.4, picomatch@npm:^2.3.1":
+  version: 2.3.1
+  resolution: "picomatch@npm:2.3.1"
+  checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
+  languageName: node
+  linkType: hard
+
+"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3":
+  version: 4.0.3
+  resolution: "picomatch@npm:4.0.3"
+  checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2
+  languageName: node
+  linkType: hard
+
+"pirates@npm:^4.0.7":
+  version: 4.0.7
+  resolution: "pirates@npm:4.0.7"
+  checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a
+  languageName: node
+  linkType: hard
+
+"pkg-dir@npm:^4.2.0":
+  version: 4.2.0
+  resolution: "pkg-dir@npm:4.2.0"
+  dependencies:
+    find-up: "npm:^4.0.0"
+  checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728
+  languageName: node
+  linkType: hard
+
+"pkg-types@npm:^1.3.1":
+  version: 1.3.1
+  resolution: "pkg-types@npm:1.3.1"
+  dependencies:
+    confbox: "npm:^0.1.8"
+    mlly: "npm:^1.7.4"
+    pathe: "npm:^2.0.1"
+  checksum: 10c0/19e6cb8b66dcc66c89f2344aecfa47f2431c988cfa3366bdfdcfb1dd6695f87dcce37fbd90fe9d1605e2f4440b77f391e83c23255347c35cf84e7fd774d7fcea
+  languageName: node
+  linkType: hard
+
+"pkg-types@npm:^2.3.0":
+  version: 2.3.0
+  resolution: "pkg-types@npm:2.3.0"
+  dependencies:
+    confbox: "npm:^0.2.2"
+    exsolve: "npm:^1.0.7"
+    pathe: "npm:^2.0.3"
+  checksum: 10c0/d2bbddc5b81bd4741e1529c08ef4c5f1542bbdcf63498b73b8e1d84cff71806d1b8b1577800549bb569cb7aa20056257677b979bff48c97967cba7e64f72ae12
+  languageName: node
+  linkType: hard
+
+"postcss@npm:^8.5.6":
+  version: 8.5.6
+  resolution: "postcss@npm:8.5.6"
+  dependencies:
+    nanoid: "npm:^3.3.11"
+    picocolors: "npm:^1.1.1"
+    source-map-js: "npm:^1.2.1"
+  checksum: 10c0/5127cc7c91ed7a133a1b7318012d8bfa112da9ef092dddf369ae699a1f10ebbd89b1b9f25f3228795b84585c72aabd5ced5fc11f2ba467eedf7b081a66fad024
+  languageName: node
+  linkType: hard
+
+"prebuild-install@npm:^7.1.2":
+  version: 7.1.3
+  resolution: "prebuild-install@npm:7.1.3"
+  dependencies:
+    detect-libc: "npm:^2.0.0"
+    expand-template: "npm:^2.0.3"
+    github-from-package: "npm:0.0.0"
+    minimist: "npm:^1.2.3"
+    mkdirp-classic: "npm:^0.5.3"
+    napi-build-utils: "npm:^2.0.0"
+    node-abi: "npm:^3.3.0"
+    pump: "npm:^3.0.0"
+    rc: "npm:^1.2.7"
+    simple-get: "npm:^4.0.0"
+    tar-fs: "npm:^2.0.0"
+    tunnel-agent: "npm:^0.6.0"
+  bin:
+    prebuild-install: bin.js
+  checksum: 10c0/25919a42b52734606a4036ab492d37cfe8b601273d8dfb1fa3c84e141a0a475e7bad3ab848c741d2f810cef892fcf6059b8c7fe5b29f98d30e0c29ad009bedff
+  languageName: node
+  linkType: hard
+
+"pretty-format@npm:30.2.0, pretty-format@npm:^30.0.0":
+  version: 30.2.0
+  resolution: "pretty-format@npm:30.2.0"
+  dependencies:
+    "@jest/schemas": "npm:30.0.5"
+    ansi-styles: "npm:^5.2.0"
+    react-is: "npm:^18.3.1"
+  checksum: 10c0/8fdacfd281aa98124e5df80b2c17223fdcb84433876422b54863a6849381b3059eb42b9806d92d2853826bcb966bcb98d499bea5b1e912d869a3c3107fd38d35
+  languageName: node
+  linkType: hard
+
+"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0":
+  version: 4.2.0
+  resolution: "proc-log@npm:4.2.0"
+  checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9
+  languageName: node
+  linkType: hard
+
+"proc-log@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "proc-log@npm:5.0.0"
+  checksum: 10c0/bbe5edb944b0ad63387a1d5b1911ae93e05ce8d0f60de1035b218cdcceedfe39dbd2c697853355b70f1a090f8f58fe90da487c85216bf9671f9499d1a897e9e3
+  languageName: node
+  linkType: hard
+
+"promise-retry@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "promise-retry@npm:2.0.1"
+  dependencies:
+    err-code: "npm:^2.0.2"
+    retry: "npm:^0.12.0"
+  checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96
+  languageName: node
+  linkType: hard
+
+"pump@npm:^3.0.0":
+  version: 3.0.3
+  resolution: "pump@npm:3.0.3"
+  dependencies:
+    end-of-stream: "npm:^1.1.0"
+    once: "npm:^1.3.1"
+  checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9
+  languageName: node
+  linkType: hard
+
+"punycode@npm:^2.1.0":
+  version: 2.3.1
+  resolution: "punycode@npm:2.3.1"
+  checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9
+  languageName: node
+  linkType: hard
+
+"pure-rand@npm:^7.0.0":
+  version: 7.0.1
+  resolution: "pure-rand@npm:7.0.1"
+  checksum: 10c0/9cade41030f5ec95f5d55a11a71404cd6f46b69becaad892097cd7f58e2c6248cd0a933349ca7d21336ab629f1da42ffe899699b671bc4651600eaf6e57f837e
+  languageName: node
+  linkType: hard
+
+"quansync@npm:^0.2.11":
+  version: 0.2.11
+  resolution: "quansync@npm:0.2.11"
+  checksum: 10c0/cb9a1f8ebce074069f2f6a78578873ffedd9de9f6aa212039b44c0870955c04a71c3b1311b5d97f8ac2f2ec476de202d0a5c01160cb12bc0a11b7ef36d22ef56
+  languageName: node
+  linkType: hard
+
+"rc@npm:^1.2.7":
+  version: 1.2.8
+  resolution: "rc@npm:1.2.8"
+  dependencies:
+    deep-extend: "npm:^0.6.0"
+    ini: "npm:~1.3.0"
+    minimist: "npm:^1.2.0"
+    strip-json-comments: "npm:~2.0.1"
+  bin:
+    rc: ./cli.js
+  checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15
+  languageName: node
+  linkType: hard
+
+"react-is@npm:^18.3.1":
+  version: 18.3.1
+  resolution: "react-is@npm:18.3.1"
+  checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072
+  languageName: node
+  linkType: hard
+
+"readable-stream@npm:>=1.0.33-1 <1.1.0-0":
+  version: 1.0.34
+  resolution: "readable-stream@npm:1.0.34"
+  dependencies:
+    core-util-is: "npm:~1.0.0"
+    inherits: "npm:~2.0.1"
+    isarray: "npm:0.0.1"
+    string_decoder: "npm:~0.10.x"
+  checksum: 10c0/02272551396ed8930ddee1a088bdf0379f0f7cc47ac49ed8804e998076cb7daec9fbd2b1fd9c0490ec72e56e8bb3651abeb8080492b8e0a9c3f2158330908ed6
+  languageName: node
+  linkType: hard
+
+"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0":
+  version: 3.6.2
+  resolution: "readable-stream@npm:3.6.2"
+  dependencies:
+    inherits: "npm:^2.0.3"
+    string_decoder: "npm:^1.1.1"
+    util-deprecate: "npm:^1.0.1"
+  checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7
+  languageName: node
+  linkType: hard
+
+"require-directory@npm:^2.1.1":
+  version: 2.1.1
+  resolution: "require-directory@npm:2.1.1"
+  checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99
+  languageName: node
+  linkType: hard
+
+"require-from-string@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "require-from-string@npm:2.0.2"
+  checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2
+  languageName: node
+  linkType: hard
+
+"resolve-cwd@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "resolve-cwd@npm:3.0.0"
+  dependencies:
+    resolve-from: "npm:^5.0.0"
+  checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4
+  languageName: node
+  linkType: hard
+
+"resolve-from@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "resolve-from@npm:5.0.0"
+  checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2
+  languageName: node
+  linkType: hard
+
+"resolve@npm:~1.22.1, resolve@npm:~1.22.2":
+  version: 1.22.10
+  resolution: "resolve@npm:1.22.10"
+  dependencies:
+    is-core-module: "npm:^2.16.0"
+    path-parse: "npm:^1.0.7"
+    supports-preserve-symlinks-flag: "npm:^1.0.0"
+  bin:
+    resolve: bin/resolve
+  checksum: 10c0/8967e1f4e2cc40f79b7e080b4582b9a8c5ee36ffb46041dccb20e6461161adf69f843b43067b4a375de926a2cd669157e29a29578191def399dd5ef89a1b5203
+  languageName: node
+  linkType: hard
+
+"resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin":
+  version: 1.22.10
+  resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d"
+  dependencies:
+    is-core-module: "npm:^2.16.0"
+    path-parse: "npm:^1.0.7"
+    supports-preserve-symlinks-flag: "npm:^1.0.0"
+  bin:
+    resolve: bin/resolve
+  checksum: 10c0/52a4e505bbfc7925ac8f4cd91fd8c4e096b6a89728b9f46861d3b405ac9a1ccf4dcbf8befb4e89a2e11370dacd0160918163885cbc669369590f2f31f4c58939
+  languageName: node
+  linkType: hard
+
+"retry@npm:^0.12.0":
+  version: 0.12.0
+  resolution: "retry@npm:0.12.0"
+  checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe
+  languageName: node
+  linkType: hard
+
+"rimraf@npm:^6.0.1":
+  version: 6.0.1
+  resolution: "rimraf@npm:6.0.1"
+  dependencies:
+    glob: "npm:^11.0.0"
+    package-json-from-dist: "npm:^1.0.0"
+  bin:
+    rimraf: dist/esm/bin.mjs
+  checksum: 10c0/b30b6b072771f0d1e73b4ca5f37bb2944ee09375be9db5f558fcd3310000d29dfcfa93cf7734d75295ad5a7486dc8e40f63089ced1722a664539ffc0c3ece8c6
+  languageName: node
+  linkType: hard
+
+"rollup@npm:^4.43.0":
+  version: 4.52.4
+  resolution: "rollup@npm:4.52.4"
+  dependencies:
+    "@rollup/rollup-android-arm-eabi": "npm:4.52.4"
+    "@rollup/rollup-android-arm64": "npm:4.52.4"
+    "@rollup/rollup-darwin-arm64": "npm:4.52.4"
+    "@rollup/rollup-darwin-x64": "npm:4.52.4"
+    "@rollup/rollup-freebsd-arm64": "npm:4.52.4"
+    "@rollup/rollup-freebsd-x64": "npm:4.52.4"
+    "@rollup/rollup-linux-arm-gnueabihf": "npm:4.52.4"
+    "@rollup/rollup-linux-arm-musleabihf": "npm:4.52.4"
+    "@rollup/rollup-linux-arm64-gnu": "npm:4.52.4"
+    "@rollup/rollup-linux-arm64-musl": "npm:4.52.4"
+    "@rollup/rollup-linux-loong64-gnu": "npm:4.52.4"
+    "@rollup/rollup-linux-ppc64-gnu": "npm:4.52.4"
+    "@rollup/rollup-linux-riscv64-gnu": "npm:4.52.4"
+    "@rollup/rollup-linux-riscv64-musl": "npm:4.52.4"
+    "@rollup/rollup-linux-s390x-gnu": "npm:4.52.4"
+    "@rollup/rollup-linux-x64-gnu": "npm:4.52.4"
+    "@rollup/rollup-linux-x64-musl": "npm:4.52.4"
+    "@rollup/rollup-openharmony-arm64": "npm:4.52.4"
+    "@rollup/rollup-win32-arm64-msvc": "npm:4.52.4"
+    "@rollup/rollup-win32-ia32-msvc": "npm:4.52.4"
+    "@rollup/rollup-win32-x64-gnu": "npm:4.52.4"
+    "@rollup/rollup-win32-x64-msvc": "npm:4.52.4"
+    "@types/estree": "npm:1.0.8"
+    fsevents: "npm:~2.3.2"
+  dependenciesMeta:
+    "@rollup/rollup-android-arm-eabi":
+      optional: true
+    "@rollup/rollup-android-arm64":
+      optional: true
+    "@rollup/rollup-darwin-arm64":
+      optional: true
+    "@rollup/rollup-darwin-x64":
+      optional: true
+    "@rollup/rollup-freebsd-arm64":
+      optional: true
+    "@rollup/rollup-freebsd-x64":
+      optional: true
+    "@rollup/rollup-linux-arm-gnueabihf":
+      optional: true
+    "@rollup/rollup-linux-arm-musleabihf":
+      optional: true
+    "@rollup/rollup-linux-arm64-gnu":
+      optional: true
+    "@rollup/rollup-linux-arm64-musl":
+      optional: true
+    "@rollup/rollup-linux-loong64-gnu":
+      optional: true
+    "@rollup/rollup-linux-ppc64-gnu":
+      optional: true
+    "@rollup/rollup-linux-riscv64-gnu":
+      optional: true
+    "@rollup/rollup-linux-riscv64-musl":
+      optional: true
+    "@rollup/rollup-linux-s390x-gnu":
+      optional: true
+    "@rollup/rollup-linux-x64-gnu":
+      optional: true
+    "@rollup/rollup-linux-x64-musl":
+      optional: true
+    "@rollup/rollup-openharmony-arm64":
+      optional: true
+    "@rollup/rollup-win32-arm64-msvc":
+      optional: true
+    "@rollup/rollup-win32-ia32-msvc":
+      optional: true
+    "@rollup/rollup-win32-x64-gnu":
+      optional: true
+    "@rollup/rollup-win32-x64-msvc":
+      optional: true
+    fsevents:
+      optional: true
+  bin:
+    rollup: dist/bin/rollup
+  checksum: 10c0/aaec0f57e887d4fb37d152f93cf7133954eec79d11643e95de768ec9a377f08793b1745c648ca65a0dcc6c795c4d9ca398724d013e5745de270e88a543782aea
+  languageName: node
+  linkType: hard
+
+"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0":
+  version: 5.2.1
+  resolution: "safe-buffer@npm:5.2.1"
+  checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3
+  languageName: node
+  linkType: hard
+
+"safer-buffer@npm:>= 2.1.2 < 3.0.0":
+  version: 2.1.2
+  resolution: "safer-buffer@npm:2.1.2"
+  checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4
+  languageName: node
+  linkType: hard
+
+"semver@npm:^6.3.1":
+  version: 6.3.1
+  resolution: "semver@npm:6.3.1"
+  bin:
+    semver: bin/semver.js
+  checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d
+  languageName: node
+  linkType: hard
+
+"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.2":
+  version: 7.7.2
+  resolution: "semver@npm:7.7.2"
+  bin:
+    semver: bin/semver.js
+  checksum: 10c0/aca305edfbf2383c22571cb7714f48cadc7ac95371b4b52362fb8eeffdfbc0de0669368b82b2b15978f8848f01d7114da65697e56cd8c37b0dab8c58e543f9ea
+  languageName: node
+  linkType: hard
+
+"semver@npm:~7.5.4":
+  version: 7.5.4
+  resolution: "semver@npm:7.5.4"
+  dependencies:
+    lru-cache: "npm:^6.0.0"
+  bin:
+    semver: bin/semver.js
+  checksum: 10c0/5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e
+  languageName: node
+  linkType: hard
+
+"shebang-command@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "shebang-command@npm:2.0.0"
+  dependencies:
+    shebang-regex: "npm:^3.0.0"
+  checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e
+  languageName: node
+  linkType: hard
+
+"shebang-regex@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "shebang-regex@npm:3.0.0"
+  checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690
+  languageName: node
+  linkType: hard
+
+"signal-exit@npm:^3.0.3":
+  version: 3.0.7
+  resolution: "signal-exit@npm:3.0.7"
+  checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912
+  languageName: node
+  linkType: hard
+
+"signal-exit@npm:^4.0.1":
+  version: 4.1.0
+  resolution: "signal-exit@npm:4.1.0"
+  checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83
+  languageName: node
+  linkType: hard
+
+"simple-concat@npm:^1.0.0":
+  version: 1.0.1
+  resolution: "simple-concat@npm:1.0.1"
+  checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776
+  languageName: node
+  linkType: hard
+
+"simple-get@npm:^4.0.0":
+  version: 4.0.1
+  resolution: "simple-get@npm:4.0.1"
+  dependencies:
+    decompress-response: "npm:^6.0.0"
+    once: "npm:^1.3.1"
+    simple-concat: "npm:^1.0.0"
+  checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0
+  languageName: node
+  linkType: hard
+
+"slash@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "slash@npm:3.0.0"
+  checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b
+  languageName: node
+  linkType: hard
+
+"smart-buffer@npm:^4.2.0":
+  version: 4.2.0
+  resolution: "smart-buffer@npm:4.2.0"
+  checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539
+  languageName: node
+  linkType: hard
+
+"socks-proxy-agent@npm:^8.0.3":
+  version: 8.0.5
+  resolution: "socks-proxy-agent@npm:8.0.5"
+  dependencies:
+    agent-base: "npm:^7.1.2"
+    debug: "npm:^4.3.4"
+    socks: "npm:^2.8.3"
+  checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6
+  languageName: node
+  linkType: hard
+
+"socks@npm:^2.8.3":
+  version: 2.8.7
+  resolution: "socks@npm:2.8.7"
+  dependencies:
+    ip-address: "npm:^10.0.1"
+    smart-buffer: "npm:^4.2.0"
+  checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2
+  languageName: node
+  linkType: hard
+
+"source-map-js@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "source-map-js@npm:1.2.1"
+  checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf
+  languageName: node
+  linkType: hard
+
+"source-map-support@npm:0.5.13":
+  version: 0.5.13
+  resolution: "source-map-support@npm:0.5.13"
+  dependencies:
+    buffer-from: "npm:^1.0.0"
+    source-map: "npm:^0.6.0"
+  checksum: 10c0/137539f8c453fa0f496ea42049ab5da4569f96781f6ac8e5bfda26937be9494f4e8891f523c5f98f0e85f71b35d74127a00c46f83f6a4f54672b58d53202565e
+  languageName: node
+  linkType: hard
+
+"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1":
+  version: 0.6.1
+  resolution: "source-map@npm:0.6.1"
+  checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011
+  languageName: node
+  linkType: hard
+
+"sprintf-js@npm:~1.0.2":
+  version: 1.0.3
+  resolution: "sprintf-js@npm:1.0.3"
+  checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb
+  languageName: node
+  linkType: hard
+
+"ssri@npm:^10.0.0":
+  version: 10.0.6
+  resolution: "ssri@npm:10.0.6"
+  dependencies:
+    minipass: "npm:^7.0.3"
+  checksum: 10c0/e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227
+  languageName: node
+  linkType: hard
+
+"ssri@npm:^12.0.0":
+  version: 12.0.0
+  resolution: "ssri@npm:12.0.0"
+  dependencies:
+    minipass: "npm:^7.0.3"
+  checksum: 10c0/caddd5f544b2006e88fa6b0124d8d7b28208b83c72d7672d5ade44d794525d23b540f3396108c4eb9280dcb7c01f0bef50682f5b4b2c34291f7c5e211fd1417d
+  languageName: node
+  linkType: hard
+
+"stack-utils@npm:^2.0.6":
+  version: 2.0.6
+  resolution: "stack-utils@npm:2.0.6"
+  dependencies:
+    escape-string-regexp: "npm:^2.0.0"
+  checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a
+  languageName: node
+  linkType: hard
+
+"streamx@npm:^2.12.5":
+  version: 2.23.0
+  resolution: "streamx@npm:2.23.0"
+  dependencies:
+    events-universal: "npm:^1.0.0"
+    fast-fifo: "npm:^1.3.2"
+    text-decoder: "npm:^1.1.0"
+  checksum: 10c0/15708ce37818d588632fe1104e8febde573e33e8c0868bf583fce0703f3faf8d2a063c278e30df2270206811b69997f64eb78792099933a1fe757e786fbcbd44
+  languageName: node
+  linkType: hard
+
+"string-argv@npm:~0.3.1":
+  version: 0.3.2
+  resolution: "string-argv@npm:0.3.2"
+  checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82
+  languageName: node
+  linkType: hard
+
+"string-length@npm:^4.0.2":
+  version: 4.0.2
+  resolution: "string-length@npm:4.0.2"
+  dependencies:
+    char-regex: "npm:^1.0.2"
+    strip-ansi: "npm:^6.0.0"
+  checksum: 10c0/1cd77409c3d7db7bc59406f6bcc9ef0783671dcbabb23597a1177c166906ef2ee7c8290f78cae73a8aec858768f189d2cb417797df5e15ec4eb5e16b3346340c
+  languageName: node
+  linkType: hard
+
+"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
+  version: 4.2.3
+  resolution: "string-width@npm:4.2.3"
+  dependencies:
+    emoji-regex: "npm:^8.0.0"
+    is-fullwidth-code-point: "npm:^3.0.0"
+    strip-ansi: "npm:^6.0.1"
+  checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b
+  languageName: node
+  linkType: hard
+
+"string-width@npm:^5.0.1, string-width@npm:^5.1.2":
+  version: 5.1.2
+  resolution: "string-width@npm:5.1.2"
+  dependencies:
+    eastasianwidth: "npm:^0.2.0"
+    emoji-regex: "npm:^9.2.2"
+    strip-ansi: "npm:^7.0.1"
+  checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca
+  languageName: node
+  linkType: hard
+
+"string_decoder@npm:^1.1.1":
+  version: 1.3.0
+  resolution: "string_decoder@npm:1.3.0"
+  dependencies:
+    safe-buffer: "npm:~5.2.0"
+  checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d
+  languageName: node
+  linkType: hard
+
+"string_decoder@npm:~0.10.x":
+  version: 0.10.31
+  resolution: "string_decoder@npm:0.10.31"
+  checksum: 10c0/1c628d78f974aa7539c496029f48e7019acc32487fc695464f9d6bdfec98edd7d933a06b3216bc2016918f6e75074c611d84430a53cb0e43071597d6c1ac5e25
+  languageName: node
+  linkType: hard
+
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1":
+  version: 6.0.1
+  resolution: "strip-ansi@npm:6.0.1"
+  dependencies:
+    ansi-regex: "npm:^5.0.1"
+  checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952
+  languageName: node
+  linkType: hard
+
+"strip-ansi@npm:^7.0.1":
+  version: 7.1.2
+  resolution: "strip-ansi@npm:7.1.2"
+  dependencies:
+    ansi-regex: "npm:^6.0.1"
+  checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b
+  languageName: node
+  linkType: hard
+
+"strip-bom@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "strip-bom@npm:4.0.0"
+  checksum: 10c0/26abad1172d6bc48985ab9a5f96c21e440f6e7e476686de49be813b5a59b3566dccb5c525b831ec54fe348283b47f3ffb8e080bc3f965fde12e84df23f6bb7ef
+  languageName: node
+  linkType: hard
+
+"strip-final-newline@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "strip-final-newline@npm:2.0.0"
+  checksum: 10c0/bddf8ccd47acd85c0e09ad7375409d81653f645fda13227a9d459642277c253d877b68f2e5e4d819fe75733b0e626bac7e954c04f3236f6d196f79c94fa4a96f
+  languageName: node
+  linkType: hard
+
+"strip-json-comments@npm:^3.1.1, strip-json-comments@npm:~3.1.1":
+  version: 3.1.1
+  resolution: "strip-json-comments@npm:3.1.1"
+  checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd
+  languageName: node
+  linkType: hard
+
+"strip-json-comments@npm:~2.0.1":
+  version: 2.0.1
+  resolution: "strip-json-comments@npm:2.0.1"
+  checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43
+  languageName: node
+  linkType: hard
+
+"supports-color@npm:^7.1.0":
+  version: 7.2.0
+  resolution: "supports-color@npm:7.2.0"
+  dependencies:
+    has-flag: "npm:^4.0.0"
+  checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124
+  languageName: node
+  linkType: hard
+
+"supports-color@npm:^8.1.1, supports-color@npm:~8.1.1":
+  version: 8.1.1
+  resolution: "supports-color@npm:8.1.1"
+  dependencies:
+    has-flag: "npm:^4.0.0"
+  checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89
+  languageName: node
+  linkType: hard
+
+"supports-preserve-symlinks-flag@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
+  checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39
+  languageName: node
+  linkType: hard
+
+"synckit@npm:^0.11.8":
+  version: 0.11.11
+  resolution: "synckit@npm:0.11.11"
+  dependencies:
+    "@pkgr/core": "npm:^0.2.9"
+  checksum: 10c0/f0761495953d12d94a86edf6326b3a565496c72f9b94c02549b6961fb4d999f4ca316ce6b3eb8ed2e4bfc5056a8de65cda0bd03a233333a35221cd2fdc0e196b
+  languageName: node
+  linkType: hard
+
+"tar-fs@npm:^2.0.0":
+  version: 2.1.4
+  resolution: "tar-fs@npm:2.1.4"
+  dependencies:
+    chownr: "npm:^1.1.1"
+    mkdirp-classic: "npm:^0.5.2"
+    pump: "npm:^3.0.0"
+    tar-stream: "npm:^2.1.4"
+  checksum: 10c0/decb25acdc6839182c06ec83cba6136205bda1db984e120c8ffd0d80182bc5baa1d916f9b6c5c663ea3f9975b4dd49e3c6bb7b1707cbcdaba4e76042f43ec84c
+  languageName: node
+  linkType: hard
+
+"tar-stream@npm:^2.1.4":
+  version: 2.2.0
+  resolution: "tar-stream@npm:2.2.0"
+  dependencies:
+    bl: "npm:^4.0.3"
+    end-of-stream: "npm:^1.4.1"
+    fs-constants: "npm:^1.0.0"
+    inherits: "npm:^2.0.3"
+    readable-stream: "npm:^3.1.1"
+  checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692
+  languageName: node
+  linkType: hard
+
+"tar@npm:^6.1.11, tar@npm:^6.2.1":
+  version: 6.2.1
+  resolution: "tar@npm:6.2.1"
+  dependencies:
+    chownr: "npm:^2.0.0"
+    fs-minipass: "npm:^2.0.0"
+    minipass: "npm:^5.0.0"
+    minizlib: "npm:^2.1.1"
+    mkdirp: "npm:^1.0.3"
+    yallist: "npm:^4.0.0"
+  checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537
+  languageName: node
+  linkType: hard
+
+"tar@npm:^7.4.3":
+  version: 7.5.1
+  resolution: "tar@npm:7.5.1"
+  dependencies:
+    "@isaacs/fs-minipass": "npm:^4.0.0"
+    chownr: "npm:^3.0.0"
+    minipass: "npm:^7.1.2"
+    minizlib: "npm:^3.1.0"
+    yallist: "npm:^5.0.0"
+  checksum: 10c0/0dad0596a61586180981133b20c32cfd93c5863c5b7140d646714e6ea8ec84583b879e5dc3928a4d683be6e6109ad7ea3de1cf71986d5194f81b3a016c8858c9
+  languageName: node
+  linkType: hard
+
+"test-exclude@npm:^6.0.0":
+  version: 6.0.0
+  resolution: "test-exclude@npm:6.0.0"
+  dependencies:
+    "@istanbuljs/schema": "npm:^0.1.2"
+    glob: "npm:^7.1.4"
+    minimatch: "npm:^3.0.4"
+  checksum: 10c0/019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57
+  languageName: node
+  linkType: hard
+
+"text-decoder@npm:^1.1.0":
+  version: 1.2.3
+  resolution: "text-decoder@npm:1.2.3"
+  dependencies:
+    b4a: "npm:^1.6.4"
+  checksum: 10c0/569d776b9250158681c83656ef2c3e0a5d5c660c27ca69f87eedef921749a4fbf02095e5f9a0f862a25cf35258379b06e31dee9c125c9f72e273b7ca1a6d1977
+  languageName: node
+  linkType: hard
+
+"through2@npm:^0.6.3":
+  version: 0.6.5
+  resolution: "through2@npm:0.6.5"
+  dependencies:
+    readable-stream: "npm:>=1.0.33-1 <1.1.0-0"
+    xtend: "npm:>=4.0.0 <4.1.0-0"
+  checksum: 10c0/3294325d73b120ffbb8cd00e28a649a99e194cef2638bf782b6c2eb0c163b388f7b7bb908003949f58f9f6b8f771defd24b6e4df051eb410fd87931521963b98
+  languageName: node
+  linkType: hard
+
+"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15":
+  version: 0.2.15
+  resolution: "tinyglobby@npm:0.2.15"
+  dependencies:
+    fdir: "npm:^6.5.0"
+    picomatch: "npm:^4.0.3"
+  checksum: 10c0/869c31490d0d88eedb8305d178d4c75e7463e820df5a9b9d388291daf93e8b1eb5de1dad1c1e139767e4269fe75f3b10d5009b2cc14db96ff98986920a186844
+  languageName: node
+  linkType: hard
+
+"tmpl@npm:1.0.5":
+  version: 1.0.5
+  resolution: "tmpl@npm:1.0.5"
+  checksum: 10c0/f935537799c2d1922cb5d6d3805f594388f75338fe7a4a9dac41504dd539704ca4db45b883b52e7b0aa5b2fd5ddadb1452bf95cd23a69da2f793a843f9451cc9
+  languageName: node
+  linkType: hard
+
+"to-regex-range@npm:^5.0.1":
+  version: 5.0.1
+  resolution: "to-regex-range@npm:5.0.1"
+  dependencies:
+    is-number: "npm:^7.0.0"
+  checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892
+  languageName: node
+  linkType: hard
+
 "torch@workspace:.":
   version: 0.0.0-use.local
   resolution: "torch@workspace:."
+  dependencies:
+    "@types/jest": "npm:^30.0.0"
+    "@types/node": "npm:^24.6.2"
+    "@veehz/gpu.js": "npm:^2.16.0"
+    jest: "npm:^30.2.0"
+    jest-util: "npm:^30.2.0"
+    rimraf: "npm:^6.0.1"
+    ts-jest: "npm:^29.4.4"
+    ts-node: "npm:^10.9.2"
+    typescript: "npm:^5.9.3"
+    vite: "npm:^7.1.9"
+    vite-plugin-dts: "npm:^4.5.4"
   languageName: unknown
   linkType: soft
+
+"ts-jest@npm:^29.4.4":
+  version: 29.4.4
+  resolution: "ts-jest@npm:29.4.4"
+  dependencies:
+    bs-logger: "npm:^0.2.6"
+    fast-json-stable-stringify: "npm:^2.1.0"
+    handlebars: "npm:^4.7.8"
+    json5: "npm:^2.2.3"
+    lodash.memoize: "npm:^4.1.2"
+    make-error: "npm:^1.3.6"
+    semver: "npm:^7.7.2"
+    type-fest: "npm:^4.41.0"
+    yargs-parser: "npm:^21.1.1"
+  peerDependencies:
+    "@babel/core": ">=7.0.0-beta.0 <8"
+    "@jest/transform": ^29.0.0 || ^30.0.0
+    "@jest/types": ^29.0.0 || ^30.0.0
+    babel-jest: ^29.0.0 || ^30.0.0
+    jest: ^29.0.0 || ^30.0.0
+    jest-util: ^29.0.0 || ^30.0.0
+    typescript: ">=4.3 <6"
+  peerDependenciesMeta:
+    "@babel/core":
+      optional: true
+    "@jest/transform":
+      optional: true
+    "@jest/types":
+      optional: true
+    babel-jest:
+      optional: true
+    esbuild:
+      optional: true
+    jest-util:
+      optional: true
+  bin:
+    ts-jest: cli.js
+  checksum: 10c0/f99d612704cda98369f4a54d3db771bad5edd1390fded4f1691f3182f0c8ce8b7f827e5846952bd8bcd26df26c9fb18f11089de760956bdf357875a5f1d49fcc
+  languageName: node
+  linkType: hard
+
+"ts-node@npm:^10.9.2":
+  version: 10.9.2
+  resolution: "ts-node@npm:10.9.2"
+  dependencies:
+    "@cspotcode/source-map-support": "npm:^0.8.0"
+    "@tsconfig/node10": "npm:^1.0.7"
+    "@tsconfig/node12": "npm:^1.0.7"
+    "@tsconfig/node14": "npm:^1.0.0"
+    "@tsconfig/node16": "npm:^1.0.2"
+    acorn: "npm:^8.4.1"
+    acorn-walk: "npm:^8.1.1"
+    arg: "npm:^4.1.0"
+    create-require: "npm:^1.1.0"
+    diff: "npm:^4.0.1"
+    make-error: "npm:^1.1.1"
+    v8-compile-cache-lib: "npm:^3.0.1"
+    yn: "npm:3.1.1"
+  peerDependencies:
+    "@swc/core": ">=1.2.50"
+    "@swc/wasm": ">=1.2.50"
+    "@types/node": "*"
+    typescript: ">=2.7"
+  peerDependenciesMeta:
+    "@swc/core":
+      optional: true
+    "@swc/wasm":
+      optional: true
+  bin:
+    ts-node: dist/bin.js
+    ts-node-cwd: dist/bin-cwd.js
+    ts-node-esm: dist/bin-esm.js
+    ts-node-script: dist/bin-script.js
+    ts-node-transpile-only: dist/bin-transpile.js
+    ts-script: dist/bin-script-deprecated.js
+  checksum: 10c0/5f29938489f96982a25ba650b64218e83a3357d76f7bede80195c65ab44ad279c8357264639b7abdd5d7e75fc269a83daa0e9c62fd8637a3def67254ecc9ddc2
+  languageName: node
+  linkType: hard
+
+"tslib@npm:^2.4.0":
+  version: 2.8.1
+  resolution: "tslib@npm:2.8.1"
+  checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
+  languageName: node
+  linkType: hard
+
+"tunnel-agent@npm:^0.6.0":
+  version: 0.6.0
+  resolution: "tunnel-agent@npm:0.6.0"
+  dependencies:
+    safe-buffer: "npm:^5.0.1"
+  checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a
+  languageName: node
+  linkType: hard
+
+"type-detect@npm:4.0.8":
+  version: 4.0.8
+  resolution: "type-detect@npm:4.0.8"
+  checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd
+  languageName: node
+  linkType: hard
+
+"type-fest@npm:^0.21.3":
+  version: 0.21.3
+  resolution: "type-fest@npm:0.21.3"
+  checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8
+  languageName: node
+  linkType: hard
+
+"type-fest@npm:^4.41.0":
+  version: 4.41.0
+  resolution: "type-fest@npm:4.41.0"
+  checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4
+  languageName: node
+  linkType: hard
+
+"typescript@npm:5.8.2":
+  version: 5.8.2
+  resolution: "typescript@npm:5.8.2"
+  bin:
+    tsc: bin/tsc
+    tsserver: bin/tsserver
+  checksum: 10c0/5c4f6fbf1c6389b6928fe7b8fcd5dc73bb2d58cd4e3883f1d774ed5bd83b151cbac6b7ecf11723de56d4676daeba8713894b1e9af56174f2f9780ae7848ec3c6
+  languageName: node
+  linkType: hard
+
+"typescript@npm:^5.9.3":
+  version: 5.9.3
+  resolution: "typescript@npm:5.9.3"
+  bin:
+    tsc: bin/tsc
+    tsserver: bin/tsserver
+  checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5
+  languageName: node
+  linkType: hard
+
+"typescript@patch:typescript@npm%3A5.8.2#optional!builtin":
+  version: 5.8.2
+  resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin::version=5.8.2&hash=5786d5"
+  bin:
+    tsc: bin/tsc
+    tsserver: bin/tsserver
+  checksum: 10c0/5448a08e595cc558ab321e49d4cac64fb43d1fa106584f6ff9a8d8e592111b373a995a1d5c7f3046211c8a37201eb6d0f1566f15cdb7a62a5e3be01d087848e2
+  languageName: node
+  linkType: hard
+
+"typescript@patch:typescript@npm%3A^5.9.3#optional!builtin":
+  version: 5.9.3
+  resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5"
+  bin:
+    tsc: bin/tsc
+    tsserver: bin/tsserver
+  checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430
+  languageName: node
+  linkType: hard
+
+"ufo@npm:^1.6.1":
+  version: 1.6.1
+  resolution: "ufo@npm:1.6.1"
+  checksum: 10c0/5a9f041e5945fba7c189d5410508cbcbefef80b253ed29aa2e1f8a2b86f4bd51af44ee18d4485e6d3468c92be9bf4a42e3a2b72dcaf27ce39ce947ec994f1e6b
+  languageName: node
+  linkType: hard
+
+"uglify-js@npm:^3.1.4":
+  version: 3.19.3
+  resolution: "uglify-js@npm:3.19.3"
+  bin:
+    uglifyjs: bin/uglifyjs
+  checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479
+  languageName: node
+  linkType: hard
+
+"undici-types@npm:~7.13.0":
+  version: 7.13.0
+  resolution: "undici-types@npm:7.13.0"
+  checksum: 10c0/44bbb0935425291351bfd8039571f017295b5d6dc5727045d0a4fea8c6ffe73a6703b48ce010f9cb539b9041a75b463f8cfe1e7309cab7486452505fb0d66151
+  languageName: node
+  linkType: hard
+
+"unique-filename@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "unique-filename@npm:3.0.0"
+  dependencies:
+    unique-slug: "npm:^4.0.0"
+  checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f
+  languageName: node
+  linkType: hard
+
+"unique-filename@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "unique-filename@npm:4.0.0"
+  dependencies:
+    unique-slug: "npm:^5.0.0"
+  checksum: 10c0/38ae681cceb1408ea0587b6b01e29b00eee3c84baee1e41fd5c16b9ed443b80fba90c40e0ba69627e30855570a34ba8b06702d4a35035d4b5e198bf5a64c9ddc
+  languageName: node
+  linkType: hard
+
+"unique-slug@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "unique-slug@npm:4.0.0"
+  dependencies:
+    imurmurhash: "npm:^0.1.4"
+  checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635
+  languageName: node
+  linkType: hard
+
+"unique-slug@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "unique-slug@npm:5.0.0"
+  dependencies:
+    imurmurhash: "npm:^0.1.4"
+  checksum: 10c0/d324c5a44887bd7e105ce800fcf7533d43f29c48757ac410afd42975de82cc38ea2035c0483f4de82d186691bf3208ef35c644f73aa2b1b20b8e651be5afd293
+  languageName: node
+  linkType: hard
+
+"universalify@npm:^2.0.0":
+  version: 2.0.1
+  resolution: "universalify@npm:2.0.1"
+  checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a
+  languageName: node
+  linkType: hard
+
+"unrs-resolver@npm:^1.7.11":
+  version: 1.11.1
+  resolution: "unrs-resolver@npm:1.11.1"
+  dependencies:
+    "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1"
+    "@unrs/resolver-binding-android-arm64": "npm:1.11.1"
+    "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1"
+    "@unrs/resolver-binding-darwin-x64": "npm:1.11.1"
+    "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1"
+    "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1"
+    "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1"
+    "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1"
+    "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1"
+    "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1"
+    napi-postinstall: "npm:^0.3.0"
+  dependenciesMeta:
+    "@unrs/resolver-binding-android-arm-eabi":
+      optional: true
+    "@unrs/resolver-binding-android-arm64":
+      optional: true
+    "@unrs/resolver-binding-darwin-arm64":
+      optional: true
+    "@unrs/resolver-binding-darwin-x64":
+      optional: true
+    "@unrs/resolver-binding-freebsd-x64":
+      optional: true
+    "@unrs/resolver-binding-linux-arm-gnueabihf":
+      optional: true
+    "@unrs/resolver-binding-linux-arm-musleabihf":
+      optional: true
+    "@unrs/resolver-binding-linux-arm64-gnu":
+      optional: true
+    "@unrs/resolver-binding-linux-arm64-musl":
+      optional: true
+    "@unrs/resolver-binding-linux-ppc64-gnu":
+      optional: true
+    "@unrs/resolver-binding-linux-riscv64-gnu":
+      optional: true
+    "@unrs/resolver-binding-linux-riscv64-musl":
+      optional: true
+    "@unrs/resolver-binding-linux-s390x-gnu":
+      optional: true
+    "@unrs/resolver-binding-linux-x64-gnu":
+      optional: true
+    "@unrs/resolver-binding-linux-x64-musl":
+      optional: true
+    "@unrs/resolver-binding-wasm32-wasi":
+      optional: true
+    "@unrs/resolver-binding-win32-arm64-msvc":
+      optional: true
+    "@unrs/resolver-binding-win32-ia32-msvc":
+      optional: true
+    "@unrs/resolver-binding-win32-x64-msvc":
+      optional: true
+  checksum: 10c0/c91b112c71a33d6b24e5c708dab43ab80911f2df8ee65b87cd7a18fb5af446708e98c4b415ca262026ad8df326debcc7ca6a801b2935504d87fd6f0b9d70dce1
+  languageName: node
+  linkType: hard
+
+"update-browserslist-db@npm:^1.1.3":
+  version: 1.1.3
+  resolution: "update-browserslist-db@npm:1.1.3"
+  dependencies:
+    escalade: "npm:^3.2.0"
+    picocolors: "npm:^1.1.1"
+  peerDependencies:
+    browserslist: ">= 4.21.0"
+  bin:
+    update-browserslist-db: cli.js
+  checksum: 10c0/682e8ecbf9de474a626f6462aa85927936cdd256fe584c6df2508b0df9f7362c44c957e9970df55dfe44d3623807d26316ea2c7d26b80bb76a16c56c37233c32
+  languageName: node
+  linkType: hard
+
+"uri-js@npm:^4.2.2, uri-js@npm:^4.4.1":
+  version: 4.4.1
+  resolution: "uri-js@npm:4.4.1"
+  dependencies:
+    punycode: "npm:^2.1.0"
+  checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c
+  languageName: node
+  linkType: hard
+
+"util-deprecate@npm:^1.0.1":
+  version: 1.0.2
+  resolution: "util-deprecate@npm:1.0.2"
+  checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942
+  languageName: node
+  linkType: hard
+
+"v8-compile-cache-lib@npm:^3.0.1":
+  version: 3.0.1
+  resolution: "v8-compile-cache-lib@npm:3.0.1"
+  checksum: 10c0/bdc36fb8095d3b41df197f5fb6f11e3a26adf4059df3213e3baa93810d8f0cc76f9a74aaefc18b73e91fe7e19154ed6f134eda6fded2e0f1c8d2272ed2d2d391
+  languageName: node
+  linkType: hard
+
+"v8-to-istanbul@npm:^9.0.1":
+  version: 9.3.0
+  resolution: "v8-to-istanbul@npm:9.3.0"
+  dependencies:
+    "@jridgewell/trace-mapping": "npm:^0.3.12"
+    "@types/istanbul-lib-coverage": "npm:^2.0.1"
+    convert-source-map: "npm:^2.0.0"
+  checksum: 10c0/968bcf1c7c88c04df1ffb463c179558a2ec17aa49e49376120504958239d9e9dad5281aa05f2a78542b8557f2be0b0b4c325710262f3b838b40d703d5ed30c23
+  languageName: node
+  linkType: hard
+
+"vite-plugin-dts@npm:^4.5.4":
+  version: 4.5.4
+  resolution: "vite-plugin-dts@npm:4.5.4"
+  dependencies:
+    "@microsoft/api-extractor": "npm:^7.50.1"
+    "@rollup/pluginutils": "npm:^5.1.4"
+    "@volar/typescript": "npm:^2.4.11"
+    "@vue/language-core": "npm:2.2.0"
+    compare-versions: "npm:^6.1.1"
+    debug: "npm:^4.4.0"
+    kolorist: "npm:^1.8.0"
+    local-pkg: "npm:^1.0.0"
+    magic-string: "npm:^0.30.17"
+  peerDependencies:
+    typescript: "*"
+    vite: "*"
+  peerDependenciesMeta:
+    vite:
+      optional: true
+  checksum: 10c0/5fcb7f3739d115f36195a692c0e9f9fca4e504bbbbabe29e71ee06630dd05ea2920169371e80e548eb4779d2eca14107277497838d7df588d53e1fadf84be861
+  languageName: node
+  linkType: hard
+
+"vite@npm:^7.1.9":
+  version: 7.1.9
+  resolution: "vite@npm:7.1.9"
+  dependencies:
+    esbuild: "npm:^0.25.0"
+    fdir: "npm:^6.5.0"
+    fsevents: "npm:~2.3.3"
+    picomatch: "npm:^4.0.3"
+    postcss: "npm:^8.5.6"
+    rollup: "npm:^4.43.0"
+    tinyglobby: "npm:^0.2.15"
+  peerDependencies:
+    "@types/node": ^20.19.0 || >=22.12.0
+    jiti: ">=1.21.0"
+    less: ^4.0.0
+    lightningcss: ^1.21.0
+    sass: ^1.70.0
+    sass-embedded: ^1.70.0
+    stylus: ">=0.54.8"
+    sugarss: ^5.0.0
+    terser: ^5.16.0
+    tsx: ^4.8.1
+    yaml: ^2.4.2
+  dependenciesMeta:
+    fsevents:
+      optional: true
+  peerDependenciesMeta:
+    "@types/node":
+      optional: true
+    jiti:
+      optional: true
+    less:
+      optional: true
+    lightningcss:
+      optional: true
+    sass:
+      optional: true
+    sass-embedded:
+      optional: true
+    stylus:
+      optional: true
+    sugarss:
+      optional: true
+    terser:
+      optional: true
+    tsx:
+      optional: true
+    yaml:
+      optional: true
+  bin:
+    vite: bin/vite.js
+  checksum: 10c0/f628f903a137c1410232558bde99c223ea00a090bda6af77752c61f912955f0050aac12d3cfe024d08a0f150ff6fab61b3d0be75d634a59b94d49f525392e1f7
+  languageName: node
+  linkType: hard
+
+"vscode-uri@npm:^3.0.8":
+  version: 3.1.0
+  resolution: "vscode-uri@npm:3.1.0"
+  checksum: 10c0/5f6c9c10fd9b1664d71fab4e9fbbae6be93c7f75bb3a1d9d74399a88ab8649e99691223fd7cef4644376cac6e94fa2c086d802521b9a8e31c5af3e60f0f35624
+  languageName: node
+  linkType: hard
+
+"walker@npm:^1.0.8":
+  version: 1.0.8
+  resolution: "walker@npm:1.0.8"
+  dependencies:
+    makeerror: "npm:1.0.12"
+  checksum: 10c0/a17e037bccd3ca8a25a80cb850903facdfed0de4864bd8728f1782370715d679fa72e0a0f5da7c1c1379365159901e5935f35be531229da53bbfc0efdabdb48e
+  languageName: node
+  linkType: hard
+
+"webgpu@npm:0.2.9":
+  version: 0.2.9
+  resolution: "webgpu@npm:0.2.9"
+  dependencies:
+    "@webgpu/types": "npm:^0.1.54"
+  checksum: 10c0/048e31afd7ac7b720aec50cf6cb1cfc4921e35d68f8c4031cf7b38764c4b9bdeca4b6be62a8e439ceb277c7cf3daa0bfb5539c3e93431f0b67c37daf706e9a96
+  languageName: node
+  linkType: hard
+
+"which@npm:^2.0.1":
+  version: 2.0.2
+  resolution: "which@npm:2.0.2"
+  dependencies:
+    isexe: "npm:^2.0.0"
+  bin:
+    node-which: ./bin/node-which
+  checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f
+  languageName: node
+  linkType: hard
+
+"which@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "which@npm:4.0.0"
+  dependencies:
+    isexe: "npm:^3.1.1"
+  bin:
+    node-which: bin/which.js
+  checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a
+  languageName: node
+  linkType: hard
+
+"which@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "which@npm:5.0.0"
+  dependencies:
+    isexe: "npm:^3.1.1"
+  bin:
+    node-which: bin/which.js
+  checksum: 10c0/e556e4cd8b7dbf5df52408c9a9dd5ac6518c8c5267c8953f5b0564073c66ed5bf9503b14d876d0e9c7844d4db9725fb0dcf45d6e911e17e26ab363dc3965ae7b
+  languageName: node
+  linkType: hard
+
+"wordwrap@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "wordwrap@npm:1.0.0"
+  checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92
+  languageName: node
+  linkType: hard
+
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0":
+  version: 7.0.0
+  resolution: "wrap-ansi@npm:7.0.0"
+  dependencies:
+    ansi-styles: "npm:^4.0.0"
+    string-width: "npm:^4.1.0"
+    strip-ansi: "npm:^6.0.0"
+  checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da
+  languageName: node
+  linkType: hard
+
+"wrap-ansi@npm:^8.1.0":
+  version: 8.1.0
+  resolution: "wrap-ansi@npm:8.1.0"
+  dependencies:
+    ansi-styles: "npm:^6.1.0"
+    string-width: "npm:^5.0.1"
+    strip-ansi: "npm:^7.0.1"
+  checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60
+  languageName: node
+  linkType: hard
+
+"wrappy@npm:1":
+  version: 1.0.2
+  resolution: "wrappy@npm:1.0.2"
+  checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0
+  languageName: node
+  linkType: hard
+
+"write-file-atomic@npm:^5.0.1":
+  version: 5.0.1
+  resolution: "write-file-atomic@npm:5.0.1"
+  dependencies:
+    imurmurhash: "npm:^0.1.4"
+    signal-exit: "npm:^4.0.1"
+  checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d
+  languageName: node
+  linkType: hard
+
+"xtend@npm:>=4.0.0 <4.1.0-0":
+  version: 4.0.2
+  resolution: "xtend@npm:4.0.2"
+  checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e
+  languageName: node
+  linkType: hard
+
+"y18n@npm:^5.0.5":
+  version: 5.0.8
+  resolution: "y18n@npm:5.0.8"
+  checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249
+  languageName: node
+  linkType: hard
+
+"yallist@npm:^3.0.2":
+  version: 3.1.1
+  resolution: "yallist@npm:3.1.1"
+  checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1
+  languageName: node
+  linkType: hard
+
+"yallist@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "yallist@npm:4.0.0"
+  checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a
+  languageName: node
+  linkType: hard
+
+"yallist@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "yallist@npm:5.0.0"
+  checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416
+  languageName: node
+  linkType: hard
+
+"yargs-parser@npm:^21.1.1":
+  version: 21.1.1
+  resolution: "yargs-parser@npm:21.1.1"
+  checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2
+  languageName: node
+  linkType: hard
+
+"yargs@npm:^17.7.2":
+  version: 17.7.2
+  resolution: "yargs@npm:17.7.2"
+  dependencies:
+    cliui: "npm:^8.0.1"
+    escalade: "npm:^3.1.1"
+    get-caller-file: "npm:^2.0.5"
+    require-directory: "npm:^2.1.1"
+    string-width: "npm:^4.2.3"
+    y18n: "npm:^5.0.5"
+    yargs-parser: "npm:^21.1.1"
+  checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05
+  languageName: node
+  linkType: hard
+
+"yn@npm:3.1.1":
+  version: 3.1.1
+  resolution: "yn@npm:3.1.1"
+  checksum: 10c0/0732468dd7622ed8a274f640f191f3eaf1f39d5349a1b72836df484998d7d9807fbea094e2f5486d6b0cd2414aad5775972df0e68f8604db89a239f0f4bf7443
+  languageName: node
+  linkType: hard
+
+"yocto-queue@npm:^0.1.0":
+  version: 0.1.0
+  resolution: "yocto-queue@npm:0.1.0"
+  checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f
+  languageName: node
+  linkType: hard

From 8fa1abc0e7a174fbf9d5ed617f7b86bf4c794d0e Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 8 Oct 2025 14:03:02 +0800
Subject: [PATCH 003/128] feat: use with pyodide

---
 examples/pyodide/bridge.py  | 136 ++++++++++++++++++++++++++++++++++++
 examples/pyodide/index.html | 120 +++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+)
 create mode 100644 examples/pyodide/bridge.py
 create mode 100644 examples/pyodide/index.html

diff --git a/examples/pyodide/bridge.py b/examples/pyodide/bridge.py
new file mode 100644
index 00000000..caeb9cca
--- /dev/null
+++ b/examples/pyodide/bridge.py
@@ -0,0 +1,136 @@
+# This is a very rough draft.
+
+# assume js_torch is available
+from pyodide.ffi import JsProxy
+
+class Tensor:
+    # dealing with when .grad is None
+    def __new__(cls, data, requires_grad=False):
+        if(data is None):
+            return None
+        return super().__new__(cls)
+
+    def __init__(self, data, requires_grad=False):
+        # print(type(data))
+        # self.data = js_torch.tensor(data)
+        if isinstance(data, JsProxy):
+            self.data = data
+        else:
+            print("creating tensor from data", data)
+            self.data = torch_utils.create_tensor_from_python_data(data, requires_grad)
+            print("created tensor", self.tolist())
+            # print("created tensor", self.data._data)
+
+    def __repr__(self):
+        return f"Tensor(data={self.tolist()}{', requires_grad=True' if self.get_tensor().requires_grad else ''})"
+
+    def tolist(self):
+        return torch_utils.get_data_from_tensor(self.data).to_py()
+
+    def get_tensor(self):
+        return self.data
+
+    def backward(self):
+        self.get_tensor().backward()
+
+    @property
+    def grad(self):
+        return Tensor(self.get_tensor().grad)
+
+    @property
+    def shape(self):
+        return self.get_tensor().shape.to_py()
+
+    def item(self):
+        return self.get_tensor().item()
+
+    def sum(self, dim=-1, keepdim=False):
+        return Tensor(self.get_tensor().sum(dim, keepdim))
+
+    def zero_grad(self):
+        self.get_tensor().zero_grad()
+
+    def __try_op__(self, op, other, func):
+        other_data = other.get_tensor() if isinstance(other, Tensor) else other
+        return Tensor(func(self.get_tensor(), other_data))
+
+    def __add__(self, other):
+        return self.__try_op__("add", other, lambda a, b: a.add(b))
+
+    def __radd__(self, other):
+        return self.__try_op__("radd", other, lambda a, b: a.add(b))
+
+    def __mul__(self, other):
+        return self.__try_op__("mul", other, lambda a, b: a.mul(b))
+
+    def __rmul__(self, other):
+        return self.__try_op__("rmul", other, lambda a, b: a.mul(b))
+
+    def __truediv__(self, other):
+        return self.__try_op__("truediv", other, lambda a, b: a.div(b))
+
+    def __sub__(self, other):
+        return self.__try_op__("sub", other, lambda a, b: a.sub(b))
+
+    def __pow__(self, other):
+        return self.__try_op__("pow", other, lambda a, b: a.pow(b))
+
+    def __matmul__(self, other):
+        return self.__try_op__("matmul", other, lambda a, b: a.matmul(b))
+
+    # For when doing e.g. {a:.5f}
+    def __format__(self, format_spec):
+        return format(self.item(), format_spec)
+
+    def reshape(self, *args):
+        return Tensor(self.get_tensor().reshape(
+            torch_utils.to_js_list(args)
+        ))
+    
+    def allclose(self, other, rtol=1e-5, atol=1e-8, equal_nan=False):
+        return self.get_tensor().allclose(other.get_tensor(), rtol, atol, equal_nan)
+
+    # Make iterable so that can unpack
+    def __iter__(self):
+        return iter(self.tolist())
+
+    def __getattr__(self, name):
+        return lambda *args, **kwargs: Tensor(self.get_tensor().__getattribute__(name)(
+            *_transform_args(args),
+            *_transform_args(kwargs)
+        ))
+
+class _NoGrad:
+    def __enter__(self):
+        self.enabled = js_torch.getGradientTrackingEnabled()
+        js_torch.setGradientTrackingEnabled(False)
+
+    def __exit__(self, type, value, traceback):
+        js_torch.setGradientTrackingEnabled(self.enabled)
+
+class _Torch:
+    _operations = [
+        "sin", "mean", "square", "abs", "relu", "ones_like", "linspace", "ones",
+    ]
+
+    no_grad = _NoGrad
+
+    @property
+    def tensor(self):
+        return Tensor
+
+    def __getattr__(self, name):
+        return lambda *args, **kwargs: Tensor(js_torch.__getattribute__(name)(
+            *_transform_args(args),
+            *_transform_args(kwargs)
+        ))
+
+    def Size(self, shape):
+        return shape
+
+    def cat(self, tensors, dim=0):
+        return Tensor(js_torch.cat(torch_utils.to_js_list(list(map(lambda x: x.get_tensor(), tensors))), dim))
+
+
+# torch = lambda: None
+torch = _Torch()
\ No newline at end of file
diff --git a/examples/pyodide/index.html b/examples/pyodide/index.html
new file mode 100644
index 00000000..98d58cd4
--- /dev/null
+++ b/examples/pyodide/index.html
@@ -0,0 +1,120 @@
+
+
+
+
+    
+    
+    torch+pyodide browser backprop example
+    
+    
+    
+    
+
+
+
+    

Torch + Pyodide

+
+ +
+ +
+ + +
+
+

Output:

+

+    
+ + + + + + \ No newline at end of file From dd15d5adfc33e3dfff8cea88687d030e9a969fe7 Mon Sep 17 00:00:00 2001 From: veehz Date: Wed, 8 Oct 2025 14:23:45 +0800 Subject: [PATCH 004/128] refactor: rename files and internal functions, remove extraneous base tensor --- src/broadcasting.ts | 2 +- src/gpu.ts | 4 +-- src/index.ts | 10 +++---- src/operations/{function_base.ts => base.ts} | 0 src/operations/{basic.ts => classes.ts} | 28 ++++++++++---------- src/operations/registry.ts | 2 +- src/tensor.ts | 6 ++--- src/tensor_base.ts | 1 - 8 files changed, 25 insertions(+), 28 deletions(-) rename src/operations/{function_base.ts => base.ts} (100%) rename src/operations/{basic.ts => classes.ts} (90%) delete mode 100644 src/tensor_base.ts diff --git a/src/broadcasting.ts b/src/broadcasting.ts index e8ef6947..76d8bb7a 100644 --- a/src/broadcasting.ts +++ b/src/broadcasting.ts @@ -38,7 +38,7 @@ export function _get_original_index(original_shape: number[], new_shape: number[ } -export function _get_original_index_gpu(original_shape: number[], new_shape: number[], index: number): number { +export function _get_original_index_kernel(original_shape: number[], new_shape: number[], index: number): number { let original_index = 0; let cur_stride = 1; let temp_index = index; diff --git a/src/gpu.ts b/src/gpu.ts index 194f8bd5..fe55e1e6 100644 --- a/src/gpu.ts +++ b/src/gpu.ts @@ -4,11 +4,11 @@ */ import { GPU } from '@veehz/gpu.js'; -import { _get_original_index_gpu } from './broadcasting'; +import { _get_original_index_kernel } from './broadcasting'; const gpu = new GPU(); -gpu.addFunction(_get_original_index_gpu, { +gpu.addFunction(_get_original_index_kernel, { returnType: 'Integer', argumentTypes: { original_shape: 'Array', diff --git a/src/index.ts b/src/index.ts index e58b4e8e..ad73e946 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,16 +1,16 @@ import { registerOperation } from './operations/registry'; import { Tensor } from './tensor'; -import { Add, Div, Log, Mul, Pow, Sub, Sum } from './operations/basic'; +import { Add, Div, Log, Mul, Pow, Sub, Sum } from './operations/classes'; -import { _broadcast_shape, _get_original_index_gpu } from './broadcasting'; +import { _broadcast_shape, _get_original_index_kernel } from './broadcasting'; export { Tensor }; registerOperation('add', Add); +registerOperation('sub', Sub); registerOperation('mul', Mul); +registerOperation('div', Div); registerOperation('sum', Sum); -registerOperation('sub', Sub); registerOperation('pow', Pow); -registerOperation('log', Log); -registerOperation('div', Div); \ No newline at end of file +registerOperation('log', Log); \ No newline at end of file diff --git a/src/operations/function_base.ts b/src/operations/base.ts similarity index 100% rename from src/operations/function_base.ts rename to src/operations/base.ts diff --git a/src/operations/basic.ts b/src/operations/classes.ts similarity index 90% rename from src/operations/basic.ts rename to src/operations/classes.ts index 234d0faa..3cc89cd3 100644 --- a/src/operations/basic.ts +++ b/src/operations/classes.ts @@ -1,8 +1,8 @@ import gpu from "../gpu"; -import { _broadcast_shape, _get_original_index_gpu, _pad_shape } from "../broadcasting"; +import { _broadcast_shape, _get_original_index_kernel, _pad_shape } from "../broadcasting"; import { Tensor } from "../tensor"; // import * as utils from "../utils"; -import { Operation, BinaryOperation, UnaryOperation } from "./function_base"; +import { Operation, BinaryOperation, UnaryOperation } from "./base"; /* This did not work as it doesn't support dynamic function registration */ // export function _broadcast_operation( @@ -68,12 +68,12 @@ export function _add_broadcast( b_shape: number[], broadcast_shape: number[] ) { - const a_index = _get_original_index_gpu( + const a_index = _get_original_index_kernel( a_shape, broadcast_shape, this.thread.x ); - const b_index = _get_original_index_gpu( + const b_index = _get_original_index_kernel( b_shape, broadcast_shape, this.thread.x @@ -132,8 +132,8 @@ export function _add_tensor( bs: number[], bcs: number[] ) { - const a_index = _get_original_index_gpu(as, bcs, this.thread.x); - const b_index = _get_original_index_gpu(bs, bcs, this.thread.x); + const a_index = _get_original_index_kernel(as, bcs, this.thread.x); + const b_index = _get_original_index_kernel(bs, bcs, this.thread.x); return a[a_index] + b[b_index]; }, @@ -182,8 +182,8 @@ export function _sub_tensor( bs: number[], bcs: number[] ) { - const a_index = _get_original_index_gpu(as, bcs, this.thread.x); - const b_index = _get_original_index_gpu(bs, bcs, this.thread.x); + const a_index = _get_original_index_kernel(as, bcs, this.thread.x); + const b_index = _get_original_index_kernel(bs, bcs, this.thread.x); return a[a_index] - b[b_index]; }, @@ -231,8 +231,8 @@ export function _mul_tensor( bs: number[], bcs: number[] ) { - const a_index = _get_original_index_gpu(as, bcs, this.thread.x); - const b_index = _get_original_index_gpu(bs, bcs, this.thread.x); + const a_index = _get_original_index_kernel(as, bcs, this.thread.x); + const b_index = _get_original_index_kernel(bs, bcs, this.thread.x); return a[a_index] * b[b_index]; }, @@ -280,8 +280,8 @@ export function _div_tensor( bs: number[], bcs: number[] ) { - const a_index = _get_original_index_gpu(as, bcs, this.thread.x); - const b_index = _get_original_index_gpu(bs, bcs, this.thread.x); + const a_index = _get_original_index_kernel(as, bcs, this.thread.x); + const b_index = _get_original_index_kernel(bs, bcs, this.thread.x); return a[a_index] / b[b_index]; }, @@ -347,8 +347,8 @@ export function _pow_tensor( bs: number[], bcs: number[] ) { - const a_index = _get_original_index_gpu(as, bcs, this.thread.x); - const b_index = _get_original_index_gpu(bs, bcs, this.thread.x); + const a_index = _get_original_index_kernel(as, bcs, this.thread.x); + const b_index = _get_original_index_kernel(bs, bcs, this.thread.x); return Math.pow(a[a_index], b[b_index]); }, diff --git a/src/operations/registry.ts b/src/operations/registry.ts index 91a0a9da..f4772ffb 100644 --- a/src/operations/registry.ts +++ b/src/operations/registry.ts @@ -1,4 +1,4 @@ -import { Operation, OperationConstructor } from "./function_base"; +import { Operation, OperationConstructor } from "./base"; // Only allow registering concrete, constructible Operation classes const operations = new Map(); diff --git a/src/tensor.ts b/src/tensor.ts index 0b1a0fe7..42972d13 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,7 +1,6 @@ import { _get_original_index } from "./broadcasting"; -import { Operation } from "./operations/function_base"; +import { Operation } from "./operations/base"; import { getOperation } from "./operations/registry"; -import { TensorBase } from "./tensor_base"; /* * TODO: @@ -44,7 +43,7 @@ function _flatten(data: NestedNumberArray): number[] { } } -export class Tensor extends TensorBase { +export class Tensor { data: number[]; _shape: number[]; operation: any = null; @@ -57,7 +56,6 @@ export class Tensor extends TensorBase { options: { requires_grad?: boolean } = {}, internal_options: { operation?: Operation, shape?: number[] } = {} ) { - super(); this.data = _flatten(data); this.requires_grad = options.requires_grad ?? false; diff --git a/src/tensor_base.ts b/src/tensor_base.ts deleted file mode 100644 index d35a4498..00000000 --- a/src/tensor_base.ts +++ /dev/null @@ -1 +0,0 @@ -export class TensorBase {} \ No newline at end of file From e56e6a084930bbffc65e4d04dc090952f3a0c94a Mon Sep 17 00:00:00 2001 From: veehz Date: Wed, 8 Oct 2025 14:25:32 +0800 Subject: [PATCH 005/128] feat: functional --- src/index.ts | 1 + src/operations/functional.ts | 37 ++++++++++++++++++++++++ test/functional.test.ts | 55 ++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 src/operations/functional.ts create mode 100644 test/functional.test.ts diff --git a/src/index.ts b/src/index.ts index ad73e946..eeae0488 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ import { Add, Div, Log, Mul, Pow, Sub, Sum } from './operations/classes'; import { _broadcast_shape, _get_original_index_kernel } from './broadcasting'; +export * from './operations/functional'; export { Tensor }; registerOperation('add', Add); diff --git a/src/operations/functional.ts b/src/operations/functional.ts new file mode 100644 index 00000000..7fe40229 --- /dev/null +++ b/src/operations/functional.ts @@ -0,0 +1,37 @@ +import { Tensor } from "../tensor"; +import { getOperation } from "./registry"; + +export function add(a: Tensor, b: Tensor): Tensor { + const operation = new (getOperation("add"))(); + return operation.forward(a, b); +} + +export function sub(a: Tensor, b: Tensor): Tensor { + const operation = new (getOperation("sub"))(); + return operation.forward(a, b); +} + +export function mul(a: Tensor, b: Tensor): Tensor { + const operation = new (getOperation("mul"))(); + return operation.forward(a, b); +} + +export function div(a: Tensor, b: Tensor): Tensor { + const operation = new (getOperation("div"))(); + return operation.forward(a, b); +} + +export function sum(a: Tensor): Tensor { + const operation = new (getOperation("sum"))(); + return operation.forward(a); +} + +export function pow(a: Tensor, b: Tensor): Tensor { + const operation = new (getOperation("pow"))(); + return operation.forward(a, b); +} + +export function log(a: Tensor): Tensor { + const operation = new (getOperation("log"))(); + return operation.forward(a); +} \ No newline at end of file diff --git a/test/functional.test.ts b/test/functional.test.ts new file mode 100644 index 00000000..26281091 --- /dev/null +++ b/test/functional.test.ts @@ -0,0 +1,55 @@ +import * as torch from "../src/index"; +import { Tensor } from "../src/index"; + +describe("Functional", () => { + describe("Addition", () => { + test("should add two tensors with same shape", () => { + const t1 = new Tensor([10]); + const t2 = new Tensor([20]); + const result = torch.add(t1, t2); + + expect(Array.from(result.data)).toEqual([30]); + expect(result.shape).toEqual([1]); + }); + + test("should add tensors with different shapes (broadcasting)", () => { + const t1 = new Tensor([10, 20, 30]); + const t2 = new Tensor([1]); + const result = torch.add(t1, t2); + + expect(Array.from(result.data)).toEqual([11, 21, 31]); + expect(result.shape).toEqual([3]); + }); + + test("should add two 1D tensors of same length", () => { + const t1 = new Tensor([1, 2, 3]); + const t2 = new Tensor([4, 5, 6]); + const result = torch.add(t1, t2); + + expect(Array.from(result.data)).toEqual([5, 7, 9]); + expect(result.shape).toEqual([3]); + }); + }); + + describe("Multiplication", () => { + test("should multiply two tensors with same shape", () => { + const t1 = new Tensor([10]); + const t2 = new Tensor([20]); + const result = torch.mul(t1, t2); + + expect(Array.from(result.data)).toEqual([200]); + expect(result.shape).toEqual([1]); + }); + }); + + describe("should multiply tensors with different shapes (broadcasting)", () => { + test("should multiply two tensors with different shapes (broadcasting)", () => { + const t1 = new Tensor([10, 20, 30]); + const t2 = new Tensor([1]); + const result = torch.mul(t1, t2); + + expect(Array.from(result.data)).toEqual([10, 20, 30]); + expect(result.shape).toEqual([3]); + }); + }); +}); From eaa0598d7409f67cac7b80bfadc58eec2321bedf Mon Sep 17 00:00:00 2001 From: veehz Date: Wed, 8 Oct 2025 14:30:43 +0800 Subject: [PATCH 006/128] feat: github workflow test --- .github/workflows/push.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/push.yml diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 00000000..707de9a8 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,29 @@ +name: test-on-push + +on: [push] + +jobs: + test: + name: Verify all tests pass and build success + runs-on: ubuntu-latest + steps: + - name: Check out source code + uses: actions/checkout@v4 + + - name: Enable Corepack + run: corepack enable + + - name: Use Node.js 💻 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + + - name: Install dependencies + run: yarn install --immutable + + - name: Build + run: yarn build + + - name: Test + run: yarn test From e6570ce391bd0747489b32f166a30bc77c7c7ab7 Mon Sep 17 00:00:00 2001 From: veehz Date: Wed, 8 Oct 2025 14:33:32 +0800 Subject: [PATCH 007/128] docs: pyodide instructions to run --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 85d2dda3..3e83fe2c 100644 --- a/README.md +++ b/README.md @@ -39,5 +39,6 @@ You can run `http-server` and load `examples/browser/index.html` to see how it w ```bash npx http-server --cors=* -c-1 . -# and navigate to http://localhost:8080/examples/browser/index.html +# and navigate to http://localhost:8080/examples/browser/index.html to run torch in js +# or http://localhost:8080/examples/pyodide/index.html to run in python ``` \ No newline at end of file From caa8c225015ae5721e9c37fdc5ce5e7c9bc0ede5 Mon Sep 17 00:00:00 2001 From: veehz Date: Wed, 8 Oct 2025 14:51:22 +0800 Subject: [PATCH 008/128] Add eslint and prettier --- .editorconfig | 13 +- .prettierrc | 8 + eslint.config.mjs | 15 + examples/browser/index.html | 4 +- package.json | 6 + src/broadcasting.ts | 88 +- src/gpu.ts | 13 +- src/index.ts | 4 +- src/operations/base.ts | 13 +- src/operations/classes.ts | 130 +-- src/operations/functional.ts | 34 +- src/operations/registry.ts | 2 +- src/tensor.ts | 30 +- src/utils.ts | 8 +- yarn.lock | 2056 +++++++++++++++++++++++++++++++++- 15 files changed, 2208 insertions(+), 216 deletions(-) create mode 100644 .prettierrc create mode 100644 eslint.config.mjs diff --git a/.editorconfig b/.editorconfig index 025dd8c8..a9fe88f6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,17 @@ root = true [*] -charset = utf-8 +insert_final_newline = true end_of_line = lf + +[*.{ts,tsx,json}] +indent_style = space +indent_size = 2 + +[*.md] +indent_style = space indent_size = 2 + +[*.{html,css}] indent_style = space -insert_final_newline = true +indent_size = 4 \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..00f0dc88 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "singleQuote": true, + "printWidth": 100, + "arrowParens": "avoid", + "trailingComma": "none", + "endOfLine": "auto" +} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..6f643f29 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,15 @@ +// @ts-check + +import eslint from '@eslint/js'; +import { defineConfig } from 'eslint/config'; +import tseslint from 'typescript-eslint'; + +export default defineConfig( + eslint.configs.recommended, + tseslint.configs.recommended, + { + rules: { + '@typescript-eslint/no-unused-vars': 'warn', // was error + }, + }, +); \ No newline at end of file diff --git a/examples/browser/index.html b/examples/browser/index.html index e21f2f1b..1fe3cc2b 100644 --- a/examples/browser/index.html +++ b/examples/browser/index.html @@ -1,5 +1,6 @@ + @@ -9,6 +10,7 @@ +

   
 
-
 
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 126081cc..db5ab478 100644
--- a/package.json
+++ b/package.json
@@ -29,14 +29,20 @@
     "test:watch": "jest --watch"
   },
   "devDependencies": {
+    "@eslint/js": "^9.37.0",
     "@types/jest": "^30.0.0",
     "@types/node": "^24.6.2",
+    "eslint": "^9.37.0",
+    "eslint-plugin-import": "^2.32.0",
+    "eslint-plugin-jest": "^29.0.1",
     "jest": "^30.2.0",
     "jest-util": "^30.2.0",
+    "prettier": "^3.6.2",
     "rimraf": "^6.0.1",
     "ts-jest": "^29.4.4",
     "ts-node": "^10.9.2",
     "typescript": "^5.9.3",
+    "typescript-eslint": "^8.46.0",
     "vite": "^7.1.9",
     "vite-plugin-dts": "^4.5.4"
   },
diff --git a/src/broadcasting.ts b/src/broadcasting.ts
index 76d8bb7a..f031ae1e 100644
--- a/src/broadcasting.ts
+++ b/src/broadcasting.ts
@@ -1,56 +1,66 @@
 // https://docs.pytorch.org/docs/stable/notes/broadcasting.html
 export function _broadcast_shape(a_shape: number[], b_shape: number[]): number[] {
-    const result_length = Math.max(a_shape.length, b_shape.length);
-    const padded_a_shape = [...Array(result_length - a_shape.length).fill(1), ...a_shape];
-    const padded_b_shape = [...Array(result_length - b_shape.length).fill(1), ...b_shape];
+  const result_length = Math.max(a_shape.length, b_shape.length);
+  const padded_a_shape = [...Array(result_length - a_shape.length).fill(1), ...a_shape];
+  const padded_b_shape = [...Array(result_length - b_shape.length).fill(1), ...b_shape];
 
-    let result_shape: number[] = [];
+  const result_shape: number[] = [];
 
-    for (let i = 0; i < result_length; i++) {
-        if (padded_a_shape[i] !== padded_b_shape[i] && padded_a_shape[i] !== 1 && padded_b_shape[i] !== 1) {
-            throw new Error(`Shape mismatch: ${a_shape} and ${b_shape}`);
-        }
-
-        result_shape.push(Math.max(padded_a_shape[i], padded_b_shape[i]));
+  for (let i = 0; i < result_length; i++) {
+    if (
+      padded_a_shape[i] !== padded_b_shape[i] &&
+      padded_a_shape[i] !== 1 &&
+      padded_b_shape[i] !== 1
+    ) {
+      throw new Error(`Shape mismatch: ${a_shape} and ${b_shape}`);
     }
 
-    return result_shape;
+    result_shape.push(Math.max(padded_a_shape[i], padded_b_shape[i]));
+  }
+
+  return result_shape;
 }
 
 export function _pad_shape(shape: number[], broadcast_shape: number[]): number[] {
-    return [...Array(broadcast_shape.length - shape.length).fill(1), ...shape];
+  return [...Array(broadcast_shape.length - shape.length).fill(1), ...shape];
 }
 
-export function _get_original_index(original_shape: number[], new_shape: number[], index: number): number {
-    let original_index = 0;
-    let cur_stride = 1;
-    let temp_index = index;
-
-    for (let i = original_shape.length - 1; i >= 0; i--) {
-        if(original_shape[i] > 1) {
-            const dim_index = Math.floor(temp_index % new_shape[i]);
-            original_index = original_index + (dim_index * cur_stride);
-        }
-        cur_stride *= original_shape[i];
-        temp_index = Math.floor(temp_index / new_shape[i]);
+export function _get_original_index(
+  original_shape: number[],
+  new_shape: number[],
+  index: number
+): number {
+  let original_index = 0;
+  let cur_stride = 1;
+  let temp_index = index;
+
+  for (let i = original_shape.length - 1; i >= 0; i--) {
+    if (original_shape[i] > 1) {
+      const dim_index = temp_index % new_shape[i];
+      original_index = original_index + dim_index * cur_stride;
     }
-    return original_index;
+    cur_stride *= original_shape[i];
+    temp_index = Math.floor(temp_index / new_shape[i]);
+  }
+  return original_index;
 }
 
+export function _get_original_index_kernel(
+  original_shape: number[],
+  new_shape: number[],
+  index: number
+): number {
+  let original_index = 0;
+  let cur_stride = 1;
+  let temp_index = index;
 
-export function _get_original_index_kernel(original_shape: number[], new_shape: number[], index: number): number {
-    let original_index = 0;
-    let cur_stride = 1;
-    let temp_index = index;
-
-    for (let i = this.constants.shape_length - 1; i >= 0; i--) {
-        if(original_shape[i] > 1) {
-            // const dim_index = temp_index % new_shape[i];
-            const dim_index = temp_index - new_shape[i] * Math.floor(temp_index / new_shape[i]);
-            original_index = original_index + (dim_index * cur_stride);
-        }
-        cur_stride = cur_stride * original_shape[i];
-        temp_index = Math.floor(temp_index / new_shape[i]);
+  for (let i = this.constants.shape_length - 1; i >= 0; i--) {
+    if (original_shape[i] > 1) {
+      const dim_index = temp_index % new_shape[i];
+      original_index = original_index + dim_index * cur_stride;
     }
-    return original_index;
+    cur_stride = cur_stride * original_shape[i];
+    temp_index = Math.floor(temp_index / new_shape[i]);
+  }
+  return original_index;
 }
diff --git a/src/gpu.ts b/src/gpu.ts
index fe55e1e6..fee81495 100644
--- a/src/gpu.ts
+++ b/src/gpu.ts
@@ -9,13 +9,12 @@ import { _get_original_index_kernel } from './broadcasting';
 const gpu = new GPU();
 
 gpu.addFunction(_get_original_index_kernel, {
-    returnType: 'Integer',
-    argumentTypes: {
-        original_shape: 'Array',
-        new_shape: 'Array',
-        // shape_length: 'Integer',
-        index: 'Integer'
-    }
+  returnType: 'Integer',
+  argumentTypes: {
+    original_shape: 'Array',
+    new_shape: 'Array',
+    index: 'Integer'
+  }
 });
 
 export default gpu;
diff --git a/src/index.ts b/src/index.ts
index eeae0488..1f7b2bf1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,8 +3,6 @@ import { Tensor } from './tensor';
 
 import { Add, Div, Log, Mul, Pow, Sub, Sum } from './operations/classes';
 
-import { _broadcast_shape, _get_original_index_kernel } from './broadcasting';
-
 export * from './operations/functional';
 export { Tensor };
 
@@ -14,4 +12,4 @@ registerOperation('mul', Mul);
 registerOperation('div', Div);
 registerOperation('sum', Sum);
 registerOperation('pow', Pow);
-registerOperation('log', Log);
\ No newline at end of file
+registerOperation('log', Log);
diff --git a/src/operations/base.ts b/src/operations/base.ts
index c46625ca..c77dd3cf 100644
--- a/src/operations/base.ts
+++ b/src/operations/base.ts
@@ -1,19 +1,18 @@
 import { Tensor } from '../tensor';
 
-
 abstract class Operation {
-    abstract forward(...args: Tensor[]): Tensor;
-    abstract backward(dz: Tensor): void;
+  abstract forward(...args: Tensor[]): Tensor;
+  abstract backward(dz: Tensor): void;
 }
 
 abstract class UnaryOperation extends Operation {
-    abstract forward(a: Tensor): Tensor;
-    abstract backward(dz: Tensor): void;
+  abstract forward(a: Tensor): Tensor;
+  abstract backward(dz: Tensor): void;
 }
 
 abstract class BinaryOperation extends Operation {
-    abstract forward(a: Tensor, b: Tensor): Tensor;
-    abstract backward(dz: Tensor): void;
+  abstract forward(a: Tensor, b: Tensor): Tensor;
+  abstract backward(dz: Tensor): void;
 }
 
 export type OperationConstructor = new () => Operation;
diff --git a/src/operations/classes.ts b/src/operations/classes.ts
index 3cc89cd3..7d9a4e75 100644
--- a/src/operations/classes.ts
+++ b/src/operations/classes.ts
@@ -1,8 +1,8 @@
-import gpu from "../gpu";
-import { _broadcast_shape, _get_original_index_kernel, _pad_shape } from "../broadcasting";
-import { Tensor } from "../tensor";
+import gpu from '../gpu';
+import { _broadcast_shape, _get_original_index_kernel, _pad_shape } from '../broadcasting';
+import { Tensor } from '../tensor';
 // import * as utils from "../utils";
-import { Operation, BinaryOperation, UnaryOperation } from "./base";
+import { Operation, BinaryOperation, UnaryOperation } from './base';
 
 /* This did not work as it doesn't support dynamic function registration */
 // export function _broadcast_operation(
@@ -68,24 +68,16 @@ export function _add_broadcast(
       b_shape: number[],
       broadcast_shape: number[]
     ) {
-      const a_index = _get_original_index_kernel(
-        a_shape,
-        broadcast_shape,
-        this.thread.x
-      );
-      const b_index = _get_original_index_kernel(
-        b_shape,
-        broadcast_shape,
-        this.thread.x
-      );
+      const a_index = _get_original_index_kernel(a_shape, broadcast_shape, this.thread.x);
+      const b_index = _get_original_index_kernel(b_shape, broadcast_shape, this.thread.x);
 
       return a[a_index] + b[b_index];
     },
     {
       constants: {
-        shape_length: broadcast_shape.length,
+        shape_length: broadcast_shape.length
       },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -114,24 +106,13 @@ export function _add_broadcast(
 //     return _broadcast_operation(_add_)(a, b);
 // }
 
-
-export function _add_tensor(
-  a: Tensor,
-  b: Tensor,
-  operation: Operation | null = null
-): Tensor {
+export function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = gpu.createKernel(
-    function (
-      a: number[],
-      as: number[],
-      b: number[],
-      bs: number[],
-      bcs: number[]
-    ) {
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
       const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
       const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -139,9 +120,9 @@ export function _add_tensor(
     },
     {
       constants: {
-        shape_length: broadcast_shape.length,
+        shape_length: broadcast_shape.length
       },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -165,23 +146,13 @@ export class Add extends BinaryOperation {
   }
 }
 
-export function _sub_tensor(
-  a: Tensor,
-  b: Tensor,
-  operation: Operation | null = null
-): Tensor {
+export function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = gpu.createKernel(
-    function (
-      a: number[],
-      as: number[],
-      b: number[],
-      bs: number[],
-      bcs: number[]
-    ) {
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
       const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
       const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -189,9 +160,9 @@ export function _sub_tensor(
     },
     {
       constants: {
-        shape_length: broadcast_shape?.length || 0,
+        shape_length: broadcast_shape?.length || 0
       },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -215,22 +186,12 @@ export class Sub extends BinaryOperation {
   }
 }
 
-export function _mul_tensor(
-  a: Tensor,
-  b: Tensor,
-  operation: Operation | null = null
-): Tensor {
+export function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
   const kernel = gpu.createKernel(
-    function (
-      a: number[],
-      as: number[],
-      b: number[],
-      bs: number[],
-      bcs: number[]
-    ) {
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
       const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
       const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -238,9 +199,9 @@ export function _mul_tensor(
     },
     {
       constants: {
-        shape_length: broadcast_shape.length,
+        shape_length: broadcast_shape.length
       },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -264,22 +225,12 @@ export class Mul extends BinaryOperation {
   }
 }
 
-export function _div_tensor(
-  a: Tensor,
-  b: Tensor,
-  operation: Operation | null = null
-): Tensor {
+export function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
   const kernel = gpu.createKernel(
-    function (
-      a: number[],
-      as: number[],
-      b: number[],
-      bs: number[],
-      bcs: number[]
-    ) {
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
       const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
       const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -287,9 +238,9 @@ export function _div_tensor(
     },
     {
       constants: {
-        shape_length: broadcast_shape.length,
+        shape_length: broadcast_shape.length
       },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -331,22 +282,12 @@ export class Sum extends UnaryOperation {
   }
 }
 
-export function _pow_tensor(
-  a: Tensor,
-  b: Tensor,
-  operation: Operation | null = null
-): Tensor {
+export function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
   const kernel = gpu.createKernel(
-    function (
-      a: number[],
-      as: number[],
-      b: number[],
-      bs: number[],
-      bcs: number[]
-    ) {
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
       const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
       const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -354,9 +295,9 @@ export function _pow_tensor(
     },
     {
       constants: {
-        shape_length: broadcast_shape.length,
+        shape_length: broadcast_shape.length
       },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -380,18 +321,13 @@ export class Pow extends BinaryOperation {
   }
 }
 
-export function _log_tensor(
-  a: Tensor,
-  operation: Operation | null = null
-): Tensor {
+export function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = gpu.createKernel(
-    function (
-      a: number[],
-    ) {
+    function (a: number[]) {
       return Math.log(a[this.thread.x]);
     },
     {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)],
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
     }
   );
 
@@ -410,6 +346,6 @@ export class Log extends UnaryOperation {
   }
   backward(dz: Tensor): void {
     const [a] = this.cache;
-    a.backward((new Tensor(1)).div(a));
+    a.backward(new Tensor(1).div(a));
   }
-}
\ No newline at end of file
+}
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 7fe40229..5b7b2c73 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -1,37 +1,37 @@
-import { Tensor } from "../tensor";
-import { getOperation } from "./registry";
+import { Tensor } from '../tensor';
+import { getOperation } from './registry';
 
 export function add(a: Tensor, b: Tensor): Tensor {
-    const operation = new (getOperation("add"))();
-    return operation.forward(a, b);
+  const operation = new (getOperation('add'))();
+  return operation.forward(a, b);
 }
 
 export function sub(a: Tensor, b: Tensor): Tensor {
-    const operation = new (getOperation("sub"))();
-    return operation.forward(a, b);
+  const operation = new (getOperation('sub'))();
+  return operation.forward(a, b);
 }
 
 export function mul(a: Tensor, b: Tensor): Tensor {
-    const operation = new (getOperation("mul"))();
-    return operation.forward(a, b);
+  const operation = new (getOperation('mul'))();
+  return operation.forward(a, b);
 }
 
 export function div(a: Tensor, b: Tensor): Tensor {
-    const operation = new (getOperation("div"))();
-    return operation.forward(a, b);
+  const operation = new (getOperation('div'))();
+  return operation.forward(a, b);
 }
 
 export function sum(a: Tensor): Tensor {
-    const operation = new (getOperation("sum"))();
-    return operation.forward(a);
+  const operation = new (getOperation('sum'))();
+  return operation.forward(a);
 }
 
 export function pow(a: Tensor, b: Tensor): Tensor {
-    const operation = new (getOperation("pow"))();
-    return operation.forward(a, b);
+  const operation = new (getOperation('pow'))();
+  return operation.forward(a, b);
 }
 
 export function log(a: Tensor): Tensor {
-    const operation = new (getOperation("log"))();
-    return operation.forward(a);
-}
\ No newline at end of file
+  const operation = new (getOperation('log'))();
+  return operation.forward(a);
+}
diff --git a/src/operations/registry.ts b/src/operations/registry.ts
index f4772ffb..a631ad57 100644
--- a/src/operations/registry.ts
+++ b/src/operations/registry.ts
@@ -1,4 +1,4 @@
-import { Operation, OperationConstructor } from "./base";
+import { OperationConstructor } from './base';
 
 // Only allow registering concrete, constructible Operation classes
 const operations = new Map();
diff --git a/src/tensor.ts b/src/tensor.ts
index 42972d13..04b448f5 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -1,6 +1,6 @@
-import { _get_original_index } from "./broadcasting";
-import { Operation } from "./operations/base";
-import { getOperation } from "./operations/registry";
+import { _get_original_index } from './broadcasting';
+import { Operation } from './operations/base';
+import { getOperation } from './operations/registry';
 
 /*
  * TODO:
@@ -35,7 +35,7 @@ function _get_shape(data: NestedNumberArray): number[] {
 
 function _flatten(data: NestedNumberArray): number[] {
   if (Array.isArray(data)) {
-    return data.flatMap((item) => _flatten(item));
+    return data.flatMap(item => _flatten(item));
   } else if (ArrayBuffer.isView(data)) {
     return Array.from(data);
   } else {
@@ -46,7 +46,7 @@ function _flatten(data: NestedNumberArray): number[] {
 export class Tensor {
   data: number[];
   _shape: number[];
-  operation: any = null;
+  operation: Operation | null = null;
   public grad: Tensor | null = null;
 
   requires_grad: boolean;
@@ -54,7 +54,7 @@ export class Tensor {
   constructor(
     data: NestedNumberArray,
     options: { requires_grad?: boolean } = {},
-    internal_options: { operation?: Operation, shape?: number[] } = {}
+    internal_options: { operation?: Operation; shape?: number[] } = {}
   ) {
     this.data = _flatten(data);
     this.requires_grad = options.requires_grad ?? false;
@@ -87,36 +87,36 @@ export class Tensor {
   }
 
   add(other: Tensor): Tensor {
-    return this._executeBinaryOp("add", other);
+    return this._executeBinaryOp('add', other);
   }
 
   sub(other: Tensor): Tensor {
-    return this._executeBinaryOp("sub", other);
+    return this._executeBinaryOp('sub', other);
   }
 
   mul(other: Tensor): Tensor {
-    return this._executeBinaryOp("mul", other);
+    return this._executeBinaryOp('mul', other);
   }
 
   div(other: Tensor): Tensor {
-    return this._executeBinaryOp("div", other);
+    return this._executeBinaryOp('div', other);
   }
 
   sum(): Tensor {
-    return this._executeUnaryOp("sum");
+    return this._executeUnaryOp('sum');
   }
 
   pow(other: Tensor): Tensor {
-    return this._executeBinaryOp("pow", other);
+    return this._executeBinaryOp('pow', other);
   }
 
   log(): Tensor {
-    return this._executeUnaryOp("log");
+    return this._executeUnaryOp('log');
   }
 
   item(): number {
     if (this.data.length !== 1) {
-      throw new Error("Tensor.item() is only valid for scalars");
+      throw new Error('Tensor.item() is only valid for scalars');
     }
     return this.data[0];
   }
@@ -129,7 +129,7 @@ export class Tensor {
 
     if (!grad) {
       if (this.data.length !== 1) {
-        throw new Error("Gradient is required for non-scalar tensors");
+        throw new Error('Gradient is required for non-scalar tensors');
       }
 
       grad = new Tensor(1);
diff --git a/src/utils.ts b/src/utils.ts
index 59713714..fd9225e2 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -1,7 +1,7 @@
 import { Tensor } from './tensor';
 
 export function ones_like(other: Tensor): Tensor {
-    const tensor = new Tensor(Array(other.data.length).fill(1));
-    tensor.shape = other.shape;
-    return tensor;
-}
\ No newline at end of file
+  const tensor = new Tensor(Array(other.data.length).fill(1));
+  tensor.shape = other.shape;
+  return tensor;
+}
diff --git a/yarn.lock b/yarn.lock
index 86a0d9dd..6ef1d96e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -600,6 +600,125 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0":
+  version: 4.9.0
+  resolution: "@eslint-community/eslint-utils@npm:4.9.0"
+  dependencies:
+    eslint-visitor-keys: "npm:^3.4.3"
+  peerDependencies:
+    eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+  checksum: 10c0/8881e22d519326e7dba85ea915ac7a143367c805e6ba1374c987aa2fbdd09195cc51183d2da72c0e2ff388f84363e1b220fd0d19bef10c272c63455162176817
+  languageName: node
+  linkType: hard
+
+"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1":
+  version: 4.12.1
+  resolution: "@eslint-community/regexpp@npm:4.12.1"
+  checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6
+  languageName: node
+  linkType: hard
+
+"@eslint/config-array@npm:^0.21.0":
+  version: 0.21.0
+  resolution: "@eslint/config-array@npm:0.21.0"
+  dependencies:
+    "@eslint/object-schema": "npm:^2.1.6"
+    debug: "npm:^4.3.1"
+    minimatch: "npm:^3.1.2"
+  checksum: 10c0/0ea801139166c4aa56465b309af512ef9b2d3c68f9198751bbc3e21894fe70f25fbf26e1b0e9fffff41857bc21bfddeee58649ae6d79aadcd747db0c5dca771f
+  languageName: node
+  linkType: hard
+
+"@eslint/config-helpers@npm:^0.4.0":
+  version: 0.4.0
+  resolution: "@eslint/config-helpers@npm:0.4.0"
+  dependencies:
+    "@eslint/core": "npm:^0.16.0"
+  checksum: 10c0/4e20c13aaeba1fa024983785df6625b36c8f4415b2433097982e1ccb08db9909e2f7bf60b793538d52ecfd572f2c4eec39a884c13c185cb6be35151f053beed5
+  languageName: node
+  linkType: hard
+
+"@eslint/core@npm:^0.16.0":
+  version: 0.16.0
+  resolution: "@eslint/core@npm:0.16.0"
+  dependencies:
+    "@types/json-schema": "npm:^7.0.15"
+  checksum: 10c0/f27496a244ccfdca3e0fbc3331f9da3f603bdf1aa431af0045a3205826789a54493bc619ad6311a9090eaf7bc25798ff4e265dea1eccd2df9ce3b454f7e7da27
+  languageName: node
+  linkType: hard
+
+"@eslint/eslintrc@npm:^3.3.1":
+  version: 3.3.1
+  resolution: "@eslint/eslintrc@npm:3.3.1"
+  dependencies:
+    ajv: "npm:^6.12.4"
+    debug: "npm:^4.3.2"
+    espree: "npm:^10.0.1"
+    globals: "npm:^14.0.0"
+    ignore: "npm:^5.2.0"
+    import-fresh: "npm:^3.2.1"
+    js-yaml: "npm:^4.1.0"
+    minimatch: "npm:^3.1.2"
+    strip-json-comments: "npm:^3.1.1"
+  checksum: 10c0/b0e63f3bc5cce4555f791a4e487bf999173fcf27c65e1ab6e7d63634d8a43b33c3693e79f192cbff486d7df1be8ebb2bd2edc6e70ddd486cbfa84a359a3e3b41
+  languageName: node
+  linkType: hard
+
+"@eslint/js@npm:9.37.0, @eslint/js@npm:^9.37.0":
+  version: 9.37.0
+  resolution: "@eslint/js@npm:9.37.0"
+  checksum: 10c0/84f98a6213522fc76ea104bd910f606136200bd918544e056a7a22442d3f9d5c3c5cd7f4cdf2499d49b1fa140155b87d597a1f16d01644920f05c228e9ca0378
+  languageName: node
+  linkType: hard
+
+"@eslint/object-schema@npm:^2.1.6":
+  version: 2.1.6
+  resolution: "@eslint/object-schema@npm:2.1.6"
+  checksum: 10c0/b8cdb7edea5bc5f6a96173f8d768d3554a628327af536da2fc6967a93b040f2557114d98dbcdbf389d5a7b290985ad6a9ce5babc547f36fc1fde42e674d11a56
+  languageName: node
+  linkType: hard
+
+"@eslint/plugin-kit@npm:^0.4.0":
+  version: 0.4.0
+  resolution: "@eslint/plugin-kit@npm:0.4.0"
+  dependencies:
+    "@eslint/core": "npm:^0.16.0"
+    levn: "npm:^0.4.1"
+  checksum: 10c0/125614e902bb34c041da859794c47ac2ec4a814f5d9e7c4d37fcd34b38d8ee5cf1f97020d38d168885d9bf4046a9a7decb86b4cee8dac9eedcc6ad08ebafe204
+  languageName: node
+  linkType: hard
+
+"@humanfs/core@npm:^0.19.1":
+  version: 0.19.1
+  resolution: "@humanfs/core@npm:0.19.1"
+  checksum: 10c0/aa4e0152171c07879b458d0e8a704b8c3a89a8c0541726c6b65b81e84fd8b7564b5d6c633feadc6598307d34564bd53294b533491424e8e313d7ab6c7bc5dc67
+  languageName: node
+  linkType: hard
+
+"@humanfs/node@npm:^0.16.6":
+  version: 0.16.7
+  resolution: "@humanfs/node@npm:0.16.7"
+  dependencies:
+    "@humanfs/core": "npm:^0.19.1"
+    "@humanwhocodes/retry": "npm:^0.4.0"
+  checksum: 10c0/9f83d3cf2cfa37383e01e3cdaead11cd426208e04c44adcdd291aa983aaf72d7d3598844d2fe9ce54896bb1bf8bd4b56883376611c8905a19c44684642823f30
+  languageName: node
+  linkType: hard
+
+"@humanwhocodes/module-importer@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "@humanwhocodes/module-importer@npm:1.0.1"
+  checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529
+  languageName: node
+  linkType: hard
+
+"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2":
+  version: 0.4.3
+  resolution: "@humanwhocodes/retry@npm:0.4.3"
+  checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42
+  languageName: node
+  linkType: hard
+
 "@isaacs/balanced-match@npm:^4.0.1":
   version: 4.0.1
   resolution: "@isaacs/balanced-match@npm:4.0.1"
@@ -1043,6 +1162,33 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@nodelib/fs.scandir@npm:2.1.5":
+  version: 2.1.5
+  resolution: "@nodelib/fs.scandir@npm:2.1.5"
+  dependencies:
+    "@nodelib/fs.stat": "npm:2.0.5"
+    run-parallel: "npm:^1.1.9"
+  checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb
+  languageName: node
+  linkType: hard
+
+"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2":
+  version: 2.0.5
+  resolution: "@nodelib/fs.stat@npm:2.0.5"
+  checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d
+  languageName: node
+  linkType: hard
+
+"@nodelib/fs.walk@npm:^1.2.3":
+  version: 1.2.8
+  resolution: "@nodelib/fs.walk@npm:1.2.8"
+  dependencies:
+    "@nodelib/fs.scandir": "npm:2.1.5"
+    fastq: "npm:^1.6.0"
+  checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1
+  languageName: node
+  linkType: hard
+
 "@npmcli/agent@npm:^2.0.0":
   version: 2.2.2
   resolution: "@npmcli/agent@npm:2.2.2"
@@ -1271,6 +1417,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@rtsao/scc@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "@rtsao/scc@npm:1.1.0"
+  checksum: 10c0/b5bcfb0d87f7d1c1c7c0f7693f53b07866ed9fec4c34a97a8c948fb9a7c0082e416ce4d3b60beb4f5e167cbe04cdeefbf6771320f3ede059b9ce91188c409a5b
+  languageName: node
+  linkType: hard
+
 "@rushstack/node-core-library@npm:5.16.0":
   version: 5.16.0
   resolution: "@rushstack/node-core-library@npm:5.16.0"
@@ -1452,7 +1605,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0":
+"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
   version: 1.0.8
   resolution: "@types/estree@npm:1.0.8"
   checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5
@@ -1494,6 +1647,20 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/json-schema@npm:^7.0.15":
+  version: 7.0.15
+  resolution: "@types/json-schema@npm:7.0.15"
+  checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db
+  languageName: node
+  linkType: hard
+
+"@types/json5@npm:^0.0.29":
+  version: 0.0.29
+  resolution: "@types/json5@npm:0.0.29"
+  checksum: 10c0/6bf5337bc447b706bb5b4431d37686aa2ea6d07cfd6f79cc31de80170d6ff9b1c7384a9c0ccbc45b3f512bae9e9f75c2e12109806a15331dc94e8a8db6dbb4ac
+  languageName: node
+  linkType: hard
+
 "@types/node@npm:*, @types/node@npm:^24.6.2":
   version: 24.6.2
   resolution: "@types/node@npm:24.6.2"
@@ -1526,6 +1693,143 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@typescript-eslint/eslint-plugin@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/eslint-plugin@npm:8.46.0"
+  dependencies:
+    "@eslint-community/regexpp": "npm:^4.10.0"
+    "@typescript-eslint/scope-manager": "npm:8.46.0"
+    "@typescript-eslint/type-utils": "npm:8.46.0"
+    "@typescript-eslint/utils": "npm:8.46.0"
+    "@typescript-eslint/visitor-keys": "npm:8.46.0"
+    graphemer: "npm:^1.4.0"
+    ignore: "npm:^7.0.0"
+    natural-compare: "npm:^1.4.0"
+    ts-api-utils: "npm:^2.1.0"
+  peerDependencies:
+    "@typescript-eslint/parser": ^8.46.0
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/9de2b2127b977b0d73733042602a744e5b69bfe906c6dac424123ff9726816dcc4bb3d4ba470bc1fc5c741421f53274a3a896c09fbb50e298352d4a72011b2c2
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/parser@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/parser@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/scope-manager": "npm:8.46.0"
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/typescript-estree": "npm:8.46.0"
+    "@typescript-eslint/visitor-keys": "npm:8.46.0"
+    debug: "npm:^4.3.4"
+  peerDependencies:
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/2e8c75b72c7cf170aca554014dbe30e85478d96799a2eb782c4fb61423c0c9e4416e98d6e7903601b1738ea1d0936417dbf61ac0293a0500f56e0eaeefbb2ecd
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/project-service@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/project-service@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/tsconfig-utils": "npm:^8.46.0"
+    "@typescript-eslint/types": "npm:^8.46.0"
+    debug: "npm:^4.3.4"
+  peerDependencies:
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/c3164c795570edfa141917f3099724eca70383b016be1b08f656a491b459d68cf8e2547ac416d75048d3511ca5feaea0586aabad339e3dfe2ae6fddb650d7bc8
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/scope-manager@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/scope-manager@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/visitor-keys": "npm:8.46.0"
+  checksum: 10c0/9c242d1edd51247559f99dd8986bdb571db0a2a583a2d02ee8f5f346d265e956f413b442c27e1b02d55ce3944609f6593050ec657be672d9b24b7ed0a359a6ad
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/tsconfig-utils@npm:8.46.0, @typescript-eslint/tsconfig-utils@npm:^8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.0"
+  peerDependencies:
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/306b27c741709f2435dd1c7eabdf552775dff1b3ced01d791c5b9755394ceb3f37c9bcceec92adb6fe60c622523f9d47d9b0d9e515071f47d50527705a4706f7
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/type-utils@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/type-utils@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/typescript-estree": "npm:8.46.0"
+    "@typescript-eslint/utils": "npm:8.46.0"
+    debug: "npm:^4.3.4"
+    ts-api-utils: "npm:^2.1.0"
+  peerDependencies:
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/a0fa4617a998094bc217be1989b76a3e45c058117cda027a723ff6f98f15e5237abfa123284afbdea7f320b4da65e1053ed47c8a211dd012591908a9daa46f02
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/types@npm:8.46.0, @typescript-eslint/types@npm:^8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/types@npm:8.46.0"
+  checksum: 10c0/2f986852139bcbe940b4aafe79bbd28dcca7176e95ba4e3880984ef58c81ad077ca9d9191aad56d2b1df6d16060f5744a96ab3118ddbc9766e5035ed470445c1
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/typescript-estree@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/typescript-estree@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/project-service": "npm:8.46.0"
+    "@typescript-eslint/tsconfig-utils": "npm:8.46.0"
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/visitor-keys": "npm:8.46.0"
+    debug: "npm:^4.3.4"
+    fast-glob: "npm:^3.3.2"
+    is-glob: "npm:^4.0.3"
+    minimatch: "npm:^9.0.4"
+    semver: "npm:^7.6.0"
+    ts-api-utils: "npm:^2.1.0"
+  peerDependencies:
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/39aed033dc23c3356e39891c9eba6dde0dc618406f0e13e9adc5967fb81790ec199b1d6eb1144e35ad13a0daaf72157f5f3fc7ac1b7c58d152ade68fe27ad221
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/utils@npm:8.46.0, @typescript-eslint/utils@npm:^8.0.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/utils@npm:8.46.0"
+  dependencies:
+    "@eslint-community/eslint-utils": "npm:^4.7.0"
+    "@typescript-eslint/scope-manager": "npm:8.46.0"
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/typescript-estree": "npm:8.46.0"
+  peerDependencies:
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/77cc7dff9132d9f02e8766d128edbeb7c2f2b56f9ebdac7308e75a04924e2369857da27b23f0054476c9640609a9707b8dd8ca8b1c59a067e45f65bf5ef4cc1b
+  languageName: node
+  linkType: hard
+
+"@typescript-eslint/visitor-keys@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/visitor-keys@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/types": "npm:8.46.0"
+    eslint-visitor-keys: "npm:^4.2.1"
+  checksum: 10c0/473dd4861b81238c1df10008b3b6d4684b2fa5ec4f3a8eeb544ea1278a5e2119f839447d16653ea3070164d7e742e3516fe9b0faf16e12a457fa26d5e14a7498
+  languageName: node
+  linkType: hard
+
 "@ungap/structured-clone@npm:^1.3.0":
   version: 1.3.0
   resolution: "@ungap/structured-clone@npm:1.3.0"
@@ -1791,6 +2095,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"acorn-jsx@npm:^5.3.2":
+  version: 5.3.2
+  resolution: "acorn-jsx@npm:5.3.2"
+  peerDependencies:
+    acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+  checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1
+  languageName: node
+  linkType: hard
+
 "acorn-walk@npm:^8.1.1":
   version: 8.3.4
   resolution: "acorn-walk@npm:8.3.4"
@@ -1861,6 +2174,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"ajv@npm:^6.12.4":
+  version: 6.12.6
+  resolution: "ajv@npm:6.12.6"
+  dependencies:
+    fast-deep-equal: "npm:^3.1.1"
+    fast-json-stable-stringify: "npm:^2.0.0"
+    json-schema-traverse: "npm:^0.4.1"
+    uri-js: "npm:^4.2.2"
+  checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71
+  languageName: node
+  linkType: hard
+
 "ajv@npm:^8.0.0":
   version: 8.17.1
   resolution: "ajv@npm:8.17.1"
@@ -1976,6 +2301,116 @@ __metadata:
   languageName: node
   linkType: hard
 
+"argparse@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "argparse@npm:2.0.1"
+  checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e
+  languageName: node
+  linkType: hard
+
+"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "array-buffer-byte-length@npm:1.0.2"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    is-array-buffer: "npm:^3.0.5"
+  checksum: 10c0/74e1d2d996941c7a1badda9cabb7caab8c449db9086407cad8a1b71d2604cc8abf105db8ca4e02c04579ec58b7be40279ddb09aea4784832984485499f48432d
+  languageName: node
+  linkType: hard
+
+"array-includes@npm:^3.1.9":
+  version: 3.1.9
+  resolution: "array-includes@npm:3.1.9"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.4"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.24.0"
+    es-object-atoms: "npm:^1.1.1"
+    get-intrinsic: "npm:^1.3.0"
+    is-string: "npm:^1.1.1"
+    math-intrinsics: "npm:^1.1.0"
+  checksum: 10c0/0235fa69078abeac05ac4250699c44996bc6f774a9cbe45db48674ce6bd142f09b327d31482ff75cf03344db4ea03eae23edb862d59378b484b47ed842574856
+  languageName: node
+  linkType: hard
+
+"array.prototype.findlastindex@npm:^1.2.6":
+  version: 1.2.6
+  resolution: "array.prototype.findlastindex@npm:1.2.6"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.4"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.9"
+    es-errors: "npm:^1.3.0"
+    es-object-atoms: "npm:^1.1.1"
+    es-shim-unscopables: "npm:^1.1.0"
+  checksum: 10c0/82559310d2e57ec5f8fc53d7df420e3abf0ba497935de0a5570586035478ba7d07618cb18e2d4ada2da514c8fb98a034aaf5c06caa0a57e2f7f4c4adedef5956
+  languageName: node
+  linkType: hard
+
+"array.prototype.flat@npm:^1.3.3":
+  version: 1.3.3
+  resolution: "array.prototype.flat@npm:1.3.3"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.5"
+    es-shim-unscopables: "npm:^1.0.2"
+  checksum: 10c0/d90e04dfbc43bb96b3d2248576753d1fb2298d2d972e29ca7ad5ec621f0d9e16ff8074dae647eac4f31f4fb7d3f561a7ac005fb01a71f51705a13b5af06a7d8a
+  languageName: node
+  linkType: hard
+
+"array.prototype.flatmap@npm:^1.3.3":
+  version: 1.3.3
+  resolution: "array.prototype.flatmap@npm:1.3.3"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.5"
+    es-shim-unscopables: "npm:^1.0.2"
+  checksum: 10c0/ba899ea22b9dc9bf276e773e98ac84638ed5e0236de06f13d63a90b18ca9e0ec7c97d622d899796e3773930b946cd2413d098656c0c5d8cc58c6f25c21e6bd54
+  languageName: node
+  linkType: hard
+
+"arraybuffer.prototype.slice@npm:^1.0.4":
+  version: 1.0.4
+  resolution: "arraybuffer.prototype.slice@npm:1.0.4"
+  dependencies:
+    array-buffer-byte-length: "npm:^1.0.1"
+    call-bind: "npm:^1.0.8"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.5"
+    es-errors: "npm:^1.3.0"
+    get-intrinsic: "npm:^1.2.6"
+    is-array-buffer: "npm:^3.0.4"
+  checksum: 10c0/2f2459caa06ae0f7f615003f9104b01f6435cc803e11bd2a655107d52a1781dc040532dc44d93026b694cc18793993246237423e13a5337e86b43ed604932c06
+  languageName: node
+  linkType: hard
+
+"async-function@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "async-function@npm:1.0.0"
+  checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73
+  languageName: node
+  linkType: hard
+
+"async-generator-function@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "async-generator-function@npm:1.0.0"
+  checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186
+  languageName: node
+  linkType: hard
+
+"available-typed-arrays@npm:^1.0.7":
+  version: 1.0.7
+  resolution: "available-typed-arrays@npm:1.0.7"
+  dependencies:
+    possible-typed-array-names: "npm:^1.0.0"
+  checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2
+  languageName: node
+  linkType: hard
+
 "b4a@npm:^1.6.4":
   version: 1.7.3
   resolution: "b4a@npm:1.7.3"
@@ -2239,7 +2674,39 @@ __metadata:
   languageName: node
   linkType: hard
 
-"callsites@npm:^3.1.0":
+"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "call-bind-apply-helpers@npm:1.0.2"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    function-bind: "npm:^1.1.2"
+  checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938
+  languageName: node
+  linkType: hard
+
+"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8":
+  version: 1.0.8
+  resolution: "call-bind@npm:1.0.8"
+  dependencies:
+    call-bind-apply-helpers: "npm:^1.0.0"
+    es-define-property: "npm:^1.0.0"
+    get-intrinsic: "npm:^1.2.4"
+    set-function-length: "npm:^1.2.2"
+  checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4
+  languageName: node
+  linkType: hard
+
+"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4":
+  version: 1.0.4
+  resolution: "call-bound@npm:1.0.4"
+  dependencies:
+    call-bind-apply-helpers: "npm:^1.0.2"
+    get-intrinsic: "npm:^1.3.0"
+  checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644
+  languageName: node
+  linkType: hard
+
+"callsites@npm:^3.0.0, callsites@npm:^3.1.0":
   version: 3.1.0
   resolution: "callsites@npm:3.1.0"
   checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301
@@ -2267,7 +2734,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"chalk@npm:^4.1.2":
+"chalk@npm:^4.0.0, chalk@npm:^4.1.2":
   version: 4.1.2
   resolution: "chalk@npm:4.1.2"
   dependencies:
@@ -2427,6 +2894,39 @@ __metadata:
   languageName: node
   linkType: hard
 
+"data-view-buffer@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "data-view-buffer@npm:1.0.2"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    es-errors: "npm:^1.3.0"
+    is-data-view: "npm:^1.0.2"
+  checksum: 10c0/7986d40fc7979e9e6241f85db8d17060dd9a71bd53c894fa29d126061715e322a4cd47a00b0b8c710394854183d4120462b980b8554012acc1c0fa49df7ad38c
+  languageName: node
+  linkType: hard
+
+"data-view-byte-length@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "data-view-byte-length@npm:1.0.2"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    es-errors: "npm:^1.3.0"
+    is-data-view: "npm:^1.0.2"
+  checksum: 10c0/f8a4534b5c69384d95ac18137d381f18a5cfae1f0fc1df0ef6feef51ef0d568606d970b69e02ea186c6c0f0eac77fe4e6ad96fec2569cc86c3afcc7475068c55
+  languageName: node
+  linkType: hard
+
+"data-view-byte-offset@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "data-view-byte-offset@npm:1.0.1"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    es-errors: "npm:^1.3.0"
+    is-data-view: "npm:^1.0.1"
+  checksum: 10c0/fa7aa40078025b7810dcffc16df02c480573b7b53ef1205aa6a61533011005c1890e5ba17018c692ce7c900212b547262d33279fde801ad9843edc0863bf78c4
+  languageName: node
+  linkType: hard
+
 "de-indent@npm:^1.0.2":
   version: 1.0.2
   resolution: "de-indent@npm:1.0.2"
@@ -2434,7 +2934,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:^4.4.0":
+"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0":
   version: 4.4.3
   resolution: "debug@npm:4.4.3"
   dependencies:
@@ -2446,6 +2946,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"debug@npm:^3.2.7":
+  version: 3.2.7
+  resolution: "debug@npm:3.2.7"
+  dependencies:
+    ms: "npm:^2.1.1"
+  checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a
+  languageName: node
+  linkType: hard
+
 "decompress-response@npm:^6.0.0":
   version: 6.0.0
   resolution: "decompress-response@npm:6.0.0"
@@ -2474,6 +2983,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"deep-is@npm:^0.1.3":
+  version: 0.1.4
+  resolution: "deep-is@npm:0.1.4"
+  checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c
+  languageName: node
+  linkType: hard
+
 "deepmerge@npm:^4.3.1":
   version: 4.3.1
   resolution: "deepmerge@npm:4.3.1"
@@ -2481,6 +2997,28 @@ __metadata:
   languageName: node
   linkType: hard
 
+"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
+  version: 1.1.4
+  resolution: "define-data-property@npm:1.1.4"
+  dependencies:
+    es-define-property: "npm:^1.0.0"
+    es-errors: "npm:^1.3.0"
+    gopd: "npm:^1.0.1"
+  checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37
+  languageName: node
+  linkType: hard
+
+"define-properties@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "define-properties@npm:1.2.1"
+  dependencies:
+    define-data-property: "npm:^1.0.1"
+    has-property-descriptors: "npm:^1.0.0"
+    object-keys: "npm:^1.1.1"
+  checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3
+  languageName: node
+  linkType: hard
+
 "detect-libc@npm:^2.0.0":
   version: 2.1.1
   resolution: "detect-libc@npm:2.1.1"
@@ -2502,6 +3040,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"doctrine@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "doctrine@npm:2.1.0"
+  dependencies:
+    esutils: "npm:^2.0.2"
+  checksum: 10c0/b6416aaff1f380bf56c3b552f31fdf7a69b45689368deca72d28636f41c16bb28ec3ebc40ace97db4c1afc0ceeb8120e8492fe0046841c94c2933b2e30a7d5ac
+  languageName: node
+  linkType: hard
+
+"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "dunder-proto@npm:1.0.1"
+  dependencies:
+    call-bind-apply-helpers: "npm:^1.0.1"
+    es-errors: "npm:^1.3.0"
+    gopd: "npm:^1.2.0"
+  checksum: 10c0/199f2a0c1c16593ca0a145dbf76a962f8033ce3129f01284d48c45ed4e14fea9bbacd7b3610b6cdc33486cef20385ac054948fefc6272fcce645c09468f93031
+  languageName: node
+  linkType: hard
+
 "eastasianwidth@npm:^0.2.0":
   version: 0.2.0
   resolution: "eastasianwidth@npm:0.2.0"
@@ -2585,14 +3143,131 @@ __metadata:
   languageName: node
   linkType: hard
 
-"esbuild@npm:^0.25.0":
-  version: 0.25.10
-  resolution: "esbuild@npm:0.25.10"
+"es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0":
+  version: 1.24.0
+  resolution: "es-abstract@npm:1.24.0"
+  dependencies:
+    array-buffer-byte-length: "npm:^1.0.2"
+    arraybuffer.prototype.slice: "npm:^1.0.4"
+    available-typed-arrays: "npm:^1.0.7"
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.4"
+    data-view-buffer: "npm:^1.0.2"
+    data-view-byte-length: "npm:^1.0.2"
+    data-view-byte-offset: "npm:^1.0.1"
+    es-define-property: "npm:^1.0.1"
+    es-errors: "npm:^1.3.0"
+    es-object-atoms: "npm:^1.1.1"
+    es-set-tostringtag: "npm:^2.1.0"
+    es-to-primitive: "npm:^1.3.0"
+    function.prototype.name: "npm:^1.1.8"
+    get-intrinsic: "npm:^1.3.0"
+    get-proto: "npm:^1.0.1"
+    get-symbol-description: "npm:^1.1.0"
+    globalthis: "npm:^1.0.4"
+    gopd: "npm:^1.2.0"
+    has-property-descriptors: "npm:^1.0.2"
+    has-proto: "npm:^1.2.0"
+    has-symbols: "npm:^1.1.0"
+    hasown: "npm:^2.0.2"
+    internal-slot: "npm:^1.1.0"
+    is-array-buffer: "npm:^3.0.5"
+    is-callable: "npm:^1.2.7"
+    is-data-view: "npm:^1.0.2"
+    is-negative-zero: "npm:^2.0.3"
+    is-regex: "npm:^1.2.1"
+    is-set: "npm:^2.0.3"
+    is-shared-array-buffer: "npm:^1.0.4"
+    is-string: "npm:^1.1.1"
+    is-typed-array: "npm:^1.1.15"
+    is-weakref: "npm:^1.1.1"
+    math-intrinsics: "npm:^1.1.0"
+    object-inspect: "npm:^1.13.4"
+    object-keys: "npm:^1.1.1"
+    object.assign: "npm:^4.1.7"
+    own-keys: "npm:^1.0.1"
+    regexp.prototype.flags: "npm:^1.5.4"
+    safe-array-concat: "npm:^1.1.3"
+    safe-push-apply: "npm:^1.0.0"
+    safe-regex-test: "npm:^1.1.0"
+    set-proto: "npm:^1.0.0"
+    stop-iteration-iterator: "npm:^1.1.0"
+    string.prototype.trim: "npm:^1.2.10"
+    string.prototype.trimend: "npm:^1.0.9"
+    string.prototype.trimstart: "npm:^1.0.8"
+    typed-array-buffer: "npm:^1.0.3"
+    typed-array-byte-length: "npm:^1.0.3"
+    typed-array-byte-offset: "npm:^1.0.4"
+    typed-array-length: "npm:^1.0.7"
+    unbox-primitive: "npm:^1.1.0"
+    which-typed-array: "npm:^1.1.19"
+  checksum: 10c0/b256e897be32df5d382786ce8cce29a1dd8c97efbab77a26609bd70f2ed29fbcfc7a31758cb07488d532e7ccccdfca76c1118f2afe5a424cdc05ca007867c318
+  languageName: node
+  linkType: hard
+
+"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "es-define-property@npm:1.0.1"
+  checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c
+  languageName: node
+  linkType: hard
+
+"es-errors@npm:^1.3.0":
+  version: 1.3.0
+  resolution: "es-errors@npm:1.3.0"
+  checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85
+  languageName: node
+  linkType: hard
+
+"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "es-object-atoms@npm:1.1.1"
   dependencies:
-    "@esbuild/aix-ppc64": "npm:0.25.10"
-    "@esbuild/android-arm": "npm:0.25.10"
-    "@esbuild/android-arm64": "npm:0.25.10"
-    "@esbuild/android-x64": "npm:0.25.10"
+    es-errors: "npm:^1.3.0"
+  checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c
+  languageName: node
+  linkType: hard
+
+"es-set-tostringtag@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "es-set-tostringtag@npm:2.1.0"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    get-intrinsic: "npm:^1.2.6"
+    has-tostringtag: "npm:^1.0.2"
+    hasown: "npm:^2.0.2"
+  checksum: 10c0/ef2ca9ce49afe3931cb32e35da4dcb6d86ab02592cfc2ce3e49ced199d9d0bb5085fc7e73e06312213765f5efa47cc1df553a6a5154584b21448e9fb8355b1af
+  languageName: node
+  linkType: hard
+
+"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "es-shim-unscopables@npm:1.1.0"
+  dependencies:
+    hasown: "npm:^2.0.2"
+  checksum: 10c0/1b9702c8a1823fc3ef39035a4e958802cf294dd21e917397c561d0b3e195f383b978359816b1732d02b255ccf63e1e4815da0065b95db8d7c992037be3bbbcdb
+  languageName: node
+  linkType: hard
+
+"es-to-primitive@npm:^1.3.0":
+  version: 1.3.0
+  resolution: "es-to-primitive@npm:1.3.0"
+  dependencies:
+    is-callable: "npm:^1.2.7"
+    is-date-object: "npm:^1.0.5"
+    is-symbol: "npm:^1.0.4"
+  checksum: 10c0/c7e87467abb0b438639baa8139f701a06537d2b9bc758f23e8622c3b42fd0fdb5bde0f535686119e446dd9d5e4c0f238af4e14960f4771877cf818d023f6730b
+  languageName: node
+  linkType: hard
+
+"esbuild@npm:^0.25.0":
+  version: 0.25.10
+  resolution: "esbuild@npm:0.25.10"
+  dependencies:
+    "@esbuild/aix-ppc64": "npm:0.25.10"
+    "@esbuild/android-arm": "npm:0.25.10"
+    "@esbuild/android-arm64": "npm:0.25.10"
+    "@esbuild/android-x64": "npm:0.25.10"
     "@esbuild/darwin-arm64": "npm:0.25.10"
     "@esbuild/darwin-x64": "npm:0.25.10"
     "@esbuild/freebsd-arm64": "npm:0.25.10"
@@ -2688,6 +3363,168 @@ __metadata:
   languageName: node
   linkType: hard
 
+"escape-string-regexp@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "escape-string-regexp@npm:4.0.0"
+  checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9
+  languageName: node
+  linkType: hard
+
+"eslint-import-resolver-node@npm:^0.3.9":
+  version: 0.3.9
+  resolution: "eslint-import-resolver-node@npm:0.3.9"
+  dependencies:
+    debug: "npm:^3.2.7"
+    is-core-module: "npm:^2.13.0"
+    resolve: "npm:^1.22.4"
+  checksum: 10c0/0ea8a24a72328a51fd95aa8f660dcca74c1429806737cf10261ab90cfcaaf62fd1eff664b76a44270868e0a932711a81b250053942595bcd00a93b1c1575dd61
+  languageName: node
+  linkType: hard
+
+"eslint-module-utils@npm:^2.12.1":
+  version: 2.12.1
+  resolution: "eslint-module-utils@npm:2.12.1"
+  dependencies:
+    debug: "npm:^3.2.7"
+  peerDependenciesMeta:
+    eslint:
+      optional: true
+  checksum: 10c0/6f4efbe7a91ae49bf67b4ab3644cb60bc5bd7db4cb5521de1b65be0847ffd3fb6bce0dd68f0995e1b312d137f768e2a1f842ee26fe73621afa05f850628fdc40
+  languageName: node
+  linkType: hard
+
+"eslint-plugin-import@npm:^2.32.0":
+  version: 2.32.0
+  resolution: "eslint-plugin-import@npm:2.32.0"
+  dependencies:
+    "@rtsao/scc": "npm:^1.1.0"
+    array-includes: "npm:^3.1.9"
+    array.prototype.findlastindex: "npm:^1.2.6"
+    array.prototype.flat: "npm:^1.3.3"
+    array.prototype.flatmap: "npm:^1.3.3"
+    debug: "npm:^3.2.7"
+    doctrine: "npm:^2.1.0"
+    eslint-import-resolver-node: "npm:^0.3.9"
+    eslint-module-utils: "npm:^2.12.1"
+    hasown: "npm:^2.0.2"
+    is-core-module: "npm:^2.16.1"
+    is-glob: "npm:^4.0.3"
+    minimatch: "npm:^3.1.2"
+    object.fromentries: "npm:^2.0.8"
+    object.groupby: "npm:^1.0.3"
+    object.values: "npm:^1.2.1"
+    semver: "npm:^6.3.1"
+    string.prototype.trimend: "npm:^1.0.9"
+    tsconfig-paths: "npm:^3.15.0"
+  peerDependencies:
+    eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
+  checksum: 10c0/bfb1b8fc8800398e62ddfefbf3638d185286edfed26dfe00875cc2846d954491b4f5112457831588b757fa789384e1ae585f812614c4797f0499fa234fd4a48b
+  languageName: node
+  linkType: hard
+
+"eslint-plugin-jest@npm:^29.0.1":
+  version: 29.0.1
+  resolution: "eslint-plugin-jest@npm:29.0.1"
+  dependencies:
+    "@typescript-eslint/utils": "npm:^8.0.0"
+  peerDependencies:
+    "@typescript-eslint/eslint-plugin": ^8.0.0
+    eslint: ^8.57.0 || ^9.0.0
+    jest: "*"
+  peerDependenciesMeta:
+    "@typescript-eslint/eslint-plugin":
+      optional: true
+    jest:
+      optional: true
+  checksum: 10c0/20edc166503a50c10b45f733797d530a5107c91efa25410ef405780d12222a796b5b41ed8f6d2b939632a1af273af6cc5732233463d1f36dbe7680bbb86c4eec
+  languageName: node
+  linkType: hard
+
+"eslint-scope@npm:^8.4.0":
+  version: 8.4.0
+  resolution: "eslint-scope@npm:8.4.0"
+  dependencies:
+    esrecurse: "npm:^4.3.0"
+    estraverse: "npm:^5.2.0"
+  checksum: 10c0/407f6c600204d0f3705bd557f81bd0189e69cd7996f408f8971ab5779c0af733d1af2f1412066b40ee1588b085874fc37a2333986c6521669cdbdd36ca5058e0
+  languageName: node
+  linkType: hard
+
+"eslint-visitor-keys@npm:^3.4.3":
+  version: 3.4.3
+  resolution: "eslint-visitor-keys@npm:3.4.3"
+  checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820
+  languageName: node
+  linkType: hard
+
+"eslint-visitor-keys@npm:^4.2.1":
+  version: 4.2.1
+  resolution: "eslint-visitor-keys@npm:4.2.1"
+  checksum: 10c0/fcd43999199d6740db26c58dbe0c2594623e31ca307e616ac05153c9272f12f1364f5a0b1917a8e962268fdecc6f3622c1c2908b4fcc2e047a106fe6de69dc43
+  languageName: node
+  linkType: hard
+
+"eslint@npm:^9.37.0":
+  version: 9.37.0
+  resolution: "eslint@npm:9.37.0"
+  dependencies:
+    "@eslint-community/eslint-utils": "npm:^4.8.0"
+    "@eslint-community/regexpp": "npm:^4.12.1"
+    "@eslint/config-array": "npm:^0.21.0"
+    "@eslint/config-helpers": "npm:^0.4.0"
+    "@eslint/core": "npm:^0.16.0"
+    "@eslint/eslintrc": "npm:^3.3.1"
+    "@eslint/js": "npm:9.37.0"
+    "@eslint/plugin-kit": "npm:^0.4.0"
+    "@humanfs/node": "npm:^0.16.6"
+    "@humanwhocodes/module-importer": "npm:^1.0.1"
+    "@humanwhocodes/retry": "npm:^0.4.2"
+    "@types/estree": "npm:^1.0.6"
+    "@types/json-schema": "npm:^7.0.15"
+    ajv: "npm:^6.12.4"
+    chalk: "npm:^4.0.0"
+    cross-spawn: "npm:^7.0.6"
+    debug: "npm:^4.3.2"
+    escape-string-regexp: "npm:^4.0.0"
+    eslint-scope: "npm:^8.4.0"
+    eslint-visitor-keys: "npm:^4.2.1"
+    espree: "npm:^10.4.0"
+    esquery: "npm:^1.5.0"
+    esutils: "npm:^2.0.2"
+    fast-deep-equal: "npm:^3.1.3"
+    file-entry-cache: "npm:^8.0.0"
+    find-up: "npm:^5.0.0"
+    glob-parent: "npm:^6.0.2"
+    ignore: "npm:^5.2.0"
+    imurmurhash: "npm:^0.1.4"
+    is-glob: "npm:^4.0.0"
+    json-stable-stringify-without-jsonify: "npm:^1.0.1"
+    lodash.merge: "npm:^4.6.2"
+    minimatch: "npm:^3.1.2"
+    natural-compare: "npm:^1.4.0"
+    optionator: "npm:^0.9.3"
+  peerDependencies:
+    jiti: "*"
+  peerDependenciesMeta:
+    jiti:
+      optional: true
+  bin:
+    eslint: bin/eslint.js
+  checksum: 10c0/30b71350b0e43542eeffa6f7380ed85c960055dde8003f17bf87d209a4a9afc6091bc0419aa32f86853e7ecef18790bdc4d678112b89dbebe61b69efcb1100e1
+  languageName: node
+  linkType: hard
+
+"espree@npm:^10.0.1, espree@npm:^10.4.0":
+  version: 10.4.0
+  resolution: "espree@npm:10.4.0"
+  dependencies:
+    acorn: "npm:^8.15.0"
+    acorn-jsx: "npm:^5.3.2"
+    eslint-visitor-keys: "npm:^4.2.1"
+  checksum: 10c0/c63fe06131c26c8157b4083313cb02a9a54720a08e21543300e55288c40e06c3fc284bdecf108d3a1372c5934a0a88644c98714f38b6ae8ed272b40d9ea08d6b
+  languageName: node
+  linkType: hard
+
 "esprima@npm:^4.0.0":
   version: 4.0.1
   resolution: "esprima@npm:4.0.1"
@@ -2698,6 +3535,31 @@ __metadata:
   languageName: node
   linkType: hard
 
+"esquery@npm:^1.5.0":
+  version: 1.6.0
+  resolution: "esquery@npm:1.6.0"
+  dependencies:
+    estraverse: "npm:^5.1.0"
+  checksum: 10c0/cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2
+  languageName: node
+  linkType: hard
+
+"esrecurse@npm:^4.3.0":
+  version: 4.3.0
+  resolution: "esrecurse@npm:4.3.0"
+  dependencies:
+    estraverse: "npm:^5.2.0"
+  checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5
+  languageName: node
+  linkType: hard
+
+"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0":
+  version: 5.3.0
+  resolution: "estraverse@npm:5.3.0"
+  checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107
+  languageName: node
+  linkType: hard
+
 "estree-walker@npm:^2.0.2":
   version: 2.0.2
   resolution: "estree-walker@npm:2.0.2"
@@ -2705,6 +3567,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"esutils@npm:^2.0.2":
+  version: 2.0.3
+  resolution: "esutils@npm:2.0.3"
+  checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7
+  languageName: node
+  linkType: hard
+
 "events-universal@npm:^1.0.0":
   version: 1.0.1
   resolution: "events-universal@npm:1.0.1"
@@ -2787,13 +3656,33 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.1.0":
+"fast-glob@npm:^3.3.2":
+  version: 3.3.3
+  resolution: "fast-glob@npm:3.3.3"
+  dependencies:
+    "@nodelib/fs.stat": "npm:^2.0.2"
+    "@nodelib/fs.walk": "npm:^1.2.3"
+    glob-parent: "npm:^5.1.2"
+    merge2: "npm:^1.3.0"
+    micromatch: "npm:^4.0.8"
+  checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe
+  languageName: node
+  linkType: hard
+
+"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0":
   version: 2.1.0
   resolution: "fast-json-stable-stringify@npm:2.1.0"
   checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b
   languageName: node
   linkType: hard
 
+"fast-levenshtein@npm:^2.0.6":
+  version: 2.0.6
+  resolution: "fast-levenshtein@npm:2.0.6"
+  checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4
+  languageName: node
+  linkType: hard
+
 "fast-uri@npm:^3.0.1":
   version: 3.1.0
   resolution: "fast-uri@npm:3.1.0"
@@ -2801,6 +3690,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"fastq@npm:^1.6.0":
+  version: 1.19.1
+  resolution: "fastq@npm:1.19.1"
+  dependencies:
+    reusify: "npm:^1.0.4"
+  checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630
+  languageName: node
+  linkType: hard
+
 "fb-watchman@npm:^2.0.2":
   version: 2.0.2
   resolution: "fb-watchman@npm:2.0.2"
@@ -2822,6 +3720,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"file-entry-cache@npm:^8.0.0":
+  version: 8.0.0
+  resolution: "file-entry-cache@npm:8.0.0"
+  dependencies:
+    flat-cache: "npm:^4.0.0"
+  checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638
+  languageName: node
+  linkType: hard
+
 "file-uri-to-path@npm:1.0.0":
   version: 1.0.0
   resolution: "file-uri-to-path@npm:1.0.0"
@@ -2848,6 +3755,42 @@ __metadata:
   languageName: node
   linkType: hard
 
+"find-up@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "find-up@npm:5.0.0"
+  dependencies:
+    locate-path: "npm:^6.0.0"
+    path-exists: "npm:^4.0.0"
+  checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a
+  languageName: node
+  linkType: hard
+
+"flat-cache@npm:^4.0.0":
+  version: 4.0.1
+  resolution: "flat-cache@npm:4.0.1"
+  dependencies:
+    flatted: "npm:^3.2.9"
+    keyv: "npm:^4.5.4"
+  checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc
+  languageName: node
+  linkType: hard
+
+"flatted@npm:^3.2.9":
+  version: 3.3.3
+  resolution: "flatted@npm:3.3.3"
+  checksum: 10c0/e957a1c6b0254aa15b8cce8533e24165abd98fadc98575db082b786b5da1b7d72062b81bfdcd1da2f4d46b6ed93bec2434e62333e9b4261d79ef2e75a10dd538
+  languageName: node
+  linkType: hard
+
+"for-each@npm:^0.3.3, for-each@npm:^0.3.5":
+  version: 0.3.5
+  resolution: "for-each@npm:0.3.5"
+  dependencies:
+    is-callable: "npm:^1.2.7"
+  checksum: 10c0/0e0b50f6a843a282637d43674d1fb278dda1dd85f4f99b640024cfb10b85058aac0cc781bf689d5fe50b4b7f638e91e548560723a4e76e04fe96ae35ef039cee
+  languageName: node
+  linkType: hard
+
 "foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1":
   version: 3.3.1
   resolution: "foreground-child@npm:3.3.1"
@@ -2927,6 +3870,34 @@ __metadata:
   languageName: node
   linkType: hard
 
+"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8":
+  version: 1.1.8
+  resolution: "function.prototype.name@npm:1.1.8"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.3"
+    define-properties: "npm:^1.2.1"
+    functions-have-names: "npm:^1.2.3"
+    hasown: "npm:^2.0.2"
+    is-callable: "npm:^1.2.7"
+  checksum: 10c0/e920a2ab52663005f3cbe7ee3373e3c71c1fb5558b0b0548648cdf3e51961085032458e26c71ff1a8c8c20e7ee7caeb03d43a5d1fa8610c459333323a2e71253
+  languageName: node
+  linkType: hard
+
+"functions-have-names@npm:^1.2.3":
+  version: 1.2.3
+  resolution: "functions-have-names@npm:1.2.3"
+  checksum: 10c0/33e77fd29bddc2d9bb78ab3eb854c165909201f88c75faa8272e35899e2d35a8a642a15e7420ef945e1f64a9670d6aa3ec744106b2aa42be68ca5114025954ca
+  languageName: node
+  linkType: hard
+
+"generator-function@npm:^2.0.0":
+  version: 2.0.1
+  resolution: "generator-function@npm:2.0.1"
+  checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8
+  languageName: node
+  linkType: hard
+
 "gensync@npm:^1.0.0-beta.2":
   version: 1.0.0-beta.2
   resolution: "gensync@npm:1.0.0-beta.2"
@@ -2941,6 +3912,27 @@ __metadata:
   languageName: node
   linkType: hard
 
+"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0":
+  version: 1.3.1
+  resolution: "get-intrinsic@npm:1.3.1"
+  dependencies:
+    async-function: "npm:^1.0.0"
+    async-generator-function: "npm:^1.0.0"
+    call-bind-apply-helpers: "npm:^1.0.2"
+    es-define-property: "npm:^1.0.1"
+    es-errors: "npm:^1.3.0"
+    es-object-atoms: "npm:^1.1.1"
+    function-bind: "npm:^1.1.2"
+    generator-function: "npm:^2.0.0"
+    get-proto: "npm:^1.0.1"
+    gopd: "npm:^1.2.0"
+    has-symbols: "npm:^1.1.0"
+    hasown: "npm:^2.0.2"
+    math-intrinsics: "npm:^1.1.0"
+  checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d
+  languageName: node
+  linkType: hard
+
 "get-package-type@npm:^0.1.0":
   version: 0.1.0
   resolution: "get-package-type@npm:0.1.0"
@@ -2948,6 +3940,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"get-proto@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "get-proto@npm:1.0.1"
+  dependencies:
+    dunder-proto: "npm:^1.0.1"
+    es-object-atoms: "npm:^1.0.0"
+  checksum: 10c0/9224acb44603c5526955e83510b9da41baf6ae73f7398875fba50edc5e944223a89c4a72b070fcd78beb5f7bdda58ecb6294adc28f7acfc0da05f76a2399643c
+  languageName: node
+  linkType: hard
+
 "get-stream@npm:^6.0.0":
   version: 6.0.1
   resolution: "get-stream@npm:6.0.1"
@@ -2955,6 +3957,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"get-symbol-description@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "get-symbol-description@npm:1.1.0"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    es-errors: "npm:^1.3.0"
+    get-intrinsic: "npm:^1.2.6"
+  checksum: 10c0/d6a7d6afca375779a4b307738c9e80dbf7afc0bdbe5948768d54ab9653c865523d8920e670991a925936eb524b7cb6a6361d199a760b21d0ca7620194455aa4b
+  languageName: node
+  linkType: hard
+
 "github-from-package@npm:0.0.0":
   version: 0.0.0
   resolution: "github-from-package@npm:0.0.0"
@@ -2984,6 +3997,24 @@ __metadata:
   languageName: node
   linkType: hard
 
+"glob-parent@npm:^5.1.2":
+  version: 5.1.2
+  resolution: "glob-parent@npm:5.1.2"
+  dependencies:
+    is-glob: "npm:^4.0.1"
+  checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee
+  languageName: node
+  linkType: hard
+
+"glob-parent@npm:^6.0.2":
+  version: 6.0.2
+  resolution: "glob-parent@npm:6.0.2"
+  dependencies:
+    is-glob: "npm:^4.0.3"
+  checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8
+  languageName: node
+  linkType: hard
+
 "glob@npm:^10.2.2, glob@npm:^10.3.10":
   version: 10.4.5
   resolution: "glob@npm:10.4.5"
@@ -3030,6 +4061,23 @@ __metadata:
   languageName: node
   linkType: hard
 
+"globals@npm:^14.0.0":
+  version: 14.0.0
+  resolution: "globals@npm:14.0.0"
+  checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d
+  languageName: node
+  linkType: hard
+
+"globalthis@npm:^1.0.4":
+  version: 1.0.4
+  resolution: "globalthis@npm:1.0.4"
+  dependencies:
+    define-properties: "npm:^1.2.1"
+    gopd: "npm:^1.0.1"
+  checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846
+  languageName: node
+  linkType: hard
+
 "glsl-tokenizer@npm:^2.1.5":
   version: 2.1.5
   resolution: "glsl-tokenizer@npm:2.1.5"
@@ -3039,6 +4087,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"gopd@npm:^1.0.1, gopd@npm:^1.2.0":
+  version: 1.2.0
+  resolution: "gopd@npm:1.2.0"
+  checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead
+  languageName: node
+  linkType: hard
+
 "gpu-mock.js@github:weagle08/gpu-mock.js":
   version: 1.3.1
   resolution: "gpu-mock.js@https://github.com/weagle08/gpu-mock.js.git#commit=7f3d7a75d29e34c5098d6102fce006c53b5df50d"
@@ -3053,6 +4108,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"graphemer@npm:^1.4.0":
+  version: 1.4.0
+  resolution: "graphemer@npm:1.4.0"
+  checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31
+  languageName: node
+  linkType: hard
+
 "handlebars@npm:^4.7.8":
   version: 4.7.8
   resolution: "handlebars@npm:4.7.8"
@@ -3071,6 +4133,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"has-bigints@npm:^1.0.2":
+  version: 1.1.0
+  resolution: "has-bigints@npm:1.1.0"
+  checksum: 10c0/2de0cdc4a1ccf7a1e75ffede1876994525ac03cc6f5ae7392d3415dd475cd9eee5bceec63669ab61aa997ff6cceebb50ef75561c7002bed8988de2b9d1b40788
+  languageName: node
+  linkType: hard
+
 "has-flag@npm:^4.0.0":
   version: 4.0.0
   resolution: "has-flag@npm:4.0.0"
@@ -3078,6 +4147,40 @@ __metadata:
   languageName: node
   linkType: hard
 
+"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "has-property-descriptors@npm:1.0.2"
+  dependencies:
+    es-define-property: "npm:^1.0.0"
+  checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236
+  languageName: node
+  linkType: hard
+
+"has-proto@npm:^1.2.0":
+  version: 1.2.0
+  resolution: "has-proto@npm:1.2.0"
+  dependencies:
+    dunder-proto: "npm:^1.0.0"
+  checksum: 10c0/46538dddab297ec2f43923c3d35237df45d8c55a6fc1067031e04c13ed8a9a8f94954460632fd4da84c31a1721eefee16d901cbb1ae9602bab93bb6e08f93b95
+  languageName: node
+  linkType: hard
+
+"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "has-symbols@npm:1.1.0"
+  checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e
+  languageName: node
+  linkType: hard
+
+"has-tostringtag@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "has-tostringtag@npm:1.0.2"
+  dependencies:
+    has-symbols: "npm:^1.0.3"
+  checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c
+  languageName: node
+  linkType: hard
+
 "hasown@npm:^2.0.2":
   version: 2.0.2
   resolution: "hasown@npm:2.0.2"
@@ -3153,6 +4256,30 @@ __metadata:
   languageName: node
   linkType: hard
 
+"ignore@npm:^5.2.0":
+  version: 5.3.2
+  resolution: "ignore@npm:5.3.2"
+  checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337
+  languageName: node
+  linkType: hard
+
+"ignore@npm:^7.0.0":
+  version: 7.0.5
+  resolution: "ignore@npm:7.0.5"
+  checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d
+  languageName: node
+  linkType: hard
+
+"import-fresh@npm:^3.2.1":
+  version: 3.3.1
+  resolution: "import-fresh@npm:3.3.1"
+  dependencies:
+    parent-module: "npm:^1.0.0"
+    resolve-from: "npm:^4.0.0"
+  checksum: 10c0/bf8cc494872fef783249709385ae883b447e3eb09db0ebd15dcead7d9afe7224dad7bd7591c6b73b0b19b3c0f9640eb8ee884f01cfaf2887ab995b0b36a0cbec
+  languageName: node
+  linkType: hard
+
 "import-lazy@npm:~4.0.0":
   version: 4.0.0
   resolution: "import-lazy@npm:4.0.0"
@@ -3210,6 +4337,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"internal-slot@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "internal-slot@npm:1.1.0"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    hasown: "npm:^2.0.2"
+    side-channel: "npm:^1.1.0"
+  checksum: 10c0/03966f5e259b009a9bf1a78d60da920df198af4318ec004f57b8aef1dd3fe377fbc8cce63a96e8c810010302654de89f9e19de1cd8ad0061d15be28a695465c7
+  languageName: node
+  linkType: hard
+
 "ip-address@npm:^10.0.1":
   version: 10.0.1
   resolution: "ip-address@npm:10.0.1"
@@ -3217,6 +4355,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5":
+  version: 3.0.5
+  resolution: "is-array-buffer@npm:3.0.5"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.3"
+    get-intrinsic: "npm:^1.2.6"
+  checksum: 10c0/c5c9f25606e86dbb12e756694afbbff64bc8b348d1bc989324c037e1068695131930199d6ad381952715dad3a9569333817f0b1a72ce5af7f883ce802e49c83d
+  languageName: node
+  linkType: hard
+
 "is-arrayish@npm:^0.2.1":
   version: 0.2.1
   resolution: "is-arrayish@npm:0.2.1"
@@ -3224,7 +4373,46 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-core-module@npm:^2.16.0":
+"is-async-function@npm:^2.0.0":
+  version: 2.1.1
+  resolution: "is-async-function@npm:2.1.1"
+  dependencies:
+    async-function: "npm:^1.0.0"
+    call-bound: "npm:^1.0.3"
+    get-proto: "npm:^1.0.1"
+    has-tostringtag: "npm:^1.0.2"
+    safe-regex-test: "npm:^1.1.0"
+  checksum: 10c0/d70c236a5e82de6fc4d44368ffd0c2fee2b088b893511ce21e679da275a5ecc6015ff59a7d7e1bdd7ca39f71a8dbdd253cf8cce5c6b3c91cdd5b42b5ce677298
+  languageName: node
+  linkType: hard
+
+"is-bigint@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "is-bigint@npm:1.1.0"
+  dependencies:
+    has-bigints: "npm:^1.0.2"
+  checksum: 10c0/f4f4b905ceb195be90a6ea7f34323bf1c18e3793f18922e3e9a73c684c29eeeeff5175605c3a3a74cc38185fe27758f07efba3dbae812e5c5afbc0d2316b40e4
+  languageName: node
+  linkType: hard
+
+"is-boolean-object@npm:^1.2.1":
+  version: 1.2.2
+  resolution: "is-boolean-object@npm:1.2.2"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    has-tostringtag: "npm:^1.0.2"
+  checksum: 10c0/36ff6baf6bd18b3130186990026f5a95c709345c39cd368468e6c1b6ab52201e9fd26d8e1f4c066357b4938b0f0401e1a5000e08257787c1a02f3a719457001e
+  languageName: node
+  linkType: hard
+
+"is-callable@npm:^1.2.7":
+  version: 1.2.7
+  resolution: "is-callable@npm:1.2.7"
+  checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f
+  languageName: node
+  linkType: hard
+
+"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1":
   version: 2.16.1
   resolution: "is-core-module@npm:2.16.1"
   dependencies:
@@ -3233,6 +4421,43 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "is-data-view@npm:1.0.2"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    get-intrinsic: "npm:^1.2.6"
+    is-typed-array: "npm:^1.1.13"
+  checksum: 10c0/ef3548a99d7e7f1370ce21006baca6d40c73e9f15c941f89f0049c79714c873d03b02dae1c64b3f861f55163ecc16da06506c5b8a1d4f16650b3d9351c380153
+  languageName: node
+  linkType: hard
+
+"is-date-object@npm:^1.0.5, is-date-object@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "is-date-object@npm:1.1.0"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    has-tostringtag: "npm:^1.0.2"
+  checksum: 10c0/1a4d199c8e9e9cac5128d32e6626fa7805175af9df015620ac0d5d45854ccf348ba494679d872d37301032e35a54fc7978fba1687e8721b2139aea7870cafa2f
+  languageName: node
+  linkType: hard
+
+"is-extglob@npm:^2.1.1":
+  version: 2.1.1
+  resolution: "is-extglob@npm:2.1.1"
+  checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912
+  languageName: node
+  linkType: hard
+
+"is-finalizationregistry@npm:^1.1.0":
+  version: 1.1.1
+  resolution: "is-finalizationregistry@npm:1.1.1"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+  checksum: 10c0/818dff679b64f19e228a8205a1e2d09989a98e98def3a817f889208cfcbf918d321b251aadf2c05918194803ebd2eb01b14fc9d0b2bea53d984f4137bfca5e97
+  languageName: node
+  linkType: hard
+
 "is-fullwidth-code-point@npm:^3.0.0":
   version: 3.0.0
   resolution: "is-fullwidth-code-point@npm:3.0.0"
@@ -3247,6 +4472,28 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-generator-function@npm:^1.0.10":
+  version: 1.1.2
+  resolution: "is-generator-function@npm:1.1.2"
+  dependencies:
+    call-bound: "npm:^1.0.4"
+    generator-function: "npm:^2.0.0"
+    get-proto: "npm:^1.0.1"
+    has-tostringtag: "npm:^1.0.2"
+    safe-regex-test: "npm:^1.1.0"
+  checksum: 10c0/83da102e89c3e3b71d67b51d47c9f9bc862bceb58f87201727e27f7fa19d1d90b0ab223644ecaee6fc6e3d2d622bb25c966fbdaf87c59158b01ce7c0fe2fa372
+  languageName: node
+  linkType: hard
+
+"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3":
+  version: 4.0.3
+  resolution: "is-glob@npm:4.0.3"
+  dependencies:
+    is-extglob: "npm:^2.1.1"
+  checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a
+  languageName: node
+  linkType: hard
+
 "is-lambda@npm:^1.0.1":
   version: 1.0.1
   resolution: "is-lambda@npm:1.0.1"
@@ -3254,6 +4501,30 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-map@npm:^2.0.3":
+  version: 2.0.3
+  resolution: "is-map@npm:2.0.3"
+  checksum: 10c0/2c4d431b74e00fdda7162cd8e4b763d6f6f217edf97d4f8538b94b8702b150610e2c64961340015fe8df5b1fcee33ccd2e9b62619c4a8a3a155f8de6d6d355fc
+  languageName: node
+  linkType: hard
+
+"is-negative-zero@npm:^2.0.3":
+  version: 2.0.3
+  resolution: "is-negative-zero@npm:2.0.3"
+  checksum: 10c0/bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e
+  languageName: node
+  linkType: hard
+
+"is-number-object@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "is-number-object@npm:1.1.1"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    has-tostringtag: "npm:^1.0.2"
+  checksum: 10c0/97b451b41f25135ff021d85c436ff0100d84a039bb87ffd799cbcdbea81ef30c464ced38258cdd34f080be08fc3b076ca1f472086286d2aa43521d6ec6a79f53
+  languageName: node
+  linkType: hard
+
 "is-number@npm:^7.0.0":
   version: 7.0.0
   resolution: "is-number@npm:7.0.0"
@@ -3261,6 +4532,34 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-regex@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "is-regex@npm:1.2.1"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    gopd: "npm:^1.2.0"
+    has-tostringtag: "npm:^1.0.2"
+    hasown: "npm:^2.0.2"
+  checksum: 10c0/1d3715d2b7889932349241680032e85d0b492cfcb045acb75ffc2c3085e8d561184f1f7e84b6f8321935b4aea39bc9c6ba74ed595b57ce4881a51dfdbc214e04
+  languageName: node
+  linkType: hard
+
+"is-set@npm:^2.0.3":
+  version: 2.0.3
+  resolution: "is-set@npm:2.0.3"
+  checksum: 10c0/f73732e13f099b2dc879c2a12341cfc22ccaca8dd504e6edae26484bd5707a35d503fba5b4daad530a9b088ced1ae6c9d8200fd92e09b428fe14ea79ce8080b7
+  languageName: node
+  linkType: hard
+
+"is-shared-array-buffer@npm:^1.0.4":
+  version: 1.0.4
+  resolution: "is-shared-array-buffer@npm:1.0.4"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+  checksum: 10c0/65158c2feb41ff1edd6bbd6fd8403a69861cf273ff36077982b5d4d68e1d59278c71691216a4a64632bd76d4792d4d1d2553901b6666d84ade13bba5ea7bc7db
+  languageName: node
+  linkType: hard
+
 "is-stream@npm:^2.0.0":
   version: 2.0.1
   resolution: "is-stream@npm:2.0.1"
@@ -3268,6 +4567,62 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-string@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "is-string@npm:1.1.1"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    has-tostringtag: "npm:^1.0.2"
+  checksum: 10c0/2f518b4e47886bb81567faba6ffd0d8a8333cf84336e2e78bf160693972e32ad00fe84b0926491cc598dee576fdc55642c92e62d0cbe96bf36f643b6f956f94d
+  languageName: node
+  linkType: hard
+
+"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "is-symbol@npm:1.1.1"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    has-symbols: "npm:^1.1.0"
+    safe-regex-test: "npm:^1.1.0"
+  checksum: 10c0/f08f3e255c12442e833f75a9e2b84b2d4882fdfd920513cf2a4a2324f0a5b076c8fd913778e3ea5d258d5183e9d92c0cd20e04b03ab3df05316b049b2670af1e
+  languageName: node
+  linkType: hard
+
+"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15":
+  version: 1.1.15
+  resolution: "is-typed-array@npm:1.1.15"
+  dependencies:
+    which-typed-array: "npm:^1.1.16"
+  checksum: 10c0/415511da3669e36e002820584e264997ffe277ff136643a3126cc949197e6ca3334d0f12d084e83b1994af2e9c8141275c741cf2b7da5a2ff62dd0cac26f76c4
+  languageName: node
+  linkType: hard
+
+"is-weakmap@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "is-weakmap@npm:2.0.2"
+  checksum: 10c0/443c35bb86d5e6cc5929cd9c75a4024bb0fff9586ed50b092f94e700b89c43a33b186b76dbc6d54f3d3d09ece689ab38dcdc1af6a482cbe79c0f2da0a17f1299
+  languageName: node
+  linkType: hard
+
+"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "is-weakref@npm:1.1.1"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+  checksum: 10c0/8e0a9c07b0c780949a100e2cab2b5560a48ecd4c61726923c1a9b77b6ab0aa0046c9e7fb2206042296817045376dee2c8ab1dabe08c7c3dfbf195b01275a085b
+  languageName: node
+  linkType: hard
+
+"is-weakset@npm:^2.0.3":
+  version: 2.0.4
+  resolution: "is-weakset@npm:2.0.4"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    get-intrinsic: "npm:^1.2.6"
+  checksum: 10c0/6491eba08acb8dc9532da23cb226b7d0192ede0b88f16199e592e4769db0a077119c1f5d2283d1e0d16d739115f70046e887e477eb0e66cd90e1bb29f28ba647
+  languageName: node
+  linkType: hard
+
 "isarray@npm:0.0.1":
   version: 0.0.1
   resolution: "isarray@npm:0.0.1"
@@ -3275,6 +4630,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"isarray@npm:^2.0.5":
+  version: 2.0.5
+  resolution: "isarray@npm:2.0.5"
+  checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd
+  languageName: node
+  linkType: hard
+
 "isexe@npm:^2.0.0":
   version: 2.0.0
   resolution: "isexe@npm:2.0.0"
@@ -3827,6 +5189,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"js-yaml@npm:^4.1.0":
+  version: 4.1.0
+  resolution: "js-yaml@npm:4.1.0"
+  dependencies:
+    argparse: "npm:^2.0.1"
+  bin:
+    js-yaml: bin/js-yaml.js
+  checksum: 10c0/184a24b4eaacfce40ad9074c64fd42ac83cf74d8c8cd137718d456ced75051229e5061b8633c3366b8aada17945a7a356b337828c19da92b51ae62126575018f
+  languageName: node
+  linkType: hard
+
 "jsesc@npm:^3.0.2":
   version: 3.1.0
   resolution: "jsesc@npm:3.1.0"
@@ -3836,6 +5209,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"json-buffer@npm:3.0.1":
+  version: 3.0.1
+  resolution: "json-buffer@npm:3.0.1"
+  checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7
+  languageName: node
+  linkType: hard
+
 "json-parse-even-better-errors@npm:^2.3.0":
   version: 2.3.1
   resolution: "json-parse-even-better-errors@npm:2.3.1"
@@ -3843,10 +5223,35 @@ __metadata:
   languageName: node
   linkType: hard
 
-"json-schema-traverse@npm:^1.0.0":
-  version: 1.0.0
-  resolution: "json-schema-traverse@npm:1.0.0"
-  checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6
+"json-schema-traverse@npm:^0.4.1":
+  version: 0.4.1
+  resolution: "json-schema-traverse@npm:0.4.1"
+  checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce
+  languageName: node
+  linkType: hard
+
+"json-schema-traverse@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "json-schema-traverse@npm:1.0.0"
+  checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6
+  languageName: node
+  linkType: hard
+
+"json-stable-stringify-without-jsonify@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "json-stable-stringify-without-jsonify@npm:1.0.1"
+  checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5
+  languageName: node
+  linkType: hard
+
+"json5@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "json5@npm:1.0.2"
+  dependencies:
+    minimist: "npm:^1.2.0"
+  bin:
+    json5: lib/cli.js
+  checksum: 10c0/9ee316bf21f000b00752e6c2a3b79ecf5324515a5c60ee88983a1910a45426b643a4f3461657586e8aeca87aaf96f0a519b0516d2ae527a6c3e7eed80f68717f
   languageName: node
   linkType: hard
 
@@ -3872,6 +5277,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"keyv@npm:^4.5.4":
+  version: 4.5.4
+  resolution: "keyv@npm:4.5.4"
+  dependencies:
+    json-buffer: "npm:3.0.1"
+  checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e
+  languageName: node
+  linkType: hard
+
 "kolorist@npm:^1.8.0":
   version: 1.8.0
   resolution: "kolorist@npm:1.8.0"
@@ -3886,6 +5300,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"levn@npm:^0.4.1":
+  version: 0.4.1
+  resolution: "levn@npm:0.4.1"
+  dependencies:
+    prelude-ls: "npm:^1.2.1"
+    type-check: "npm:~0.4.0"
+  checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e
+  languageName: node
+  linkType: hard
+
 "lines-and-columns@npm:^1.1.6":
   version: 1.2.4
   resolution: "lines-and-columns@npm:1.2.4"
@@ -3913,6 +5337,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"locate-path@npm:^6.0.0":
+  version: 6.0.0
+  resolution: "locate-path@npm:6.0.0"
+  dependencies:
+    p-locate: "npm:^5.0.0"
+  checksum: 10c0/d3972ab70dfe58ce620e64265f90162d247e87159b6126b01314dd67be43d50e96a50b517bce2d9452a79409c7614054c277b5232377de50416564a77ac7aad3
+  languageName: node
+  linkType: hard
+
 "lodash.memoize@npm:^4.1.2":
   version: 4.1.2
   resolution: "lodash.memoize@npm:4.1.2"
@@ -3920,6 +5353,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"lodash.merge@npm:^4.6.2":
+  version: 4.6.2
+  resolution: "lodash.merge@npm:4.6.2"
+  checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506
+  languageName: node
+  linkType: hard
+
 "lodash@npm:~4.17.15":
   version: 4.17.21
   resolution: "lodash@npm:4.17.21"
@@ -4032,6 +5472,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"math-intrinsics@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "math-intrinsics@npm:1.1.0"
+  checksum: 10c0/7579ff94e899e2f76ab64491d76cf606274c874d8f2af4a442c016bd85688927fcfca157ba6bf74b08e9439dc010b248ce05b96cc7c126a354c3bae7fcb48b7f
+  languageName: node
+  linkType: hard
+
 "merge-stream@npm:^2.0.0":
   version: 2.0.0
   resolution: "merge-stream@npm:2.0.0"
@@ -4039,6 +5486,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"merge2@npm:^1.3.0":
+  version: 1.4.1
+  resolution: "merge2@npm:1.4.1"
+  checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb
+  languageName: node
+  linkType: hard
+
 "micromatch@npm:^4.0.8":
   version: 4.0.8
   resolution: "micromatch@npm:4.0.8"
@@ -4072,7 +5526,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1":
+"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
   version: 3.1.2
   resolution: "minimatch@npm:3.1.2"
   dependencies:
@@ -4090,7 +5544,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5":
+"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
   version: 1.2.8
   resolution: "minimist@npm:1.2.8"
   checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
@@ -4233,7 +5687,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ms@npm:^2.1.3":
+"ms@npm:^2.1.1, ms@npm:^2.1.3":
   version: 2.1.3
   resolution: "ms@npm:2.1.3"
   checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
@@ -4410,6 +5864,69 @@ __metadata:
   languageName: node
   linkType: hard
 
+"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4":
+  version: 1.13.4
+  resolution: "object-inspect@npm:1.13.4"
+  checksum: 10c0/d7f8711e803b96ea3191c745d6f8056ce1f2496e530e6a19a0e92d89b0fa3c76d910c31f0aa270432db6bd3b2f85500a376a83aaba849a8d518c8845b3211692
+  languageName: node
+  linkType: hard
+
+"object-keys@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "object-keys@npm:1.1.1"
+  checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d
+  languageName: node
+  linkType: hard
+
+"object.assign@npm:^4.1.7":
+  version: 4.1.7
+  resolution: "object.assign@npm:4.1.7"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.3"
+    define-properties: "npm:^1.2.1"
+    es-object-atoms: "npm:^1.0.0"
+    has-symbols: "npm:^1.1.0"
+    object-keys: "npm:^1.1.1"
+  checksum: 10c0/3b2732bd860567ea2579d1567525168de925a8d852638612846bd8082b3a1602b7b89b67b09913cbb5b9bd6e95923b2ae73580baa9d99cb4e990564e8cbf5ddc
+  languageName: node
+  linkType: hard
+
+"object.fromentries@npm:^2.0.8":
+  version: 2.0.8
+  resolution: "object.fromentries@npm:2.0.8"
+  dependencies:
+    call-bind: "npm:^1.0.7"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.2"
+    es-object-atoms: "npm:^1.0.0"
+  checksum: 10c0/cd4327e6c3369cfa805deb4cbbe919bfb7d3aeebf0bcaba291bb568ea7169f8f8cdbcabe2f00b40db0c20cd20f08e11b5f3a5a36fb7dd3fe04850c50db3bf83b
+  languageName: node
+  linkType: hard
+
+"object.groupby@npm:^1.0.3":
+  version: 1.0.3
+  resolution: "object.groupby@npm:1.0.3"
+  dependencies:
+    call-bind: "npm:^1.0.7"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.2"
+  checksum: 10c0/60d0455c85c736fbfeda0217d1a77525956f76f7b2495edeca9e9bbf8168a45783199e77b894d30638837c654d0cc410e0e02cbfcf445bc8de71c3da1ede6a9c
+  languageName: node
+  linkType: hard
+
+"object.values@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "object.values@npm:1.2.1"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.3"
+    define-properties: "npm:^1.2.1"
+    es-object-atoms: "npm:^1.0.0"
+  checksum: 10c0/3c47814fdc64842ae3d5a74bc9d06bdd8d21563c04d9939bf6716a9c00596a4ebc342552f8934013d1ec991c74e3671b26710a0c51815f0b603795605ab6b2c9
+  languageName: node
+  linkType: hard
+
 "once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
   version: 1.4.0
   resolution: "once@npm:1.4.0"
@@ -4428,6 +5945,20 @@ __metadata:
   languageName: node
   linkType: hard
 
+"optionator@npm:^0.9.3":
+  version: 0.9.4
+  resolution: "optionator@npm:0.9.4"
+  dependencies:
+    deep-is: "npm:^0.1.3"
+    fast-levenshtein: "npm:^2.0.6"
+    levn: "npm:^0.4.1"
+    prelude-ls: "npm:^1.2.1"
+    type-check: "npm:^0.4.0"
+    word-wrap: "npm:^1.2.5"
+  checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675
+  languageName: node
+  linkType: hard
+
 "ordered-read-streams@npm:^2.0.0":
   version: 2.0.0
   resolution: "ordered-read-streams@npm:2.0.0"
@@ -4437,6 +5968,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"own-keys@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "own-keys@npm:1.0.1"
+  dependencies:
+    get-intrinsic: "npm:^1.2.6"
+    object-keys: "npm:^1.1.1"
+    safe-push-apply: "npm:^1.0.0"
+  checksum: 10c0/6dfeb3455bff92ec3f16a982d4e3e65676345f6902d9f5ded1d8265a6318d0200ce461956d6d1c70053c7fe9f9fe65e552faac03f8140d37ef0fdd108e67013a
+  languageName: node
+  linkType: hard
+
 "p-limit@npm:^2.2.0":
   version: 2.3.0
   resolution: "p-limit@npm:2.3.0"
@@ -4446,7 +5988,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"p-limit@npm:^3.1.0":
+"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0":
   version: 3.1.0
   resolution: "p-limit@npm:3.1.0"
   dependencies:
@@ -4464,6 +6006,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"p-locate@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "p-locate@npm:5.0.0"
+  dependencies:
+    p-limit: "npm:^3.0.2"
+  checksum: 10c0/2290d627ab7903b8b70d11d384fee714b797f6040d9278932754a6860845c4d3190603a0772a663c8cb5a7b21d1b16acb3a6487ebcafa9773094edc3dfe6009a
+  languageName: node
+  linkType: hard
+
 "p-map@npm:^4.0.0":
   version: 4.0.0
   resolution: "p-map@npm:4.0.0"
@@ -4494,6 +6045,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"parent-module@npm:^1.0.0":
+  version: 1.0.1
+  resolution: "parent-module@npm:1.0.1"
+  dependencies:
+    callsites: "npm:^3.0.0"
+  checksum: 10c0/c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556
+  languageName: node
+  linkType: hard
+
 "parse-json@npm:^5.2.0":
   version: 5.2.0
   resolution: "parse-json@npm:5.2.0"
@@ -4627,6 +6187,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"possible-typed-array-names@npm:^1.0.0":
+  version: 1.1.0
+  resolution: "possible-typed-array-names@npm:1.1.0"
+  checksum: 10c0/c810983414142071da1d644662ce4caebce890203eb2bc7bf119f37f3fe5796226e117e6cca146b521921fa6531072674174a3325066ac66fce089a53e1e5196
+  languageName: node
+  linkType: hard
+
 "postcss@npm:^8.5.6":
   version: 8.5.6
   resolution: "postcss@npm:8.5.6"
@@ -4660,6 +6227,22 @@ __metadata:
   languageName: node
   linkType: hard
 
+"prelude-ls@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "prelude-ls@npm:1.2.1"
+  checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd
+  languageName: node
+  linkType: hard
+
+"prettier@npm:^3.6.2":
+  version: 3.6.2
+  resolution: "prettier@npm:3.6.2"
+  bin:
+    prettier: bin/prettier.cjs
+  checksum: 10c0/488cb2f2b99ec13da1e50074912870217c11edaddedeadc649b1244c749d15ba94e846423d062e2c4c9ae683e2d65f754de28889ba06e697ac4f988d44f45812
+  languageName: node
+  linkType: hard
+
 "pretty-format@npm:30.2.0, pretty-format@npm:^30.0.0":
   version: 30.2.0
   resolution: "pretty-format@npm:30.2.0"
@@ -4726,6 +6309,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"queue-microtask@npm:^1.2.2":
+  version: 1.2.3
+  resolution: "queue-microtask@npm:1.2.3"
+  checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102
+  languageName: node
+  linkType: hard
+
 "rc@npm:^1.2.7":
   version: 1.2.8
   resolution: "rc@npm:1.2.8"
@@ -4770,6 +6360,36 @@ __metadata:
   languageName: node
   linkType: hard
 
+"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9":
+  version: 1.0.10
+  resolution: "reflect.getprototypeof@npm:1.0.10"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.9"
+    es-errors: "npm:^1.3.0"
+    es-object-atoms: "npm:^1.0.0"
+    get-intrinsic: "npm:^1.2.7"
+    get-proto: "npm:^1.0.1"
+    which-builtin-type: "npm:^1.2.1"
+  checksum: 10c0/7facec28c8008876f8ab98e80b7b9cb4b1e9224353fd4756dda5f2a4ab0d30fa0a5074777c6df24e1e0af463a2697513b0a11e548d99cf52f21f7bc6ba48d3ac
+  languageName: node
+  linkType: hard
+
+"regexp.prototype.flags@npm:^1.5.4":
+  version: 1.5.4
+  resolution: "regexp.prototype.flags@npm:1.5.4"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    define-properties: "npm:^1.2.1"
+    es-errors: "npm:^1.3.0"
+    get-proto: "npm:^1.0.1"
+    gopd: "npm:^1.2.0"
+    set-function-name: "npm:^2.0.2"
+  checksum: 10c0/83b88e6115b4af1c537f8dabf5c3744032cb875d63bc05c288b1b8c0ef37cbe55353f95d8ca817e8843806e3e150b118bc624e4279b24b4776b4198232735a77
+  languageName: node
+  linkType: hard
+
 "require-directory@npm:^2.1.1":
   version: 2.1.1
   resolution: "require-directory@npm:2.1.1"
@@ -4793,6 +6413,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"resolve-from@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "resolve-from@npm:4.0.0"
+  checksum: 10c0/8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190
+  languageName: node
+  linkType: hard
+
 "resolve-from@npm:^5.0.0":
   version: 5.0.0
   resolution: "resolve-from@npm:5.0.0"
@@ -4800,7 +6427,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"resolve@npm:~1.22.1, resolve@npm:~1.22.2":
+"resolve@npm:^1.22.4, resolve@npm:~1.22.1, resolve@npm:~1.22.2":
   version: 1.22.10
   resolution: "resolve@npm:1.22.10"
   dependencies:
@@ -4813,7 +6440,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin":
+"resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin":
   version: 1.22.10
   resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d"
   dependencies:
@@ -4833,6 +6460,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"reusify@npm:^1.0.4":
+  version: 1.1.0
+  resolution: "reusify@npm:1.1.0"
+  checksum: 10c0/4eff0d4a5f9383566c7d7ec437b671cc51b25963bd61bf127c3f3d3f68e44a026d99b8d2f1ad344afff8d278a8fe70a8ea092650a716d22287e8bef7126bb2fa
+  languageName: node
+  linkType: hard
+
 "rimraf@npm:^6.0.1":
   version: 6.0.1
   resolution: "rimraf@npm:6.0.1"
@@ -4926,6 +6560,28 @@ __metadata:
   languageName: node
   linkType: hard
 
+"run-parallel@npm:^1.1.9":
+  version: 1.2.0
+  resolution: "run-parallel@npm:1.2.0"
+  dependencies:
+    queue-microtask: "npm:^1.2.2"
+  checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39
+  languageName: node
+  linkType: hard
+
+"safe-array-concat@npm:^1.1.3":
+  version: 1.1.3
+  resolution: "safe-array-concat@npm:1.1.3"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.2"
+    get-intrinsic: "npm:^1.2.6"
+    has-symbols: "npm:^1.1.0"
+    isarray: "npm:^2.0.5"
+  checksum: 10c0/43c86ffdddc461fb17ff8a17c5324f392f4868f3c7dd2c6a5d9f5971713bc5fd755667212c80eab9567595f9a7509cc2f83e590ddaebd1bd19b780f9c79f9a8d
+  languageName: node
+  linkType: hard
+
 "safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0":
   version: 5.2.1
   resolution: "safe-buffer@npm:5.2.1"
@@ -4933,6 +6589,27 @@ __metadata:
   languageName: node
   linkType: hard
 
+"safe-push-apply@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "safe-push-apply@npm:1.0.0"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    isarray: "npm:^2.0.5"
+  checksum: 10c0/831f1c9aae7436429e7862c7e46f847dfe490afac20d0ee61bae06108dbf5c745a0de3568ada30ccdd3eeb0864ca8331b2eef703abd69bfea0745b21fd320750
+  languageName: node
+  linkType: hard
+
+"safe-regex-test@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "safe-regex-test@npm:1.1.0"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    es-errors: "npm:^1.3.0"
+    is-regex: "npm:^1.2.1"
+  checksum: 10c0/f2c25281bbe5d39cddbbce7f86fca5ea9b3ce3354ea6cd7c81c31b006a5a9fff4286acc5450a3b9122c56c33eba69c56b9131ad751457b2b4a585825e6a10665
+  languageName: node
+  linkType: hard
+
 "safer-buffer@npm:>= 2.1.2 < 3.0.0":
   version: 2.1.2
   resolution: "safer-buffer@npm:2.1.2"
@@ -4958,6 +6635,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"semver@npm:^7.6.0":
+  version: 7.7.3
+  resolution: "semver@npm:7.7.3"
+  bin:
+    semver: bin/semver.js
+  checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e
+  languageName: node
+  linkType: hard
+
 "semver@npm:~7.5.4":
   version: 7.5.4
   resolution: "semver@npm:7.5.4"
@@ -4969,6 +6655,43 @@ __metadata:
   languageName: node
   linkType: hard
 
+"set-function-length@npm:^1.2.2":
+  version: 1.2.2
+  resolution: "set-function-length@npm:1.2.2"
+  dependencies:
+    define-data-property: "npm:^1.1.4"
+    es-errors: "npm:^1.3.0"
+    function-bind: "npm:^1.1.2"
+    get-intrinsic: "npm:^1.2.4"
+    gopd: "npm:^1.0.1"
+    has-property-descriptors: "npm:^1.0.2"
+  checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c
+  languageName: node
+  linkType: hard
+
+"set-function-name@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "set-function-name@npm:2.0.2"
+  dependencies:
+    define-data-property: "npm:^1.1.4"
+    es-errors: "npm:^1.3.0"
+    functions-have-names: "npm:^1.2.3"
+    has-property-descriptors: "npm:^1.0.2"
+  checksum: 10c0/fce59f90696c450a8523e754abb305e2b8c73586452619c2bad5f7bf38c7b6b4651895c9db895679c5bef9554339cf3ef1c329b66ece3eda7255785fbe299316
+  languageName: node
+  linkType: hard
+
+"set-proto@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "set-proto@npm:1.0.0"
+  dependencies:
+    dunder-proto: "npm:^1.0.1"
+    es-errors: "npm:^1.3.0"
+    es-object-atoms: "npm:^1.0.0"
+  checksum: 10c0/ca5c3ccbba479d07c30460e367e66337cec825560b11e8ba9c5ebe13a2a0d6021ae34eddf94ff3dfe17a3104dc1f191519cb6c48378b503e5c3f36393938776a
+  languageName: node
+  linkType: hard
+
 "shebang-command@npm:^2.0.0":
   version: 2.0.0
   resolution: "shebang-command@npm:2.0.0"
@@ -4985,6 +6708,54 @@ __metadata:
   languageName: node
   linkType: hard
 
+"side-channel-list@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "side-channel-list@npm:1.0.0"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    object-inspect: "npm:^1.13.3"
+  checksum: 10c0/644f4ac893456c9490ff388bf78aea9d333d5e5bfc64cfb84be8f04bf31ddc111a8d4b83b85d7e7e8a7b845bc185a9ad02c052d20e086983cf59f0be517d9b3d
+  languageName: node
+  linkType: hard
+
+"side-channel-map@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "side-channel-map@npm:1.0.1"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    es-errors: "npm:^1.3.0"
+    get-intrinsic: "npm:^1.2.5"
+    object-inspect: "npm:^1.13.3"
+  checksum: 10c0/010584e6444dd8a20b85bc926d934424bd809e1a3af941cace229f7fdcb751aada0fb7164f60c2e22292b7fa3c0ff0bce237081fd4cdbc80de1dc68e95430672
+  languageName: node
+  linkType: hard
+
+"side-channel-weakmap@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "side-channel-weakmap@npm:1.0.2"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    es-errors: "npm:^1.3.0"
+    get-intrinsic: "npm:^1.2.5"
+    object-inspect: "npm:^1.13.3"
+    side-channel-map: "npm:^1.0.1"
+  checksum: 10c0/71362709ac233e08807ccd980101c3e2d7efe849edc51455030327b059f6c4d292c237f94dc0685031dd11c07dd17a68afde235d6cf2102d949567f98ab58185
+  languageName: node
+  linkType: hard
+
+"side-channel@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "side-channel@npm:1.1.0"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    object-inspect: "npm:^1.13.3"
+    side-channel-list: "npm:^1.0.0"
+    side-channel-map: "npm:^1.0.1"
+    side-channel-weakmap: "npm:^1.0.2"
+  checksum: 10c0/cb20dad41eb032e6c24c0982e1e5a24963a28aa6122b4f05b3f3d6bf8ae7fd5474ef382c8f54a6a3ab86e0cac4d41a23bd64ede3970e5bfb50326ba02a7996e6
+  languageName: node
+  linkType: hard
+
 "signal-exit@npm:^3.0.3":
   version: 3.0.7
   resolution: "signal-exit@npm:3.0.7"
@@ -5110,6 +6881,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"stop-iteration-iterator@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "stop-iteration-iterator@npm:1.1.0"
+  dependencies:
+    es-errors: "npm:^1.3.0"
+    internal-slot: "npm:^1.1.0"
+  checksum: 10c0/de4e45706bb4c0354a4b1122a2b8cc45a639e86206807ce0baf390ee9218d3ef181923fa4d2b67443367c491aa255c5fbaa64bb74648e3c5b48299928af86c09
+  languageName: node
+  linkType: hard
+
 "streamx@npm:^2.12.5":
   version: 2.23.0
   resolution: "streamx@npm:2.23.0"
@@ -5160,6 +6941,44 @@ __metadata:
   languageName: node
   linkType: hard
 
+"string.prototype.trim@npm:^1.2.10":
+  version: 1.2.10
+  resolution: "string.prototype.trim@npm:1.2.10"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.2"
+    define-data-property: "npm:^1.1.4"
+    define-properties: "npm:^1.2.1"
+    es-abstract: "npm:^1.23.5"
+    es-object-atoms: "npm:^1.0.0"
+    has-property-descriptors: "npm:^1.0.2"
+  checksum: 10c0/8a8854241c4b54a948e992eb7dd6b8b3a97185112deb0037a134f5ba57541d8248dd610c966311887b6c2fd1181a3877bffb14d873ce937a344535dabcc648f8
+  languageName: node
+  linkType: hard
+
+"string.prototype.trimend@npm:^1.0.9":
+  version: 1.0.9
+  resolution: "string.prototype.trimend@npm:1.0.9"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.2"
+    define-properties: "npm:^1.2.1"
+    es-object-atoms: "npm:^1.0.0"
+  checksum: 10c0/59e1a70bf9414cb4c536a6e31bef5553c8ceb0cf44d8b4d0ed65c9653358d1c64dd0ec203b100df83d0413bbcde38b8c5d49e14bc4b86737d74adc593a0d35b6
+  languageName: node
+  linkType: hard
+
+"string.prototype.trimstart@npm:^1.0.8":
+  version: 1.0.8
+  resolution: "string.prototype.trimstart@npm:1.0.8"
+  dependencies:
+    call-bind: "npm:^1.0.7"
+    define-properties: "npm:^1.2.1"
+    es-object-atoms: "npm:^1.0.0"
+  checksum: 10c0/d53af1899959e53c83b64a5fd120be93e067da740e7e75acb433849aa640782fb6c7d4cd5b84c954c84413745a3764df135a8afeb22908b86a835290788d8366
+  languageName: node
+  linkType: hard
+
 "string_decoder@npm:^1.1.1":
   version: 1.3.0
   resolution: "string_decoder@npm:1.3.0"
@@ -5194,6 +7013,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"strip-bom@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "strip-bom@npm:3.0.0"
+  checksum: 10c0/51201f50e021ef16672593d7434ca239441b7b760e905d9f33df6e4f3954ff54ec0e0a06f100d028af0982d6f25c35cd5cda2ce34eaebccd0250b8befb90d8f1
+  languageName: node
+  linkType: hard
+
 "strip-bom@npm:^4.0.0":
   version: 4.0.0
   resolution: "strip-bom@npm:4.0.0"
@@ -5368,20 +7194,35 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "torch@workspace:."
   dependencies:
+    "@eslint/js": "npm:^9.37.0"
     "@types/jest": "npm:^30.0.0"
     "@types/node": "npm:^24.6.2"
     "@veehz/gpu.js": "npm:^2.16.0"
+    eslint: "npm:^9.37.0"
+    eslint-plugin-import: "npm:^2.32.0"
+    eslint-plugin-jest: "npm:^29.0.1"
     jest: "npm:^30.2.0"
     jest-util: "npm:^30.2.0"
+    prettier: "npm:^3.6.2"
     rimraf: "npm:^6.0.1"
     ts-jest: "npm:^29.4.4"
     ts-node: "npm:^10.9.2"
     typescript: "npm:^5.9.3"
+    typescript-eslint: "npm:^8.46.0"
     vite: "npm:^7.1.9"
     vite-plugin-dts: "npm:^4.5.4"
   languageName: unknown
   linkType: soft
 
+"ts-api-utils@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "ts-api-utils@npm:2.1.0"
+  peerDependencies:
+    typescript: ">=4.8.4"
+  checksum: 10c0/9806a38adea2db0f6aa217ccc6bc9c391ddba338a9fe3080676d0d50ed806d305bb90e8cef0276e793d28c8a929f400abb184ddd7ff83a416959c0f4d2ce754f
+  languageName: node
+  linkType: hard
+
 "ts-jest@npm:^29.4.4":
   version: 29.4.4
   resolution: "ts-jest@npm:29.4.4"
@@ -5460,6 +7301,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"tsconfig-paths@npm:^3.15.0":
+  version: 3.15.0
+  resolution: "tsconfig-paths@npm:3.15.0"
+  dependencies:
+    "@types/json5": "npm:^0.0.29"
+    json5: "npm:^1.0.2"
+    minimist: "npm:^1.2.6"
+    strip-bom: "npm:^3.0.0"
+  checksum: 10c0/5b4f301a2b7a3766a986baf8fc0e177eb80bdba6e396792ff92dc23b5bca8bb279fc96517dcaaef63a3b49bebc6c4c833653ec58155780bc906bdbcf7dda0ef5
+  languageName: node
+  linkType: hard
+
 "tslib@npm:^2.4.0":
   version: 2.8.1
   resolution: "tslib@npm:2.8.1"
@@ -5476,6 +7329,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
+  version: 0.4.0
+  resolution: "type-check@npm:0.4.0"
+  dependencies:
+    prelude-ls: "npm:^1.2.1"
+  checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58
+  languageName: node
+  linkType: hard
+
 "type-detect@npm:4.0.8":
   version: 4.0.8
   resolution: "type-detect@npm:4.0.8"
@@ -5497,6 +7359,74 @@ __metadata:
   languageName: node
   linkType: hard
 
+"typed-array-buffer@npm:^1.0.3":
+  version: 1.0.3
+  resolution: "typed-array-buffer@npm:1.0.3"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    es-errors: "npm:^1.3.0"
+    is-typed-array: "npm:^1.1.14"
+  checksum: 10c0/1105071756eb248774bc71646bfe45b682efcad93b55532c6ffa4518969fb6241354e4aa62af679ae83899ec296d69ef88f1f3763657cdb3a4d29321f7b83079
+  languageName: node
+  linkType: hard
+
+"typed-array-byte-length@npm:^1.0.3":
+  version: 1.0.3
+  resolution: "typed-array-byte-length@npm:1.0.3"
+  dependencies:
+    call-bind: "npm:^1.0.8"
+    for-each: "npm:^0.3.3"
+    gopd: "npm:^1.2.0"
+    has-proto: "npm:^1.2.0"
+    is-typed-array: "npm:^1.1.14"
+  checksum: 10c0/6ae083c6f0354f1fce18b90b243343b9982affd8d839c57bbd2c174a5d5dc71be9eb7019ffd12628a96a4815e7afa85d718d6f1e758615151d5f35df841ffb3e
+  languageName: node
+  linkType: hard
+
+"typed-array-byte-offset@npm:^1.0.4":
+  version: 1.0.4
+  resolution: "typed-array-byte-offset@npm:1.0.4"
+  dependencies:
+    available-typed-arrays: "npm:^1.0.7"
+    call-bind: "npm:^1.0.8"
+    for-each: "npm:^0.3.3"
+    gopd: "npm:^1.2.0"
+    has-proto: "npm:^1.2.0"
+    is-typed-array: "npm:^1.1.15"
+    reflect.getprototypeof: "npm:^1.0.9"
+  checksum: 10c0/3d805b050c0c33b51719ee52de17c1cd8e6a571abdf0fffb110e45e8dd87a657e8b56eee94b776b13006d3d347a0c18a730b903cf05293ab6d92e99ff8f77e53
+  languageName: node
+  linkType: hard
+
+"typed-array-length@npm:^1.0.7":
+  version: 1.0.7
+  resolution: "typed-array-length@npm:1.0.7"
+  dependencies:
+    call-bind: "npm:^1.0.7"
+    for-each: "npm:^0.3.3"
+    gopd: "npm:^1.0.1"
+    is-typed-array: "npm:^1.1.13"
+    possible-typed-array-names: "npm:^1.0.0"
+    reflect.getprototypeof: "npm:^1.0.6"
+  checksum: 10c0/e38f2ae3779584c138a2d8adfa8ecf749f494af3cd3cdafe4e688ce51418c7d2c5c88df1bd6be2bbea099c3f7cea58c02ca02ed438119e91f162a9de23f61295
+  languageName: node
+  linkType: hard
+
+"typescript-eslint@npm:^8.46.0":
+  version: 8.46.0
+  resolution: "typescript-eslint@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/eslint-plugin": "npm:8.46.0"
+    "@typescript-eslint/parser": "npm:8.46.0"
+    "@typescript-eslint/typescript-estree": "npm:8.46.0"
+    "@typescript-eslint/utils": "npm:8.46.0"
+  peerDependencies:
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/fcfd2bbf2932734fced5515b3697e0f8e69ba2aca40625d12f4e0225396407e816aa9085ff4886e8f79903110b02676deeaef2525d60700a4f5d47841a27282a
+  languageName: node
+  linkType: hard
+
 "typescript@npm:5.8.2":
   version: 5.8.2
   resolution: "typescript@npm:5.8.2"
@@ -5553,6 +7483,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"unbox-primitive@npm:^1.1.0":
+  version: 1.1.0
+  resolution: "unbox-primitive@npm:1.1.0"
+  dependencies:
+    call-bound: "npm:^1.0.3"
+    has-bigints: "npm:^1.0.2"
+    has-symbols: "npm:^1.1.0"
+    which-boxed-primitive: "npm:^1.1.1"
+  checksum: 10c0/7dbd35ab02b0e05fe07136c72cb9355091242455473ec15057c11430129bab38b7b3624019b8778d02a881c13de44d63cd02d122ee782fb519e1de7775b5b982
+  languageName: node
+  linkType: hard
+
 "undici-types@npm:~7.13.0":
   version: 7.13.0
   resolution: "undici-types@npm:7.13.0"
@@ -5821,6 +7763,67 @@ __metadata:
   languageName: node
   linkType: hard
 
+"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "which-boxed-primitive@npm:1.1.1"
+  dependencies:
+    is-bigint: "npm:^1.1.0"
+    is-boolean-object: "npm:^1.2.1"
+    is-number-object: "npm:^1.1.1"
+    is-string: "npm:^1.1.1"
+    is-symbol: "npm:^1.1.1"
+  checksum: 10c0/aceea8ede3b08dede7dce168f3883323f7c62272b49801716e8332ff750e7ae59a511ae088840bc6874f16c1b7fd296c05c949b0e5b357bfe3c431b98c417abe
+  languageName: node
+  linkType: hard
+
+"which-builtin-type@npm:^1.2.1":
+  version: 1.2.1
+  resolution: "which-builtin-type@npm:1.2.1"
+  dependencies:
+    call-bound: "npm:^1.0.2"
+    function.prototype.name: "npm:^1.1.6"
+    has-tostringtag: "npm:^1.0.2"
+    is-async-function: "npm:^2.0.0"
+    is-date-object: "npm:^1.1.0"
+    is-finalizationregistry: "npm:^1.1.0"
+    is-generator-function: "npm:^1.0.10"
+    is-regex: "npm:^1.2.1"
+    is-weakref: "npm:^1.0.2"
+    isarray: "npm:^2.0.5"
+    which-boxed-primitive: "npm:^1.1.0"
+    which-collection: "npm:^1.0.2"
+    which-typed-array: "npm:^1.1.16"
+  checksum: 10c0/8dcf323c45e5c27887800df42fbe0431d0b66b1163849bb7d46b5a730ad6a96ee8bfe827d078303f825537844ebf20c02459de41239a0a9805e2fcb3cae0d471
+  languageName: node
+  linkType: hard
+
+"which-collection@npm:^1.0.2":
+  version: 1.0.2
+  resolution: "which-collection@npm:1.0.2"
+  dependencies:
+    is-map: "npm:^2.0.3"
+    is-set: "npm:^2.0.3"
+    is-weakmap: "npm:^2.0.2"
+    is-weakset: "npm:^2.0.3"
+  checksum: 10c0/3345fde20964525a04cdf7c4a96821f85f0cc198f1b2ecb4576e08096746d129eb133571998fe121c77782ac8f21cbd67745a3d35ce100d26d4e684c142ea1f2
+  languageName: node
+  linkType: hard
+
+"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19":
+  version: 1.1.19
+  resolution: "which-typed-array@npm:1.1.19"
+  dependencies:
+    available-typed-arrays: "npm:^1.0.7"
+    call-bind: "npm:^1.0.8"
+    call-bound: "npm:^1.0.4"
+    for-each: "npm:^0.3.5"
+    get-proto: "npm:^1.0.1"
+    gopd: "npm:^1.2.0"
+    has-tostringtag: "npm:^1.0.2"
+  checksum: 10c0/702b5dc878addafe6c6300c3d0af5983b175c75fcb4f2a72dfc3dd38d93cf9e89581e4b29c854b16ea37e50a7d7fca5ae42ece5c273d8060dcd603b2404bbb3f
+  languageName: node
+  linkType: hard
+
 "which@npm:^2.0.1":
   version: 2.0.2
   resolution: "which@npm:2.0.2"
@@ -5854,6 +7857,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"word-wrap@npm:^1.2.5":
+  version: 1.2.5
+  resolution: "word-wrap@npm:1.2.5"
+  checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20
+  languageName: node
+  linkType: hard
+
 "wordwrap@npm:^1.0.0":
   version: 1.0.0
   resolution: "wordwrap@npm:1.0.0"

From 4ab6401be1c17c61c84f6432ffd7f61ef96741ef Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 17:02:50 +0800
Subject: [PATCH 009/128] feat: creation functions

---
 src/creation/index.ts | 55 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 src/creation/index.ts

diff --git a/src/creation/index.ts b/src/creation/index.ts
new file mode 100644
index 00000000..9edf9fef
--- /dev/null
+++ b/src/creation/index.ts
@@ -0,0 +1,55 @@
+import { Tensor } from '../tensor';
+
+export function linspace(start: number, end: number, steps: number) {
+  const data = [];
+  const step = (end - start) / (steps - 1);
+  for (let i = 0; i < steps - 1; i++) {
+    data.push(start + i * step);
+  }
+  data.push(end);
+  return new Tensor(data);
+}
+
+function get_shape_from_args(args: number[] | number[][]): number[] {
+  if (Array.isArray(args[0])) {
+    return args[0];
+  }
+
+  return args as number[];
+}
+
+export function ones(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(1));
+  tensor.shape = shape;
+  return tensor;
+}
+
+export function zeros(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(0));
+  tensor.shape = shape;
+  return tensor;
+}
+
+/* TODO: use the correct distributions */
+
+export function randn(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.random()));
+  tensor.shape = shape;
+  return tensor;
+}
+
+export function rand(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.random()));
+  tensor.shape = shape;
+  return tensor;
+}
+
+export function randint(low: number, high: number, shape: number[]): Tensor {
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.floor(Math.random() * (high - low) + low)));
+  tensor.shape = shape;
+  return tensor;
+}
\ No newline at end of file

From c871a3edc89a4c4dc2fbebafd84093838ea31d64 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 20:33:32 +0800
Subject: [PATCH 010/128] feat: macros with jinja2, matmul, transpose

---
 README.md                    |   8 +-
 package.json                 |   1 +
 scripts/.gitignore           |   1 +
 scripts/generate.py          |  72 ++++++
 scripts/macros.ts.j2         |  84 +++++++
 src/broadcasting.ts          |  48 ++++
 src/gpu.ts                   |  12 +-
 src/index.ts                 |  13 +-
 src/operations/base.ts       |   2 +-
 src/operations/classes.ts    | 351 ----------------------------
 src/operations/functional.ts |  55 ++---
 src/operations/ops.gen.ts    | 441 +++++++++++++++++++++++++++++++++++
 src/operations/ops.ts.j2     | 183 +++++++++++++++
 src/tensor.ts                |  30 ++-
 test/functional.test.ts      |  67 ++++++
 test/tensor.test.ts          |  36 +++
 16 files changed, 1005 insertions(+), 399 deletions(-)
 create mode 100644 scripts/.gitignore
 create mode 100644 scripts/generate.py
 create mode 100644 scripts/macros.ts.j2
 delete mode 100644 src/operations/classes.ts
 create mode 100644 src/operations/ops.gen.ts
 create mode 100644 src/operations/ops.ts.j2

diff --git a/README.md b/README.md
index 3e83fe2c..56b82b80 100644
--- a/README.md
+++ b/README.md
@@ -41,4 +41,10 @@ You can run `http-server` and load `examples/browser/index.html` to see how it w
 npx http-server --cors=* -c-1 .
 # and navigate to http://localhost:8080/examples/browser/index.html to run torch in js
 # or http://localhost:8080/examples/pyodide/index.html to run in python
-```
\ No newline at end of file
+```
+
+## Development Notes
+
+Files ending with `.ts.j2` are generated by jinja to `.gen.ts`, using `scripts/generate.py`.
+
+Do not edit `.gen.ts` directly, instead edit the `.ts.j2` files.
\ No newline at end of file
diff --git a/package.json b/package.json
index db5ab478..638afa8d 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
     "build:browser": "vite build --config vite.config.browser.ts",
     "build:node": "vite build --config vite.config.node.ts",
     "build": "npm run clean && npm run build:node && npm run build:browser",
+    "generate": "node scripts/generate-m4.js",
     "test": "jest",
     "test:watch": "jest --watch"
   },
diff --git a/scripts/.gitignore b/scripts/.gitignore
new file mode 100644
index 00000000..a395bf38
--- /dev/null
+++ b/scripts/.gitignore
@@ -0,0 +1 @@
+macros.gen.ts
\ No newline at end of file
diff --git a/scripts/generate.py b/scripts/generate.py
new file mode 100644
index 00000000..2f5607b7
--- /dev/null
+++ b/scripts/generate.py
@@ -0,0 +1,72 @@
+import os
+import jinja2
+from pathlib import Path
+
+def find_template_files(root_dir):
+    """Find all .ts.j2 files in the project"""
+    template_files = []
+    for root, dirs, files in os.walk(root_dir):
+        for file in files:
+            if file.endswith('.ts.j2'):
+                template_files.append(os.path.join(root, file))
+    return template_files
+
+def compile_template(template_path, output_path, env):
+    """Compile a single template file to .gen.ts"""
+    try:
+        # Get relative path for template loading
+        project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+        rel_path = os.path.relpath(template_path, project_root)
+        
+        # Use the FileSystemLoader to load the template
+        template = env.get_template(rel_path)
+        
+        # Render the template
+        output = template.render({})
+
+        output = f"// This file is generated by scripts/generate_script.py from {rel_path}\n" + output
+        
+        # Write to .gen.ts file
+        with open(output_path, 'w') as f:
+            f.write(output)
+        
+        print(f"Generated: {output_path}")
+        return True
+    except Exception as e:
+        print(f"Error compiling {template_path}: {e}")
+        return False
+
+def main():
+    # Setup Jinja2 environment - point to project root so it can find both src and scripts
+    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+    env = jinja2.Environment(
+        loader=jinja2.FileSystemLoader(project_root),
+        trim_blocks=True,
+        lstrip_blocks=True
+    )
+    
+    # Find all template files
+    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+    template_files = find_template_files(project_root)
+    
+    if not template_files:
+        print("No .ts.j2 files found")
+        return
+    
+    print(f"Found {len(template_files)} template files:")
+    for template_file in template_files:
+        print(f"  - {template_file}")
+    
+    # Compile each template
+    success_count = 0
+    for template_file in template_files:
+        # Generate output filename
+        output_file = template_file.replace('.ts.j2', '.gen.ts')
+        
+        if compile_template(template_file, output_file, env):
+            success_count += 1
+    
+    print(f"\nCompilation complete: {success_count}/{len(template_files)} files generated successfully")
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2
new file mode 100644
index 00000000..0891e2aa
--- /dev/null
+++ b/scripts/macros.ts.j2
@@ -0,0 +1,84 @@
+{% macro binary_op_base(name, operation) -%}
+// function generated from binary_op_base("{{ name }}", "{{ operation }}")
+function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return {{ operation }};
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+{%- endmacro %}
+
+{% macro unary_op_base(name, operation) -%}
+// function generated from unary_op_base("{{ name }}", "{{ operation }}")
+function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return {{ operation }};
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+{%- endmacro %}
+
+{% macro binary_op_class(classname, opname, backward_operations) -%}
+// class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations)
+export class {{ classname }} extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _{{ opname }}_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    {{ backward_operations | join("\n    ") }}
+  }
+}
+registerOperation('{{ opname }}', {{ classname }});
+{%- endmacro %}
+
+{% macro unary_op_class(classname, opname, backward_operations) -%}
+// class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations)
+export class {{ classname }} extends UnaryOperation {
+  cache: [Tensor];
+  forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _{{ opname }}_tensor(a, this);
+  }
+  backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    {{ backward_operations | join("\n    ") }}
+  }
+}
+registerOperation('{{ opname }}', {{ classname }});
+{%- endmacro %}
\ No newline at end of file
diff --git a/src/broadcasting.ts b/src/broadcasting.ts
index f031ae1e..0b57aed6 100644
--- a/src/broadcasting.ts
+++ b/src/broadcasting.ts
@@ -22,6 +22,10 @@ export function _broadcast_shape(a_shape: number[], b_shape: number[]): number[]
 }
 
 export function _pad_shape(shape: number[], broadcast_shape: number[]): number[] {
+  if(shape.length >= broadcast_shape.length) {
+    return shape;
+  }
+
   return [...Array(broadcast_shape.length - shape.length).fill(1), ...shape];
 }
 
@@ -64,3 +68,47 @@ export function _get_original_index_kernel(
   }
   return original_index;
 }
+
+export function _get_original_index_from_transposed_index(
+  original_shape: number[],
+  dim0: number,
+  dim1: number,
+  transposed_index: number
+): number {
+  let original_index = 0;
+  let cur_stride = 1;
+  let temp_index = transposed_index;
+
+  let dim0_index = 0;
+  let dim1_index = 0;
+
+  for (let i = this.constants.shape_length - 1; i >= 0; i--) {
+    const dim_index = temp_index % original_shape[i];
+    if(i == dim0) {
+      dim0_index = dim_index;
+    }
+    if(i == dim1) {
+      dim1_index = dim_index;
+    }
+    temp_index = Math.floor(temp_index / original_shape[i]);
+  }
+
+  temp_index = transposed_index;
+
+  for (let j = this.constants.shape_length - 1; j >= 0; j--) {
+    const dim_index = temp_index % original_shape[j];
+    if(j == dim0) {
+      original_index = original_index + dim1_index * cur_stride;
+    } else if(j == dim1) {
+      original_index = original_index + dim0_index * cur_stride;
+    } else {
+      original_index = original_index + dim_index * cur_stride;
+    }
+    cur_stride = cur_stride * original_shape[j];
+    temp_index = Math.floor(temp_index / original_shape[j]);
+  }
+
+  return original_index;
+
+  // return transposed_index;
+}
\ No newline at end of file
diff --git a/src/gpu.ts b/src/gpu.ts
index fee81495..e72362e9 100644
--- a/src/gpu.ts
+++ b/src/gpu.ts
@@ -4,7 +4,7 @@
  */
 
 import { GPU } from '@veehz/gpu.js';
-import { _get_original_index_kernel } from './broadcasting';
+import { _get_original_index_from_transposed_index, _get_original_index_kernel } from './broadcasting';
 
 const gpu = new GPU();
 
@@ -17,4 +17,14 @@ gpu.addFunction(_get_original_index_kernel, {
   }
 });
 
+gpu.addFunction(_get_original_index_from_transposed_index, {
+  returnType: 'Integer',
+  argumentTypes: {
+    original_shape: 'Array',
+    dim0: 'Integer',
+    dim1: 'Integer',
+    transposed_index: 'Integer'
+  }
+});
+
 export default gpu;
diff --git a/src/index.ts b/src/index.ts
index 1f7b2bf1..44ea8e5f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,15 +1,6 @@
-import { registerOperation } from './operations/registry';
 import { Tensor } from './tensor';
 
-import { Add, Div, Log, Mul, Pow, Sub, Sum } from './operations/classes';
-
+export * from './operations/ops.gen';
 export * from './operations/functional';
+export * from './creation/index';
 export { Tensor };
-
-registerOperation('add', Add);
-registerOperation('sub', Sub);
-registerOperation('mul', Mul);
-registerOperation('div', Div);
-registerOperation('sum', Sum);
-registerOperation('pow', Pow);
-registerOperation('log', Log);
diff --git a/src/operations/base.ts b/src/operations/base.ts
index c77dd3cf..c75d40ce 100644
--- a/src/operations/base.ts
+++ b/src/operations/base.ts
@@ -1,7 +1,7 @@
 import { Tensor } from '../tensor';
 
 abstract class Operation {
-  abstract forward(...args: Tensor[]): Tensor;
+  abstract forward(...args: (Tensor | number)[]): Tensor;
   abstract backward(dz: Tensor): void;
 }
 
diff --git a/src/operations/classes.ts b/src/operations/classes.ts
deleted file mode 100644
index 7d9a4e75..00000000
--- a/src/operations/classes.ts
+++ /dev/null
@@ -1,351 +0,0 @@
-import gpu from '../gpu';
-import { _broadcast_shape, _get_original_index_kernel, _pad_shape } from '../broadcasting';
-import { Tensor } from '../tensor';
-// import * as utils from "../utils";
-import { Operation, BinaryOperation, UnaryOperation } from './base';
-
-/* This did not work as it doesn't support dynamic function registration */
-// export function _broadcast_operation(
-//   f: (a: number, b: number) => number
-// ): (a: Tensor, b: Tensor) => Tensor {
-//   return (a: Tensor, b: Tensor) => {
-//     const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-
-//     gpu.addFunction(f, {
-//       returnType: 'Number',
-//       argumentTypes: {
-//         a: 'Number',
-//         b: 'Number'
-//       }
-//     });
-
-//     const kernel = gpu
-//       .createKernel(function (
-//         a: number[],
-//         as: number[],
-//         b: number[],
-//         bs: number[],
-//         bcs: number[]
-//       ) {
-//         const a_index = _get_original_index_gpu(as, bcs, this.thread.x);
-//         const b_index = _get_original_index_gpu(bs, bcs, this.thread.x);
-
-//         return f(a[a_index], b[b_index]);
-//       })
-//       .setConstants({ shape_length: broadcast_shape.length })
-//       .setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)])
-//       .setFunctions([f]);
-
-//     return new Tensor(
-//       kernel(a.data, a.shape, b.data, b.shape, broadcast_shape) as number[]
-//     );
-//   };
-// }
-
-export function _add(a: number[], b: number[]): number[] {
-  const kernel = gpu
-    .createKernel(function (a: number[], b: number[]) {
-      return a[this.thread.x] + b[this.thread.x];
-    })
-    .setOutput([a.length]);
-
-  return kernel(a, b) as number[];
-}
-
-export function _add_broadcast(
-  a: number[],
-  a_shape: number[],
-  b: number[],
-  b_shape: number[]
-): number[] {
-  const broadcast_shape = _broadcast_shape(a_shape, b_shape);
-
-  const kernel = gpu.createKernel(
-    function (
-      a: number[],
-      a_shape: number[],
-      b: number[],
-      b_shape: number[],
-      broadcast_shape: number[]
-    ) {
-      const a_index = _get_original_index_kernel(a_shape, broadcast_shape, this.thread.x);
-      const b_index = _get_original_index_kernel(b_shape, broadcast_shape, this.thread.x);
-
-      return a[a_index] + b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return kernel(a, a_shape, b, b_shape, broadcast_shape) as number[];
-}
-
-// export function _add_tensor(
-//   a: Tensor,
-//   b: Tensor,
-//   operation: Operation | null = null
-// ): Tensor {
-//   const a_shape = a.shape;
-//   const b_shape = b.shape;
-
-//   const result = _add_broadcast(a.data, a_shape, b.data, b_shape);
-
-//   return new Tensor(
-//     result,
-//     { requires_grad: a.requires_grad || b.requires_grad },
-//     { operation: operation }
-//   );
-// }
-
-// export function _add_tensor(a: Tensor, b: Tensor): Tensor {
-//     function _add_(a: number, b: number): number { return a + b }
-//     return _broadcast_operation(_add_)(a, b);
-// }
-
-export function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] + b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
-  );
-}
-
-export class Add extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _add_tensor(a, b, this);
-  }
-  backward(dz: Tensor): void {
-    const [a, b] = this.cache;
-    a.backward(dz);
-    b.backward(dz);
-  }
-}
-
-export function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] - b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape?.length || 0
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
-  );
-}
-
-export class Sub extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _sub_tensor(a, b, this);
-  }
-  backward(dz: Tensor): void {
-    const [a, b] = this.cache;
-    a.backward(dz);
-    b.backward(dz.mul(new Tensor(-1)));
-  }
-}
-
-export function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] * b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
-  );
-}
-
-export class Mul extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _mul_tensor(a, b, this);
-  }
-  backward(dz: Tensor): void {
-    const [a, b] = this.cache;
-    a.backward(dz.mul(b));
-    b.backward(dz.mul(a));
-  }
-}
-
-export function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] / b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
-  );
-}
-
-export class Div extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _div_tensor(a, b, this);
-  }
-  backward(dz: Tensor): void {
-    const [a, b] = this.cache;
-    a.backward(dz.div(b));
-    b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));
-  }
-}
-
-export class Sum extends UnaryOperation {
-  cache: [Tensor];
-  forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return new Tensor(
-      a.data.reduce((acc, val) => acc + val, 0),
-      { requires_grad: a.requires_grad },
-      { operation: this }
-    );
-  }
-
-  backward(dz: Tensor): void {
-    const [a] = this.cache;
-    const result = new Tensor(Array(a.data.length).fill(dz.data[0]));
-    a.backward(result);
-  }
-}
-
-export function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return Math.pow(a[a_index], b[b_index]);
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
-  );
-}
-
-export class Pow extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _pow_tensor(a, b, this);
-  }
-  backward(dz: Tensor): void {
-    const [a, b] = this.cache;
-    a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));
-    b.backward(dz.mul(a.pow(b)).mul(a.log()));
-  }
-}
-
-export function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.log(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: a.shape }
-  );
-}
-
-export class Log extends UnaryOperation {
-  cache: [Tensor];
-  forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _log_tensor(a, this);
-  }
-  backward(dz: Tensor): void {
-    const [a] = this.cache;
-    a.backward(new Tensor(1).div(a));
-  }
-}
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 5b7b2c73..ee00853d 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -1,37 +1,38 @@
 import { Tensor } from '../tensor';
 import { getOperation } from './registry';
 
-export function add(a: Tensor, b: Tensor): Tensor {
-  const operation = new (getOperation('add'))();
-  return operation.forward(a, b);
-}
-
-export function sub(a: Tensor, b: Tensor): Tensor {
-  const operation = new (getOperation('sub'))();
-  return operation.forward(a, b);
-}
+function generate_unary_function(opname: string) {
+  return (a: Tensor | number) => {
+    if (typeof a == 'number') {
+      a = new Tensor(a);
+    }
 
-export function mul(a: Tensor, b: Tensor): Tensor {
-  const operation = new (getOperation('mul'))();
-  return operation.forward(a, b);
+    const operation = new (getOperation(opname))();
+    return operation.forward(a);
+  };
 }
 
-export function div(a: Tensor, b: Tensor): Tensor {
-  const operation = new (getOperation('div'))();
-  return operation.forward(a, b);
-}
+function generate_binary_function(opname: string) {
+  return (a: Tensor | number, b: Tensor | number) => {
+    if (typeof a == 'number') {
+      a = new Tensor(a);
+    }
 
-export function sum(a: Tensor): Tensor {
-  const operation = new (getOperation('sum'))();
-  return operation.forward(a);
-}
+    if (typeof b == 'number') {
+      b = new Tensor(b);
+    }
 
-export function pow(a: Tensor, b: Tensor): Tensor {
-  const operation = new (getOperation('pow'))();
-  return operation.forward(a, b);
+    const operation = new (getOperation(opname))();
+    return operation.forward(a, b);
+  };
 }
 
-export function log(a: Tensor): Tensor {
-  const operation = new (getOperation('log'))();
-  return operation.forward(a);
-}
+export const add = generate_binary_function('add');
+export const sub = generate_binary_function('sub');
+export const mul = generate_binary_function('mul');
+export const div = generate_binary_function('div');
+export const sum = generate_unary_function('sum');
+export const mean = generate_unary_function('mean');
+export const pow = generate_unary_function('pow');
+export const log = generate_unary_function('log');
+export const matmul = generate_binary_function('matmul');
\ No newline at end of file
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
new file mode 100644
index 00000000..2a7a408a
--- /dev/null
+++ b/src/operations/ops.gen.ts
@@ -0,0 +1,441 @@
+// This file is generated by scripts/generate_script.py from src/operations/ops.ts.j2
+import { Tensor } from "../tensor";
+import { _broadcast_shape, _get_original_index_from_transposed_index, _get_original_index_kernel, _pad_shape } from "../broadcasting";
+import gpu from "../gpu";
+import { Operation, BinaryOperation, UnaryOperation } from './base';
+import { registerOperation } from "./registry";
+
+export function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  return new Tensor(
+    a.data.reduce((acc, val) => acc + val, 0),
+    { requires_grad: a.requires_grad },
+    { operation: operation }
+  );
+}
+
+// class generated from unary_op_class("Sum", "sum", backward_operations)
+export class Sum extends UnaryOperation {
+  cache: [Tensor];
+  forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sum_tensor(a, this);
+  }
+  backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    const result = new Tensor(Array(a.data.length).fill(dz.data[0]));
+    a.backward(result);
+  }
+}
+registerOperation('sum', Sum);
+
+export function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  return new Tensor(
+    a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
+    { requires_grad: a.requires_grad },
+    { operation: operation }
+  );
+}
+
+// class generated from unary_op_class("Mean", "mean", backward_operations)
+export class Mean extends UnaryOperation {
+  cache: [Tensor];
+  forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _mean_tensor(a, this);
+  }
+  backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));
+    a.backward(result);
+  }
+}
+registerOperation('mean', Mean);
+
+// function generated from binary_op_base("add", "a[a_index] + b[b_index]")
+function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] + b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Add", "add", backward_operations)
+export class Add extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _add_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz);
+    b.backward(dz);
+  }
+}
+registerOperation('add', Add);
+
+// function generated from binary_op_base("sub", "a[a_index] - b[b_index]")
+function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] - b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Sub", "sub", backward_operations)
+export class Sub extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _sub_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz);
+    b.backward(dz.mul(new Tensor(-1)));
+  }
+}
+registerOperation('sub', Sub);
+
+// function generated from binary_op_base("mul", "a[a_index] * b[b_index]")
+function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] * b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Mul", "mul", backward_operations)
+export class Mul extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _mul_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(b));
+    b.backward(dz.mul(a));
+  }
+}
+registerOperation('mul', Mul);
+
+// function generated from binary_op_base("div", "a[a_index] / b[b_index]")
+function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] / b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Div", "div", backward_operations)
+export class Div extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _div_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.div(b));
+    b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));
+  }
+}
+registerOperation('div', Div);
+
+// function generated from binary_op_base("pow", "a[a_index] ** b[b_index]")
+function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] ** b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Pow", "pow", backward_operations)
+export class Pow extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _pow_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));
+    b.backward(dz.mul(a.pow(b)).mul(a.log()));
+  }
+}
+registerOperation('pow', Pow);
+
+function _transpose_tensor(a: Tensor, dim0: number, dim1: number, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], dim0: number, dim1: number) {
+      const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
+      return a[a_index];
+    },
+    {
+      constants: {
+        shape_length: a.shape.length
+      },
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  const swapped_shape = a.shape;
+  [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
+
+  return new Tensor(
+    kernel(a.data, a.shape, dim0, dim1) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: swapped_shape }
+  );
+}
+
+export class Transpose extends Operation {
+  cache: [Tensor, number, number];
+  forward(a: Tensor, dim0: number, dim1: number): Tensor {
+    this.cache = [a, dim0, dim1];
+    return _transpose_tensor(a, dim0, dim1, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, dim0, dim1] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.transpose(dim0, dim1));
+  }
+}
+registerOperation('transpose', Transpose);
+
+function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  if (a.shape.length == 1 && b.shape.length == 1) {
+    return a.mul(b).sum();
+  }
+
+  const a_1d = a.shape.length == 1;
+  const b_1d = b.shape.length == 1;
+
+  const a_shape = a_1d ? [1, a.shape[0]] : a.shape;
+  const b_shape = b_1d ? [b.shape[0], 1] : b.shape;
+
+  if(a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
+    // TODO: check what error pytorch throws
+    throw new Error("Shape mismatch: " + a.shape + " and " + b.shape);
+  }
+
+  const loop_iterations = a_shape[a_shape.length - 1];
+
+  if(loop_iterations > 1000) {
+    // TODO: can try fixing with maxLoopIterations by gpu.js
+    throw new Error("Loop iterations too large: " + loop_iterations);
+  }
+
+  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2))
+                            .concat([a_shape[a_shape.length - 2], b_shape[b_shape.length - 1]]);
+
+  const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
+
+  function _matmul_kernel(a: number[], as: number[], b: number[], bs: number[], bcs: number[], lp: number) {
+    let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    const l = this.constants.shape_length;
+
+    const position = this.thread.x % (bcs[l] * bcs[l + 1]);
+    a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
+    b_index = b_index * bs[l] * bs[l + 1] + position % bcs[l + 1];
+
+    const b_stride = bs[l+1];
+
+    let sum = 0;
+    for(let i = 0; i < lp; i++) {
+      sum = sum + a[a_index] * b[b_index];
+      a_index = a_index + 1;
+      b_index = b_index + b_stride;
+    }
+
+    return sum;
+  }
+
+  const kernel = gpu.createKernel(
+    _matmul_kernel,
+    {
+      constants: {
+        // assumes that _get_original_index_kernel reads from the front
+        shape_length: broadcast_shape.length - 2
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  let shape_after_removing_extra_dims = broadcast_shape;
+
+  if(a_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -2).concat([a.shape[0]]);
+  }
+
+  if(b_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
+  }
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, loop_iterations) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: shape_after_removing_extra_dims }
+  );
+}
+
+// class generated from binary_op_class("Matmul", "matmul", backward_operations)
+export class Matmul extends BinaryOperation {
+  cache: [Tensor, Tensor];
+  forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _matmul_tensor(a, b, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('matmul', Matmul);
+
+
+
+// function generated from unary_op_base("log", "Math.log(a[this.thread.x])")
+function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.log(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Log", "log", backward_operations)
+export class Log extends UnaryOperation {
+  cache: [Tensor];
+  forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _log_tensor(a, this);
+  }
+  backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(new Tensor(1).div(a));
+  }
+}
+registerOperation('log', Log);
+
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
new file mode 100644
index 00000000..f5d3c557
--- /dev/null
+++ b/src/operations/ops.ts.j2
@@ -0,0 +1,183 @@
+{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class %}
+import { Tensor } from "../tensor";
+import { _broadcast_shape, _get_original_index_from_transposed_index, _get_original_index_kernel, _pad_shape } from "../broadcasting";
+import gpu from "../gpu";
+import { Operation, BinaryOperation, UnaryOperation } from './base';
+import { registerOperation } from "./registry";
+
+export function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  return new Tensor(
+    a.data.reduce((acc, val) => acc + val, 0),
+    { requires_grad: a.requires_grad },
+    { operation: operation }
+  );
+}
+
+{{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.data.length).fill(dz.data[0]));", "a.backward(result);"]) }}
+
+export function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  return new Tensor(
+    a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
+    { requires_grad: a.requires_grad },
+    { operation: operation }
+  );
+}
+
+{{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));", "a.backward(result);"]) }}
+
+{{ binary_op_base("add", "a[a_index] + b[b_index]") }}
+{{ binary_op_class("Add", "add", ["a.backward(dz);", "b.backward(dz);"]) }}
+
+{{ binary_op_base("sub", "a[a_index] - b[b_index]") }}
+{{ binary_op_class("Sub", "sub", ["a.backward(dz);", "b.backward(dz.mul(new Tensor(-1)));"]) }}
+
+{{ binary_op_base("mul", "a[a_index] * b[b_index]") }}
+{{ binary_op_class("Mul", "mul", ["a.backward(dz.mul(b));", "b.backward(dz.mul(a));"]) }}
+
+{{ binary_op_base("div", "a[a_index] / b[b_index]") }}
+{{ binary_op_class("Div", "div", ["a.backward(dz.div(b));", "b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));"]) }}
+
+{{ binary_op_base("pow", "a[a_index] ** b[b_index]") }}
+{{ binary_op_class("Pow", "pow", [
+  "a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));",
+  "b.backward(dz.mul(a.pow(b)).mul(a.log()));"
+])}}
+
+function _transpose_tensor(a: Tensor, dim0: number, dim1: number, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], dim0: number, dim1: number) {
+      const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
+      return a[a_index];
+    },
+    {
+      constants: {
+        shape_length: a.shape.length
+      },
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  const swapped_shape = a.shape;
+  [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
+
+  return new Tensor(
+    kernel(a.data, a.shape, dim0, dim1) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: swapped_shape }
+  );
+}
+
+export class Transpose extends Operation {
+  cache: [Tensor, number, number];
+  forward(a: Tensor, dim0: number, dim1: number): Tensor {
+    this.cache = [a, dim0, dim1];
+    return _transpose_tensor(a, dim0, dim1, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, dim0, dim1] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.transpose(dim0, dim1));
+  }
+}
+registerOperation('transpose', Transpose);
+
+function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  if (a.shape.length == 1 && b.shape.length == 1) {
+    return a.mul(b).sum();
+  }
+
+  const a_1d = a.shape.length == 1;
+  const b_1d = b.shape.length == 1;
+
+  const a_shape = a_1d ? [1, a.shape[0]] : a.shape;
+  const b_shape = b_1d ? [b.shape[0], 1] : b.shape;
+
+  if(a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
+    // TODO: check what error pytorch throws
+    throw new Error("Shape mismatch: " + a.shape + " and " + b.shape);
+  }
+
+  const loop_iterations = a_shape[a_shape.length - 1];
+
+  if(loop_iterations > 1000) {
+    // TODO: can try fixing with maxLoopIterations by gpu.js
+    throw new Error("Loop iterations too large: " + loop_iterations);
+  }
+
+  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2))
+                            .concat([a_shape[a_shape.length - 2], b_shape[b_shape.length - 1]]);
+
+  const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
+
+  function _matmul_kernel(a: number[], as: number[], b: number[], bs: number[], bcs: number[], lp: number) {
+    let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    const l = this.constants.shape_length;
+
+    const position = this.thread.x % (bcs[l] * bcs[l + 1]);
+    a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
+    b_index = b_index * bs[l] * bs[l + 1] + position % bcs[l + 1];
+
+    const b_stride = bs[l+1];
+
+    let sum = 0;
+    for(let i = 0; i < lp; i++) {
+      sum = sum + a[a_index] * b[b_index];
+      a_index = a_index + 1;
+      b_index = b_index + b_stride;
+    }
+
+    return sum;
+  }
+
+  const kernel = gpu.createKernel(
+    _matmul_kernel,
+    {
+      constants: {
+        // assumes that _get_original_index_kernel reads from the front
+        shape_length: broadcast_shape.length - 2
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
+    }
+  );
+
+  let shape_after_removing_extra_dims = broadcast_shape;
+
+  if(a_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -2).concat([a.shape[0]]);
+  }
+
+  if(b_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
+  }
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, loop_iterations) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: shape_after_removing_extra_dims }
+  );
+}
+
+{{ binary_op_class("Matmul", "matmul", []) }}
+
+{# {{ binary_op_base("mod", "a[a_index] % b[b_index]") }}
+{{ binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0") }}
+{{ binary_op_base("gt", "(a[a_index] > b[b_index]) ? 1 : 0") }}
+{{ binary_op_base("le", "(a[a_index] <= b[b_index]) ? 1 : 0") }}
+{{ binary_op_base("ge", "(a[a_index] >= b[b_index]) ? 1 : 0") }}
+{{ binary_op_base("eq", "(a[a_index] == b[b_index]) ? 1 : 0") }}
+{{ binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0") }} #}
+
+{# {{ unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])") }}
+{{ unary_op_base("abs", "Math.abs(a[this.thread.x])") }}
+{{ unary_op_base("sin", "Math.sin(a[this.thread.x])") }}
+{{ unary_op_base("cos", "Math.cos(a[this.thread.x])") }}
+{{ unary_op_base("exp", "Math.exp(a[this.thread.x])") }} #}
+
+{{ unary_op_base("log", "Math.log(a[this.thread.x])") }}
+{{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }}
+
+{# {{ unary_op_base("neg", "-a[this.thread.x]") }} #}
diff --git a/src/tensor.ts b/src/tensor.ts
index 04b448f5..eea6a26d 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -18,7 +18,7 @@ type TypedArray =
   | Float32Array
   | Float64Array;
 
-type NestedNumberArray = number | TypedArray | NestedNumberArray[];
+export type NestedNumberArray = number | TypedArray | NestedNumberArray[];
 
 function _get_shape(data: NestedNumberArray): number[] {
   if (ArrayBuffer.isView(data)) {
@@ -81,24 +81,32 @@ export class Tensor {
     return operation.forward(this);
   }
 
-  private _executeBinaryOp(opName: string, other: Tensor): Tensor {
+  private _executeBinaryOp(opName: string, other: Tensor | number): Tensor {
+    if (typeof other == 'number') {
+      other = new Tensor(other);
+    }
     const operation = new (getOperation(opName))();
     return operation.forward(this, other);
   }
 
-  add(other: Tensor): Tensor {
+  private _executeOpRaw(opName: string, ...args: any[]): Tensor {
+    const operation = new (getOperation(opName))();
+    return operation.forward(this, ...args);
+  }
+
+  add(other: Tensor | number): Tensor {
     return this._executeBinaryOp('add', other);
   }
 
-  sub(other: Tensor): Tensor {
+  sub(other: Tensor | number): Tensor {
     return this._executeBinaryOp('sub', other);
   }
 
-  mul(other: Tensor): Tensor {
+  mul(other: Tensor | number): Tensor {
     return this._executeBinaryOp('mul', other);
   }
 
-  div(other: Tensor): Tensor {
+  div(other: Tensor | number): Tensor {
     return this._executeBinaryOp('div', other);
   }
 
@@ -106,7 +114,7 @@ export class Tensor {
     return this._executeUnaryOp('sum');
   }
 
-  pow(other: Tensor): Tensor {
+  pow(other: Tensor | number): Tensor {
     return this._executeBinaryOp('pow', other);
   }
 
@@ -114,6 +122,14 @@ export class Tensor {
     return this._executeUnaryOp('log');
   }
 
+  transpose(dim0: number, dim1: number): Tensor {
+    return this._executeOpRaw('transpose', dim0, dim1);
+  }
+
+  matmul(other: Tensor): Tensor {
+    return this._executeBinaryOp('matmul', other);
+  }
+
   item(): number {
     if (this.data.length !== 1) {
       throw new Error('Tensor.item() is only valid for scalars');
diff --git a/test/functional.test.ts b/test/functional.test.ts
index 26281091..5fadfd10 100644
--- a/test/functional.test.ts
+++ b/test/functional.test.ts
@@ -52,4 +52,71 @@ describe("Functional", () => {
       expect(result.shape).toEqual([3]);
     });
   });
+
+  describe("Matrix Multiplication", () => {
+    test("should multiply two tensors with shape (1)", () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = torch.matmul(t1, t2);
+
+      expect(Array.from(result.data)).toEqual([200]);
+      expect(result.shape).toEqual([1]);
+    });
+
+    test("should multiply two tensors with 1 dim", () => {
+      const t1 = new Tensor([1, 2, 3, 4]);
+      const t2 = new Tensor([5, 6, 7, 8]);
+      const result = torch.matmul(t1, t2);
+
+      expect(Array.from(result.data)).toEqual([70]);
+      expect(result.shape).toEqual([1]);
+    });
+
+    test("should multiply two tensors with shape (2, 3) and (3, 3) with the correct values", () => {
+      const t1 = new Tensor([
+        [1, 2, 3],
+        [4, 5, 6]
+      ]);
+
+      const t2 = new Tensor([
+        [9, 9, 1],
+        [6, 4, 3],
+        [5, 5, 6]
+      ])
+
+      const result = torch.matmul(t1, t2);
+
+      const expected = [
+        36, 32, 25,
+        96, 86, 55
+      ];
+
+      expect(Array.from(result.data)).toEqual(expected);
+      expect(result.shape).toEqual([2, 3]);
+    });
+
+    test("should output correct shape", () => {
+      function shape_of(shape1: number[], shape2: number[]): number[] {
+        const tensor1 = torch.randn(shape1);
+        const tensor2 = torch.randn(shape2);
+        const result = torch.matmul(tensor1, tensor2);
+        return result.shape;
+      }
+
+      expect(shape_of([3, 4], [4, 5])).toEqual([3, 5]);
+      expect(shape_of([3, 4], [4])).toEqual([3]);
+      expect(shape_of([10, 3, 4], [4])).toEqual([10, 3]);
+      expect(shape_of([10, 3, 4], [10, 4, 5])).toEqual([10, 3, 5]);
+      expect(shape_of([10, 3, 4], [4, 5])).toEqual([10, 3, 5]);
+    });
+  });
+
+  describe("Transpose", () => {
+    test("should transpose a tensor", () => {
+      const t = new Tensor([[1, 2], [3, 4]]);
+      const result = t.transpose(0, 1);
+      expect(Array.from(result.data)).toEqual([1, 3, 2, 4]);
+      expect(result.shape).toEqual([2, 2]);
+    });
+  });
 });
diff --git a/test/tensor.test.ts b/test/tensor.test.ts
index 2fbb610b..64181a0f 100644
--- a/test/tensor.test.ts
+++ b/test/tensor.test.ts
@@ -65,4 +65,40 @@ describe('Tensor', () => {
       expect(result.shape).toEqual([3]);
     });
   });
+
+  describe("Matrix Multiplication", () => {
+    test("should multiply two tensors with dim 1", () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = t1.matmul(t2);
+
+      expect(Array.from(result.data)).toEqual([200]);
+      expect(result.shape).toEqual([1]);
+    });
+
+    test("should multiply two tensors with the correct values", () => {
+      const t1 = new Tensor([
+        [1, 2, 3],
+        [4, 5, 6]
+      ]);
+
+      const t2 = new Tensor([
+        [9, 9, 1],
+        [6, 4, 3],
+        [5, 5, 6]
+      ])
+
+      const result = t1.matmul(t2);
+
+      const expected = [
+        36, 32, 25,
+        96, 86, 55
+      ];
+
+      expect(Array.from(result.data)).toEqual(expected);
+      expect(result.shape).toEqual([2, 3]);
+    });
+  });
+
+
 });

From 729a8528c4f639d1f768c74e8b30a66255af1978 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 21:07:40 +0800
Subject: [PATCH 011/128] feat: operation access modifiers

---
 scripts/macros.ts.j2      | 12 ++++-----
 src/operations/ops.gen.ts | 54 +++++++++++++++++++--------------------
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2
index 0891e2aa..5038d4c8 100644
--- a/scripts/macros.ts.j2
+++ b/scripts/macros.ts.j2
@@ -50,12 +50,12 @@ function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tens
 {% macro binary_op_class(classname, opname, backward_operations) -%}
 // class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations)
 export class {{ classname }} extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _{{ opname }}_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -68,12 +68,12 @@ registerOperation('{{ opname }}', {{ classname }});
 {% macro unary_op_class(classname, opname, backward_operations) -%}
 // class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations)
 export class {{ classname }} extends UnaryOperation {
-  cache: [Tensor];
-  forward(a: Tensor): Tensor {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
     this.cache = [a];
     return _{{ opname }}_tensor(a, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a] = this.cache;
 
     // backward_operations:
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 2a7a408a..b70cdee7 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -15,12 +15,12 @@ export function _sum_tensor(a: Tensor, operation: Operation | null = null): Tens
 
 // class generated from unary_op_class("Sum", "sum", backward_operations)
 export class Sum extends UnaryOperation {
-  cache: [Tensor];
-  forward(a: Tensor): Tensor {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
     this.cache = [a];
     return _sum_tensor(a, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a] = this.cache;
 
     // backward_operations:
@@ -40,12 +40,12 @@ export function _mean_tensor(a: Tensor, operation: Operation | null = null): Ten
 
 // class generated from unary_op_class("Mean", "mean", backward_operations)
 export class Mean extends UnaryOperation {
-  cache: [Tensor];
-  forward(a: Tensor): Tensor {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
     this.cache = [a];
     return _mean_tensor(a, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a] = this.cache;
 
     // backward_operations:
@@ -83,12 +83,12 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 }
 // class generated from binary_op_class("Add", "add", backward_operations)
 export class Add extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _add_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -126,12 +126,12 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 }
 // class generated from binary_op_class("Sub", "sub", backward_operations)
 export class Sub extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _sub_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -169,12 +169,12 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 }
 // class generated from binary_op_class("Mul", "mul", backward_operations)
 export class Mul extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _mul_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -212,12 +212,12 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 }
 // class generated from binary_op_class("Div", "div", backward_operations)
 export class Div extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _div_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -255,12 +255,12 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 }
 // class generated from binary_op_class("Pow", "pow", backward_operations)
 export class Pow extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _pow_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -390,12 +390,12 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
 // class generated from binary_op_class("Matmul", "matmul", backward_operations)
 export class Matmul extends BinaryOperation {
-  cache: [Tensor, Tensor];
-  forward(a: Tensor, b: Tensor): Tensor {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
     this.cache = [a, b];
     return _matmul_tensor(a, b, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a, b] = this.cache;
 
     // backward_operations:
@@ -425,12 +425,12 @@ function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 }
 // class generated from unary_op_class("Log", "log", backward_operations)
 export class Log extends UnaryOperation {
-  cache: [Tensor];
-  forward(a: Tensor): Tensor {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
     this.cache = [a];
     return _log_tensor(a, this);
   }
-  backward(dz: Tensor): void {
+  public backward(dz: Tensor): void {
     const [a] = this.cache;
 
     // backward_operations:

From 8b2a7de4c9b1764a0182e60e98c18b0aac8aa1b9 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 21:08:16 +0800
Subject: [PATCH 012/128] feat: typedoc

---
 .github/workflows/push.yml |  29 +++++++
 .gitignore                 |   1 +
 package.json               |   4 +-
 yarn.lock                  | 158 ++++++++++++++++++++++++++++++++++++-
 4 files changed, 189 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 707de9a8..ca8492e6 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -27,3 +27,32 @@ jobs:
 
         - name: Test
           run: yarn test
+
+  docs:
+    name: Deploy to GitHub Pages
+    runs-on: ubuntu-latest
+    needs: test
+    steps:
+        - name: Check out source code
+          uses: actions/checkout@v4
+
+        - name: Enable Corepack
+          run: corepack enable
+
+        - name: Use Node.js 💻
+          uses: actions/setup-node@v4
+          with:
+            node-version: 20
+            cache: yarn
+
+        - name: Install dependencies
+          run: yarn install --immutable
+
+        - name: Build docs
+          run: yarn docs
+
+        - name: Deploy docs
+          uses: peaceiris/actions-gh-pages@v4
+          with:
+            github_token: ${{ secrets.GITHUB_TOKEN }} 
+            publish_dir: ./docs # The folder the action should deploy.
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f3474e56..f61d2d7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 # See https://help.github.com/ignore-files/ for more about ignoring files.
+/docs
 
 # dependencies
 /node_modules
diff --git a/package.json b/package.json
index 638afa8d..f35d9698 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,8 @@
     "build:browser": "vite build --config vite.config.browser.ts",
     "build:node": "vite build --config vite.config.node.ts",
     "build": "npm run clean && npm run build:node && npm run build:browser",
-    "generate": "node scripts/generate-m4.js",
+    "docs": "typedoc --out docs src",
+    "generate": "python3 scripts/generate.py",
     "test": "jest",
     "test:watch": "jest --watch"
   },
@@ -42,6 +43,7 @@
     "rimraf": "^6.0.1",
     "ts-jest": "^29.4.4",
     "ts-node": "^10.9.2",
+    "typedoc": "^0.28.14",
     "typescript": "^5.9.3",
     "typescript-eslint": "^8.46.0",
     "vite": "^7.1.9",
diff --git a/yarn.lock b/yarn.lock
index 6ef1d96e..fa610f7e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -688,6 +688,19 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@gerrit0/mini-shiki@npm:^3.12.0":
+  version: 3.13.1
+  resolution: "@gerrit0/mini-shiki@npm:3.13.1"
+  dependencies:
+    "@shikijs/engine-oniguruma": "npm:^3.13.0"
+    "@shikijs/langs": "npm:^3.13.0"
+    "@shikijs/themes": "npm:^3.13.0"
+    "@shikijs/types": "npm:^3.13.0"
+    "@shikijs/vscode-textmate": "npm:^10.0.2"
+  checksum: 10c0/926babea969fb6788eb8c36fb69ff4c45273bbebde318297a89a45807aba42d266cab5654f13b4126b0bb9c4d074dbf2505d874d917daa9381d5281a5f66953c
+  languageName: node
+  linkType: hard
+
 "@humanfs/core@npm:^0.19.1":
   version: 0.19.1
   resolution: "@humanfs/core@npm:0.19.1"
@@ -1495,6 +1508,51 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@shikijs/engine-oniguruma@npm:^3.13.0":
+  version: 3.13.0
+  resolution: "@shikijs/engine-oniguruma@npm:3.13.0"
+  dependencies:
+    "@shikijs/types": "npm:3.13.0"
+    "@shikijs/vscode-textmate": "npm:^10.0.2"
+  checksum: 10c0/0cd0307028acf0a30fff7de642b84d4600aa33086f88952f1313f9ef56b604e067ebeb2e64f4e9025c06c68dfd6434c2c5da83d385af4792b622e6ad07f7613f
+  languageName: node
+  linkType: hard
+
+"@shikijs/langs@npm:^3.13.0":
+  version: 3.13.0
+  resolution: "@shikijs/langs@npm:3.13.0"
+  dependencies:
+    "@shikijs/types": "npm:3.13.0"
+  checksum: 10c0/3fe59b55b5d1da9784cd93dc2eaae19249c5d218b39ce52c0c802b38894cdedcc55ccf813486a9362be0c97bbc0568a4f7bb2a62bf2ee0edbb2d52852878c8ed
+  languageName: node
+  linkType: hard
+
+"@shikijs/themes@npm:^3.13.0":
+  version: 3.13.0
+  resolution: "@shikijs/themes@npm:3.13.0"
+  dependencies:
+    "@shikijs/types": "npm:3.13.0"
+  checksum: 10c0/b00052267de6f8acf09d01994823234ef4f75285d4c6587f039f5081490462a50ef73defb916add45fec1f469cf0c15ed53e5ada8ca9a48ebc7a243e4a76bbc6
+  languageName: node
+  linkType: hard
+
+"@shikijs/types@npm:3.13.0, @shikijs/types@npm:^3.13.0":
+  version: 3.13.0
+  resolution: "@shikijs/types@npm:3.13.0"
+  dependencies:
+    "@shikijs/vscode-textmate": "npm:^10.0.2"
+    "@types/hast": "npm:^3.0.4"
+  checksum: 10c0/5f0ceca1dad4f4dfb8c424f1aa78953ace7eb2215d82b863500f1ea023faf55acaa54373f3b59a8ada85f15c304cf658b95eae128c43505855d13607d979a726
+  languageName: node
+  linkType: hard
+
+"@shikijs/vscode-textmate@npm:^10.0.2":
+  version: 10.0.2
+  resolution: "@shikijs/vscode-textmate@npm:10.0.2"
+  checksum: 10c0/36b682d691088ec244de292dc8f91b808f95c89466af421cf84cbab92230f03c8348649c14b3251991b10ce632b0c715e416e992dd5f28ff3221dc2693fd9462
+  languageName: node
+  linkType: hard
+
 "@sinclair/typebox@npm:^0.34.0":
   version: 0.34.41
   resolution: "@sinclair/typebox@npm:0.34.41"
@@ -1612,6 +1670,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/hast@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "@types/hast@npm:3.0.4"
+  dependencies:
+    "@types/unist": "npm:*"
+  checksum: 10c0/3249781a511b38f1d330fd1e3344eed3c4e7ea8eff82e835d35da78e637480d36fad37a78be5a7aed8465d237ad0446abc1150859d0fde395354ea634decf9f7
+  languageName: node
+  linkType: hard
+
 "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6":
   version: 2.0.6
   resolution: "@types/istanbul-lib-coverage@npm:2.0.6"
@@ -1677,6 +1744,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/unist@npm:*":
+  version: 3.0.3
+  resolution: "@types/unist@npm:3.0.3"
+  checksum: 10c0/2b1e4adcab78388e088fcc3c0ae8700f76619dbcb4741d7d201f87e2cb346bfc29a89003cfea2d76c996e1061452e14fcd737e8b25aacf949c1f2d6b2bc3dd60
+  languageName: node
+  linkType: hard
+
 "@types/yargs-parser@npm:*":
   version: 21.0.3
   resolution: "@types/yargs-parser@npm:21.0.3"
@@ -3113,7 +3187,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"entities@npm:^4.5.0":
+"entities@npm:^4.4.0, entities@npm:^4.5.0":
   version: 4.5.0
   resolution: "entities@npm:4.5.0"
   checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250
@@ -5317,6 +5391,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"linkify-it@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "linkify-it@npm:5.0.0"
+  dependencies:
+    uc.micro: "npm:^2.0.0"
+  checksum: 10c0/ff4abbcdfa2003472fc3eb4b8e60905ec97718e11e33cca52059919a4c80cc0e0c2a14d23e23d8c00e5402bc5a885cdba8ca053a11483ab3cc8b3c7a52f88e2d
+  languageName: node
+  linkType: hard
+
 "local-pkg@npm:^1.0.0":
   version: 1.1.2
   resolution: "local-pkg@npm:1.1.2"
@@ -5399,6 +5482,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"lunr@npm:^2.3.9":
+  version: 2.3.9
+  resolution: "lunr@npm:2.3.9"
+  checksum: 10c0/77d7dbb4fbd602aac161e2b50887d8eda28c0fa3b799159cee380fbb311f1e614219126ecbbd2c3a9c685f1720a8109b3c1ca85cc893c39b6c9cc6a62a1d8a8b
+  languageName: node
+  linkType: hard
+
 "magic-string@npm:^0.30.17":
   version: 0.30.19
   resolution: "magic-string@npm:0.30.19"
@@ -5472,6 +5562,22 @@ __metadata:
   languageName: node
   linkType: hard
 
+"markdown-it@npm:^14.1.0":
+  version: 14.1.0
+  resolution: "markdown-it@npm:14.1.0"
+  dependencies:
+    argparse: "npm:^2.0.1"
+    entities: "npm:^4.4.0"
+    linkify-it: "npm:^5.0.0"
+    mdurl: "npm:^2.0.0"
+    punycode.js: "npm:^2.3.1"
+    uc.micro: "npm:^2.1.0"
+  bin:
+    markdown-it: bin/markdown-it.mjs
+  checksum: 10c0/9a6bb444181d2db7016a4173ae56a95a62c84d4cbfb6916a399b11d3e6581bf1cc2e4e1d07a2f022ae72c25f56db90fbe1e529fca16fbf9541659dc53480d4b4
+  languageName: node
+  linkType: hard
+
 "math-intrinsics@npm:^1.1.0":
   version: 1.1.0
   resolution: "math-intrinsics@npm:1.1.0"
@@ -5479,6 +5585,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"mdurl@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "mdurl@npm:2.0.0"
+  checksum: 10c0/633db522272f75ce4788440669137c77540d74a83e9015666a9557a152c02e245b192edc20bc90ae953bbab727503994a53b236b4d9c99bdaee594d0e7dd2ce0
+  languageName: node
+  linkType: hard
+
 "merge-stream@npm:^2.0.0":
   version: 2.0.0
   resolution: "merge-stream@npm:2.0.0"
@@ -5535,7 +5648,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4":
+"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5":
   version: 9.0.5
   resolution: "minimatch@npm:9.0.5"
   dependencies:
@@ -6288,6 +6401,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"punycode.js@npm:^2.3.1":
+  version: 2.3.1
+  resolution: "punycode.js@npm:2.3.1"
+  checksum: 10c0/1d12c1c0e06127fa5db56bd7fdf698daf9a78104456a6b67326877afc21feaa821257b171539caedd2f0524027fa38e67b13dd094159c8d70b6d26d2bea4dfdb
+  languageName: node
+  linkType: hard
+
 "punycode@npm:^2.1.0":
   version: 2.3.1
   resolution: "punycode@npm:2.3.1"
@@ -7207,6 +7327,7 @@ __metadata:
     rimraf: "npm:^6.0.1"
     ts-jest: "npm:^29.4.4"
     ts-node: "npm:^10.9.2"
+    typedoc: "npm:^0.28.14"
     typescript: "npm:^5.9.3"
     typescript-eslint: "npm:^8.46.0"
     vite: "npm:^7.1.9"
@@ -7412,6 +7533,23 @@ __metadata:
   languageName: node
   linkType: hard
 
+"typedoc@npm:^0.28.14":
+  version: 0.28.14
+  resolution: "typedoc@npm:0.28.14"
+  dependencies:
+    "@gerrit0/mini-shiki": "npm:^3.12.0"
+    lunr: "npm:^2.3.9"
+    markdown-it: "npm:^14.1.0"
+    minimatch: "npm:^9.0.5"
+    yaml: "npm:^2.8.1"
+  peerDependencies:
+    typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x
+  bin:
+    typedoc: bin/typedoc
+  checksum: 10c0/a8727134991ba3f9a982e9f6ceecfbcf0fac531e4865e4865cdee68ea6fe1a594228b8654011d38ffa2332b7e84e4eaa3d0dac04a8bdf36a0686d1c3f327e80b
+  languageName: node
+  linkType: hard
+
 "typescript-eslint@npm:^8.46.0":
   version: 8.46.0
   resolution: "typescript-eslint@npm:8.46.0"
@@ -7467,6 +7605,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"uc.micro@npm:^2.0.0, uc.micro@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "uc.micro@npm:2.1.0"
+  checksum: 10c0/8862eddb412dda76f15db8ad1c640ccc2f47cdf8252a4a30be908d535602c8d33f9855dfcccb8b8837855c1ce1eaa563f7fa7ebe3c98fd0794351aab9b9c55fa
+  languageName: node
+  linkType: hard
+
 "ufo@npm:^1.6.1":
   version: 1.6.1
   resolution: "ufo@npm:1.6.1"
@@ -7945,6 +8090,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"yaml@npm:^2.8.1":
+  version: 2.8.1
+  resolution: "yaml@npm:2.8.1"
+  bin:
+    yaml: bin.mjs
+  checksum: 10c0/7c587be00d9303d2ae1566e03bc5bc7fe978ba0d9bf39cc418c3139d37929dfcb93a230d9749f2cb578b6aa5d9ebebc322415e4b653cb83acd8bc0bc321707f3
+  languageName: node
+  linkType: hard
+
 "yargs-parser@npm:^21.1.1":
   version: 21.1.1
   resolution: "yargs-parser@npm:21.1.1"

From 7a2984b6608ab38387a81d4f4874af05fe253951 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 21:11:41 +0800
Subject: [PATCH 013/128] fix sum, mean export

---
 src/operations/ops.gen.ts | 4 ++--
 src/operations/ops.ts.j2  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index b70cdee7..5dddc176 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -5,7 +5,7 @@ import gpu from "../gpu";
 import { Operation, BinaryOperation, UnaryOperation } from './base';
 import { registerOperation } from "./registry";
 
-export function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
     a.data.reduce((acc, val) => acc + val, 0),
     { requires_grad: a.requires_grad },
@@ -30,7 +30,7 @@ export class Sum extends UnaryOperation {
 }
 registerOperation('sum', Sum);
 
-export function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
     a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
     { requires_grad: a.requires_grad },
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index f5d3c557..98052442 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -5,7 +5,7 @@ import gpu from "../gpu";
 import { Operation, BinaryOperation, UnaryOperation } from './base';
 import { registerOperation } from "./registry";
 
-export function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
     a.data.reduce((acc, val) => acc + val, 0),
     { requires_grad: a.requires_grad },
@@ -15,7 +15,7 @@ export function _sum_tensor(a: Tensor, operation: Operation | null = null): Tens
 
 {{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.data.length).fill(dz.data[0]));", "a.backward(result);"]) }}
 
-export function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
     a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
     { requires_grad: a.requires_grad },

From f24990ede0cc91dbe36481ee4b00b2159bfccb6e Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 21:41:19 +0800
Subject: [PATCH 014/128] refactor: code formatting

---
 src/broadcasting.ts          | 12 ++---
 src/creation/index.ts        |  6 ++-
 src/gpu.ts                   |  5 +-
 src/operations/functional.ts |  2 +-
 src/operations/ops.gen.ts    | 88 +++++++++++++++++++++++-------------
 src/operations/ops.ts.j2     | 88 +++++++++++++++++++++++-------------
 6 files changed, 127 insertions(+), 74 deletions(-)

diff --git a/src/broadcasting.ts b/src/broadcasting.ts
index 0b57aed6..105b9b6b 100644
--- a/src/broadcasting.ts
+++ b/src/broadcasting.ts
@@ -22,7 +22,7 @@ export function _broadcast_shape(a_shape: number[], b_shape: number[]): number[]
 }
 
 export function _pad_shape(shape: number[], broadcast_shape: number[]): number[] {
-  if(shape.length >= broadcast_shape.length) {
+  if (shape.length >= broadcast_shape.length) {
     return shape;
   }
 
@@ -84,10 +84,10 @@ export function _get_original_index_from_transposed_index(
 
   for (let i = this.constants.shape_length - 1; i >= 0; i--) {
     const dim_index = temp_index % original_shape[i];
-    if(i == dim0) {
+    if (i == dim0) {
       dim0_index = dim_index;
     }
-    if(i == dim1) {
+    if (i == dim1) {
       dim1_index = dim_index;
     }
     temp_index = Math.floor(temp_index / original_shape[i]);
@@ -97,9 +97,9 @@ export function _get_original_index_from_transposed_index(
 
   for (let j = this.constants.shape_length - 1; j >= 0; j--) {
     const dim_index = temp_index % original_shape[j];
-    if(j == dim0) {
+    if (j == dim0) {
       original_index = original_index + dim1_index * cur_stride;
-    } else if(j == dim1) {
+    } else if (j == dim1) {
       original_index = original_index + dim0_index * cur_stride;
     } else {
       original_index = original_index + dim_index * cur_stride;
@@ -111,4 +111,4 @@ export function _get_original_index_from_transposed_index(
   return original_index;
 
   // return transposed_index;
-}
\ No newline at end of file
+}
diff --git a/src/creation/index.ts b/src/creation/index.ts
index 9edf9fef..64f51490 100644
--- a/src/creation/index.ts
+++ b/src/creation/index.ts
@@ -49,7 +49,9 @@ export function rand(...args: number[] | number[][]): Tensor {
 }
 
 export function randint(low: number, high: number, shape: number[]): Tensor {
-  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.floor(Math.random() * (high - low) + low)));
+  const tensor = new Tensor(
+    Array(shape.reduce((a, b) => a * b, 1)).fill(Math.floor(Math.random() * (high - low) + low))
+  );
   tensor.shape = shape;
   return tensor;
-}
\ No newline at end of file
+}
diff --git a/src/gpu.ts b/src/gpu.ts
index e72362e9..1773b23a 100644
--- a/src/gpu.ts
+++ b/src/gpu.ts
@@ -4,7 +4,10 @@
  */
 
 import { GPU } from '@veehz/gpu.js';
-import { _get_original_index_from_transposed_index, _get_original_index_kernel } from './broadcasting';
+import {
+  _get_original_index_from_transposed_index,
+  _get_original_index_kernel
+} from './broadcasting';
 
 const gpu = new GPU();
 
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index ee00853d..0a824ec6 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -35,4 +35,4 @@ export const sum = generate_unary_function('sum');
 export const mean = generate_unary_function('mean');
 export const pow = generate_unary_function('pow');
 export const log = generate_unary_function('log');
-export const matmul = generate_binary_function('matmul');
\ No newline at end of file
+export const matmul = generate_binary_function('matmul');
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 5dddc176..da179054 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -1,9 +1,14 @@
 // This file is generated by scripts/generate_script.py from src/operations/ops.ts.j2
-import { Tensor } from "../tensor";
-import { _broadcast_shape, _get_original_index_from_transposed_index, _get_original_index_kernel, _pad_shape } from "../broadcasting";
-import gpu from "../gpu";
+import { Tensor } from '../tensor';
+import {
+  _broadcast_shape,
+  _get_original_index_from_transposed_index,
+  _get_original_index_kernel,
+  _pad_shape
+} from '../broadcasting';
+import gpu from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from './base';
-import { registerOperation } from "./registry";
+import { registerOperation } from './registry';
 
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
@@ -270,7 +275,12 @@ export class Pow extends BinaryOperation {
 }
 registerOperation('pow', Pow);
 
-function _transpose_tensor(a: Tensor, dim0: number, dim1: number, operation: Operation | null = null): Tensor {
+function _transpose_tensor(
+  a: Tensor,
+  dim0: number,
+  dim1: number,
+  operation: Operation | null = null
+): Tensor {
   const kernel = gpu.createKernel(
     function (a: number[], as: number[], dim0: number, dim1: number) {
       const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
@@ -284,7 +294,7 @@ function _transpose_tensor(a: Tensor, dim0: number, dim1: number, operation: Ope
     }
   );
 
-  const swapped_shape = a.shape;
+  const swapped_shape = [...a.shape];
   [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
 
   return new Tensor(
@@ -320,25 +330,34 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
   const a_shape = a_1d ? [1, a.shape[0]] : a.shape;
   const b_shape = b_1d ? [b.shape[0], 1] : b.shape;
 
-  if(a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
+  if (a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
     // TODO: check what error pytorch throws
-    throw new Error("Shape mismatch: " + a.shape + " and " + b.shape);
+    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
   }
 
   const loop_iterations = a_shape[a_shape.length - 1];
 
-  if(loop_iterations > 1000) {
+  if (loop_iterations > 1000) {
     // TODO: can try fixing with maxLoopIterations by gpu.js
-    throw new Error("Loop iterations too large: " + loop_iterations);
+    throw new Error('Loop iterations too large: ' + loop_iterations);
   }
 
-  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2))
-                            .concat([a_shape[a_shape.length - 2], b_shape[b_shape.length - 1]]);
+  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([
+    a_shape[a_shape.length - 2],
+    b_shape[b_shape.length - 1]
+  ]);
 
   const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
 
-  function _matmul_kernel(a: number[], as: number[], b: number[], bs: number[], bcs: number[], lp: number) {
+  function _matmul_kernel(
+    a: number[],
+    as: number[],
+    b: number[],
+    bs: number[],
+    bcs: number[],
+    lp: number
+  ) {
     let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
     let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -346,12 +365,12 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
     const position = this.thread.x % (bcs[l] * bcs[l + 1]);
     a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
-    b_index = b_index * bs[l] * bs[l + 1] + position % bcs[l + 1];
+    b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
 
-    const b_stride = bs[l+1];
+    const b_stride = bs[l + 1];
 
     let sum = 0;
-    for(let i = 0; i < lp; i++) {
+    for (let i = 0; i < lp; i++) {
       sum = sum + a[a_index] * b[b_index];
       a_index = a_index + 1;
       b_index = b_index + b_stride;
@@ -360,29 +379,35 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
     return sum;
   }
 
-  const kernel = gpu.createKernel(
-    _matmul_kernel,
-    {
-      constants: {
-        // assumes that _get_original_index_kernel reads from the front
-        shape_length: broadcast_shape.length - 2
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
-    }
-  );
+  const kernel = gpu.createKernel(_matmul_kernel, {
+    constants: {
+      // assumes that _get_original_index_kernel reads from the front
+      shape_length: broadcast_shape.length - 2
+    },
+    output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+  });
 
-  let shape_after_removing_extra_dims = broadcast_shape;
+  let shape_after_removing_extra_dims = [...broadcast_shape];
 
-  if(a_1d) {
-    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -2).concat([a.shape[0]]);
+  if (a_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims
+      .slice(0, -2)
+      .concat([broadcast_shape[broadcast_shape.length - 1]]);
   }
 
-  if(b_1d) {
+  if (b_1d) {
     shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
   }
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, loop_iterations) as number[],
+    kernel(
+      a.data,
+      padded_a_shape,
+      b.data,
+      padded_b_shape,
+      broadcast_shape,
+      loop_iterations
+    ) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: shape_after_removing_extra_dims }
   );
@@ -438,4 +463,3 @@ export class Log extends UnaryOperation {
   }
 }
 registerOperation('log', Log);
-
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index 98052442..f4100d2b 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -1,9 +1,14 @@
 {% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class %}
-import { Tensor } from "../tensor";
-import { _broadcast_shape, _get_original_index_from_transposed_index, _get_original_index_kernel, _pad_shape } from "../broadcasting";
-import gpu from "../gpu";
+import { Tensor } from '../tensor';
+import {
+  _broadcast_shape,
+  _get_original_index_from_transposed_index,
+  _get_original_index_kernel,
+  _pad_shape
+} from '../broadcasting';
+import gpu from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from './base';
-import { registerOperation } from "./registry";
+import { registerOperation } from './registry';
 
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
@@ -43,7 +48,12 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   "b.backward(dz.mul(a.pow(b)).mul(a.log()));"
 ])}}
 
-function _transpose_tensor(a: Tensor, dim0: number, dim1: number, operation: Operation | null = null): Tensor {
+function _transpose_tensor(
+  a: Tensor,
+  dim0: number,
+  dim1: number,
+  operation: Operation | null = null
+): Tensor {
   const kernel = gpu.createKernel(
     function (a: number[], as: number[], dim0: number, dim1: number) {
       const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
@@ -57,7 +67,7 @@ function _transpose_tensor(a: Tensor, dim0: number, dim1: number, operation: Ope
     }
   );
 
-  const swapped_shape = a.shape;
+  const swapped_shape = [...a.shape];
   [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
 
   return new Tensor(
@@ -93,25 +103,34 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
   const a_shape = a_1d ? [1, a.shape[0]] : a.shape;
   const b_shape = b_1d ? [b.shape[0], 1] : b.shape;
 
-  if(a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
+  if (a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
     // TODO: check what error pytorch throws
-    throw new Error("Shape mismatch: " + a.shape + " and " + b.shape);
+    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
   }
 
   const loop_iterations = a_shape[a_shape.length - 1];
 
-  if(loop_iterations > 1000) {
+  if (loop_iterations > 1000) {
     // TODO: can try fixing with maxLoopIterations by gpu.js
-    throw new Error("Loop iterations too large: " + loop_iterations);
+    throw new Error('Loop iterations too large: ' + loop_iterations);
   }
 
-  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2))
-                            .concat([a_shape[a_shape.length - 2], b_shape[b_shape.length - 1]]);
+  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([
+    a_shape[a_shape.length - 2],
+    b_shape[b_shape.length - 1]
+  ]);
 
   const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
 
-  function _matmul_kernel(a: number[], as: number[], b: number[], bs: number[], bcs: number[], lp: number) {
+  function _matmul_kernel(
+    a: number[],
+    as: number[],
+    b: number[],
+    bs: number[],
+    bcs: number[],
+    lp: number
+  ) {
     let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
     let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
 
@@ -119,12 +138,12 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
     const position = this.thread.x % (bcs[l] * bcs[l + 1]);
     a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
-    b_index = b_index * bs[l] * bs[l + 1] + position % bcs[l + 1];
+    b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
 
-    const b_stride = bs[l+1];
+    const b_stride = bs[l + 1];
 
     let sum = 0;
-    for(let i = 0; i < lp; i++) {
+    for (let i = 0; i < lp; i++) {
       sum = sum + a[a_index] * b[b_index];
       a_index = a_index + 1;
       b_index = b_index + b_stride;
@@ -133,29 +152,35 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
     return sum;
   }
 
-  const kernel = gpu.createKernel(
-    _matmul_kernel,
-    {
-      constants: {
-        // assumes that _get_original_index_kernel reads from the front
-        shape_length: broadcast_shape.length - 2
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)],
-    }
-  );
+  const kernel = gpu.createKernel(_matmul_kernel, {
+    constants: {
+      // assumes that _get_original_index_kernel reads from the front
+      shape_length: broadcast_shape.length - 2
+    },
+    output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+  });
 
-  let shape_after_removing_extra_dims = broadcast_shape;
+  let shape_after_removing_extra_dims = [...broadcast_shape];
 
-  if(a_1d) {
-    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -2).concat([a.shape[0]]);
+  if (a_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims
+      .slice(0, -2)
+      .concat([broadcast_shape[broadcast_shape.length - 1]]);
   }
 
-  if(b_1d) {
+  if (b_1d) {
     shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
   }
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, loop_iterations) as number[],
+    kernel(
+      a.data,
+      padded_a_shape,
+      b.data,
+      padded_b_shape,
+      broadcast_shape,
+      loop_iterations
+    ) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: shape_after_removing_extra_dims }
   );
@@ -179,5 +204,4 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
 {{ unary_op_base("log", "Math.log(a[this.thread.x])") }}
 {{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }}
-
 {# {{ unary_op_base("neg", "-a[this.thread.x]") }} #}

From 78ac92886fe76e89f911db9b1534423c7a195450 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 22:40:11 +0800
Subject: [PATCH 015/128] feat: nn layers and modules

---
 src/index.ts                 |   1 +
 src/nn/functional.ts         |  37 ++++
 src/nn/index.ts              |   4 +
 src/nn/loss.ts               |  25 +++
 src/nn/module.ts             |  91 ++++++++
 src/nn/ops.gen.ts            |  44 ++++
 src/nn/ops.ts.j2             |  14 ++
 src/operations/functional.ts |  18 ++
 src/operations/ops.gen.ts    | 392 +++++++++++++++++++++++++++++++++++
 src/operations/ops.ts.j2     |  29 ++-
 src/tensor.ts                |  52 ++++-
 test/module.test.ts          |  27 +++
 test/nn_functional.test.ts   |  12 ++
 13 files changed, 736 insertions(+), 10 deletions(-)
 create mode 100644 src/nn/functional.ts
 create mode 100644 src/nn/index.ts
 create mode 100644 src/nn/loss.ts
 create mode 100644 src/nn/module.ts
 create mode 100644 src/nn/ops.gen.ts
 create mode 100644 src/nn/ops.ts.j2
 create mode 100644 test/module.test.ts
 create mode 100644 test/nn_functional.test.ts

diff --git a/src/index.ts b/src/index.ts
index 44ea8e5f..e4302111 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -3,4 +3,5 @@ import { Tensor } from './tensor';
 export * from './operations/ops.gen';
 export * from './operations/functional';
 export * from './creation/index';
+export * as nn from './nn/index';
 export { Tensor };
diff --git a/src/nn/functional.ts b/src/nn/functional.ts
new file mode 100644
index 00000000..a561fd08
--- /dev/null
+++ b/src/nn/functional.ts
@@ -0,0 +1,37 @@
+import { Tensor } from "../tensor";
+import { getOperation } from "../operations/registry";
+
+function generate_function(opname: string) {
+  return (...args: (Tensor | number)[]) => {
+    const operation = new (getOperation(opname))();
+    return operation.forward(...args);
+  };
+}
+
+function generate_unary_function(opname: string) {
+  return (a: Tensor | number) => {
+    if (typeof a == 'number') {
+      a = new Tensor(a);
+    }
+
+    const operation = new (getOperation(opname))();
+    return operation.forward(a);
+  };
+}
+
+function generate_binary_function(opname: string) {
+  return (a: Tensor | number, b: Tensor | number) => {
+    if (typeof a == 'number') {
+      a = new Tensor(a);
+    }
+
+    if (typeof b == 'number') {
+      b = new Tensor(b);
+    }
+
+    const operation = new (getOperation(opname))();
+    return operation.forward(a, b);
+  };
+}
+
+export const relu = generate_unary_function('relu');
diff --git a/src/nn/index.ts b/src/nn/index.ts
new file mode 100644
index 00000000..c92f96a3
--- /dev/null
+++ b/src/nn/index.ts
@@ -0,0 +1,4 @@
+import './ops.gen';
+
+export * from './module';
+export * as functional from './functional';
\ No newline at end of file
diff --git a/src/nn/loss.ts b/src/nn/loss.ts
new file mode 100644
index 00000000..881d1319
--- /dev/null
+++ b/src/nn/loss.ts
@@ -0,0 +1,25 @@
+import { Tensor } from "../tensor";
+
+class Loss {}
+
+
+
+export class MSELoss extends Loss {
+  constructor() {
+    super();
+  }
+
+  forward(input: Tensor, target: Tensor) {
+    return input.sub(target).pow(2).mean();
+  }
+}
+
+export class L1Loss extends Loss {
+  constructor() {
+    super();
+  }
+
+  forward(input: Tensor, target: Tensor) {
+    return input.sub(target).abs().mean();
+  }
+}
\ No newline at end of file
diff --git a/src/nn/module.ts b/src/nn/module.ts
new file mode 100644
index 00000000..2454f19d
--- /dev/null
+++ b/src/nn/module.ts
@@ -0,0 +1,91 @@
+import { Tensor } from "../tensor";
+import { NestedNumberArray } from "../tensor";
+import { Operation } from "../operations/base";
+import { rand } from "../creation";
+import { functional } from ".";
+
+export class Parameter extends Tensor {
+  constructor(
+    data: NestedNumberArray | Tensor | Parameter,
+    // Default to requires_grad=true
+    options: { requires_grad?: boolean } = {
+        requires_grad: true,
+    },
+    internal_options: { operation?: Operation; shape?: number[] } = {}
+  ) {
+    if (data instanceof Tensor) {
+      super(data.data, { requires_grad: true }, { shape: data.shape });
+    } else if (data instanceof Parameter) {
+      super(data.data, { requires_grad: true }, { shape: data.shape });
+    } else {
+      super(data, options, internal_options);
+    }
+  }
+}
+
+export abstract class Module {
+  private _modules: { [key: string]: Module };
+  private _parameters: { [key: string]: Parameter };
+
+  constructor() {
+    this._parameters = {};
+    this._modules = {};
+  }
+
+  private register_parameter(parameter_name: string, parameter: Parameter) {
+    this._parameters[parameter_name] = parameter;
+  }
+
+  private register_module(module_name: string, module: Module) {
+    this._modules[module_name] = module;
+  }
+
+  protected register(name: string, value: Parameter | Module) {
+    if (value instanceof Parameter) {
+      this.register_parameter(name, value);
+    } else {
+      this.register_module(name, value);
+    }
+  }
+
+  public abstract forward(...args: Tensor[]): Tensor;
+
+  public parameters(): Parameter[] {
+    let params: Parameter[] = Object.values(this._parameters);
+    for (const module of Object.values(this._modules)) {
+      params = params.concat(module.parameters());
+    }
+    return params;
+  }
+}
+
+export class Linear extends Module {
+  private weight: Parameter;
+  private bias: Parameter;
+
+  constructor(in_features: number, out_features: number) {
+    super();
+    const k = Math.sqrt(1 / in_features);
+
+    this.weight = new Parameter(rand([out_features, in_features]).mul(2 * k).sub(k));
+    console.log("weight", this.weight.shape);
+    this.bias = new Parameter(rand([out_features]).mul(2 * k).sub(k));
+
+    this.register("weight", this.weight);
+    this.register("bias", this.bias);
+  }
+
+  forward(input: Tensor) {
+    return input.matmul(this.weight.transpose(0, 1)).add(this.bias);
+  }
+}
+
+export class ReLU extends Module {
+  constructor() {
+    super();
+  }
+
+  forward(input: Tensor) {
+    return functional.relu(input);
+  }
+}
diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts
new file mode 100644
index 00000000..34bc25ac
--- /dev/null
+++ b/src/nn/ops.gen.ts
@@ -0,0 +1,44 @@
+// This file is generated by scripts/generate_script.py from src/nn/ops.ts.j2
+import { Tensor } from '../tensor';
+import {
+  _broadcast_shape,
+  _get_original_index_from_transposed_index,
+  _get_original_index_kernel,
+  _pad_shape
+} from '../broadcasting';
+import gpu from '../gpu';
+import { Operation, BinaryOperation, UnaryOperation } from '../operations/base';
+import { registerOperation } from '../operations/registry';
+
+// function generated from unary_op_base("relu", "Math.max(a[this.thread.x], 0)")
+function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.max(a[this.thread.x], 0);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Relu", "relu", backward_operations)
+export class Relu extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _relu_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.gt(0)));
+  }
+}
+registerOperation('relu', Relu);
\ No newline at end of file
diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2
new file mode 100644
index 00000000..3c4fbd02
--- /dev/null
+++ b/src/nn/ops.ts.j2
@@ -0,0 +1,14 @@
+{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class %}
+import { Tensor } from '../tensor';
+import {
+  _broadcast_shape,
+  _get_original_index_from_transposed_index,
+  _get_original_index_kernel,
+  _pad_shape
+} from '../broadcasting';
+import gpu from '../gpu';
+import { Operation, BinaryOperation, UnaryOperation } from '../operations/base';
+import { registerOperation } from '../operations/registry';
+
+{{ unary_op_base("relu", "Math.max(a[this.thread.x], 0)") }}
+{{ unary_op_class("Relu", "relu", ["a.backward(dz.mul(a.gt(0)));"]) }}
\ No newline at end of file
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 0a824ec6..74dac8d7 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -1,6 +1,13 @@
 import { Tensor } from '../tensor';
 import { getOperation } from './registry';
 
+function generate_function(opname: string) {
+  return (...args: (Tensor | number)[]) => {
+    const operation = new (getOperation(opname))();
+    return operation.forward(...args);
+  };
+}
+
 function generate_unary_function(opname: string) {
   return (a: Tensor | number) => {
     if (typeof a == 'number') {
@@ -35,4 +42,15 @@ export const sum = generate_unary_function('sum');
 export const mean = generate_unary_function('mean');
 export const pow = generate_unary_function('pow');
 export const log = generate_unary_function('log');
+export const transpose = generate_function('transpose');
 export const matmul = generate_binary_function('matmul');
+export const fmod = generate_binary_function('fmod');
+export const lt = generate_binary_function('lt');
+export const gt = generate_binary_function('gt');
+export const le = generate_binary_function('le');
+export const ge = generate_binary_function('ge');
+export const eq = generate_binary_function('eq');
+export const ne = generate_binary_function('ne');
+export const sqrt = generate_unary_function('sqrt');
+export const sign = generate_unary_function('sign');
+export const abs = generate_unary_function('abs');
\ No newline at end of file
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index da179054..b41962b7 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -8,6 +8,7 @@ import {
 } from '../broadcasting';
 import gpu from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from './base';
+import * as functional from './functional';
 import { registerOperation } from './registry';
 
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
@@ -429,7 +430,398 @@ export class Matmul extends BinaryOperation {
 }
 registerOperation('matmul', Matmul);
 
+// function generated from binary_op_base("fmod", "a[a_index] % b[b_index]")
+function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] % b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Fmod", "fmod", backward_operations)
+export class Fmod extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _fmod_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz);
+  }
+}
+registerOperation('fmod', Fmod);
+
+// function generated from binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0")
+function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return (a[a_index] < b[b_index]) ? 1 : 0;
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Lt", "lt", backward_operations)
+export class Lt extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _lt_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('lt', Lt);
+
+// function generated from binary_op_base("gt", "(a[a_index] > b[b_index]) ? 1 : 0")
+function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return (a[a_index] > b[b_index]) ? 1 : 0;
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Gt", "gt", backward_operations)
+export class Gt extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _gt_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('gt', Gt);
+
+// function generated from binary_op_base("le", "(a[a_index] <= b[b_index]) ? 1 : 0")
+function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return (a[a_index] <= b[b_index]) ? 1 : 0;
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Le", "le", backward_operations)
+export class Le extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _le_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('le', Le);
+
+// function generated from binary_op_base("ge", "(a[a_index] >= b[b_index]) ? 1 : 0")
+function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return (a[a_index] >= b[b_index]) ? 1 : 0;
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
 
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Ge", "ge", backward_operations)
+export class Ge extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _ge_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('ge', Ge);
+
+// function generated from binary_op_base("eq", "(a[a_index] == b[b_index]) ? 1 : 0")
+function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return (a[a_index] == b[b_index]) ? 1 : 0;
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Eq", "eq", backward_operations)
+export class Eq extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _eq_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('eq', Eq);
+
+// function generated from binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0")
+function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return (a[a_index] != b[b_index]) ? 1 : 0;
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Ne", "ne", backward_operations)
+export class Ne extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _ne_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('ne', Ne);
+
+// function generated from unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])")
+function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.sqrt(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Sqrt", "sqrt", backward_operations)
+export class Sqrt extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sqrt_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(new Tensor(1).div(a.sqrt()).div(2));
+  }
+}
+registerOperation('sqrt', Sqrt);
+
+// function generated from unary_op_base("sign", "Math.sign(a[this.thread.x])")
+function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.sign(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Sign", "sign", backward_operations)
+export class Sign extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sign_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('sign', Sign);
+
+// function generated from unary_op_base("abs", "Math.abs(a[this.thread.x])")
+function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.abs(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Abs", "abs", backward_operations)
+export class Abs extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _abs_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(functional.sign(a)));
+  }
+}
+registerOperation('abs', Abs);
 
 // function generated from unary_op_base("log", "Math.log(a[this.thread.x])")
 function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index f4100d2b..074cd72f 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -8,6 +8,7 @@ import {
 } from '../broadcasting';
 import gpu from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from './base';
+import * as functional from './functional';
 import { registerOperation } from './registry';
 
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
@@ -188,19 +189,35 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
 {{ binary_op_class("Matmul", "matmul", []) }}
 
-{# {{ binary_op_base("mod", "a[a_index] % b[b_index]") }}
+{{ binary_op_base("fmod", "a[a_index] % b[b_index]") }}
+{{ binary_op_class("Fmod", "fmod", ["a.backward(dz);"]) }}
+
 {{ binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0") }}
+{{ binary_op_class("Lt", "lt", []) }}
+
 {{ binary_op_base("gt", "(a[a_index] > b[b_index]) ? 1 : 0") }}
+{{ binary_op_class("Gt", "gt", []) }}
+
 {{ binary_op_base("le", "(a[a_index] <= b[b_index]) ? 1 : 0") }}
+{{ binary_op_class("Le", "le", []) }}
+
 {{ binary_op_base("ge", "(a[a_index] >= b[b_index]) ? 1 : 0") }}
+{{ binary_op_class("Ge", "ge", []) }}
+
 {{ binary_op_base("eq", "(a[a_index] == b[b_index]) ? 1 : 0") }}
-{{ binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0") }} #}
+{{ binary_op_class("Eq", "eq", []) }}
+
+{{ binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0") }}
+{{ binary_op_class("Ne", "ne", []) }}
+
+{{ unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])") }}
+{{ unary_op_class("Sqrt", "sqrt", ["a.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }}
+
+{{ unary_op_base("sign", "Math.sign(a[this.thread.x])") }}
+{{ unary_op_class("Sign", "sign", []) }}
 
-{# {{ unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])") }}
 {{ unary_op_base("abs", "Math.abs(a[this.thread.x])") }}
-{{ unary_op_base("sin", "Math.sin(a[this.thread.x])") }}
-{{ unary_op_base("cos", "Math.cos(a[this.thread.x])") }}
-{{ unary_op_base("exp", "Math.exp(a[this.thread.x])") }} #}
+{{ unary_op_class("Abs", "abs", ["a.backward(dz.mul(functional.sign(a)));"]) }}
 
 {{ unary_op_base("log", "Math.log(a[this.thread.x])") }}
 {{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }}
diff --git a/src/tensor.ts b/src/tensor.ts
index eea6a26d..0e022958 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -114,12 +114,12 @@ export class Tensor {
     return this._executeUnaryOp('sum');
   }
 
-  pow(other: Tensor | number): Tensor {
-    return this._executeBinaryOp('pow', other);
+  mean(): Tensor {
+    return this._executeUnaryOp('mean');
   }
 
-  log(): Tensor {
-    return this._executeUnaryOp('log');
+  pow(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('pow', other);
   }
 
   transpose(dim0: number, dim1: number): Tensor {
@@ -130,6 +130,50 @@ export class Tensor {
     return this._executeBinaryOp('matmul', other);
   }
 
+  fmod(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('fmod', other);
+  }
+
+  lt(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('lt', other);
+  }
+
+  gt(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('gt', other);
+  }
+
+  le(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('le', other);
+  }
+
+  ge(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('ge', other);
+  }
+  
+  eq(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('eq', other);
+  }
+
+  ne(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('ne', other);
+  }
+
+  sqrt(): Tensor {
+    return this._executeUnaryOp('sqrt');
+  }
+
+  sign(): Tensor {
+    return this._executeUnaryOp('sign');
+  }
+
+  abs(): Tensor {
+    return this._executeUnaryOp('abs');
+  }
+
+  log(): Tensor {
+    return this._executeUnaryOp('log');
+  }
+
   item(): number {
     if (this.data.length !== 1) {
       throw new Error('Tensor.item() is only valid for scalars');
diff --git a/test/module.test.ts b/test/module.test.ts
new file mode 100644
index 00000000..6f281a70
--- /dev/null
+++ b/test/module.test.ts
@@ -0,0 +1,27 @@
+import * as torch from "../src/index";
+
+describe("Module", () => {
+  describe("Linear", () => {
+    test("should create a linear module", () => {
+      const linear = new torch.nn.Linear(10, 20);
+      expect(linear.parameters().length).toEqual(2);
+      expect(linear.parameters()[0].shape).toEqual([20, 10]);
+      expect(linear.parameters()[1].shape).toEqual([20]);
+    });
+
+    test("should forward a tensor", () => {
+      const linear = new torch.nn.Linear(10, 20);
+      const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+      const output = linear.forward(input);
+      expect(output.shape).toEqual([20]);
+    });
+
+    test("should forward a tensor (2D)", () => {
+      // example from https://docs.pytorch.org/docs/stable/generated/torch.nn.Linear.html
+      const m = new torch.nn.Linear(20, 30);
+      const input = torch.randn(128, 20);
+      const output = m.forward(input);
+      expect(output.shape).toEqual([128, 30]);
+    });
+  });
+});
\ No newline at end of file
diff --git a/test/nn_functional.test.ts b/test/nn_functional.test.ts
new file mode 100644
index 00000000..134a57f7
--- /dev/null
+++ b/test/nn_functional.test.ts
@@ -0,0 +1,12 @@
+import * as torch from "../src/index";
+
+describe("NN Functional", () => {
+  describe("Relu", () => {
+    test("should forward a tensor", () => {
+      const x = new torch.Tensor([1, -2, 3, -4, 5]);
+      const result = torch.nn.functional.relu(x);
+      expect(Array.from(result.data)).toEqual([1, 0, 3, 0, 5]);
+      expect(result.shape).toEqual([5]);
+    });
+  });
+});
\ No newline at end of file

From 02201981a9ec548148bd7d46380f4aaadea9fedb Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 23:10:46 +0800
Subject: [PATCH 016/128] feat: optimizers

---
 src/index.ts            |  1 +
 src/optim/base.ts       | 19 ++++++++++++
 src/optim/index.ts      |  2 ++
 src/optim/optimizers.ts | 65 +++++++++++++++++++++++++++++++++++++++++
 test/optimizers.test.ts | 15 ++++++++++
 5 files changed, 102 insertions(+)
 create mode 100644 src/optim/base.ts
 create mode 100644 src/optim/index.ts
 create mode 100644 src/optim/optimizers.ts
 create mode 100644 test/optimizers.test.ts

diff --git a/src/index.ts b/src/index.ts
index e4302111..89d9a6c5 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -4,4 +4,5 @@ export * from './operations/ops.gen';
 export * from './operations/functional';
 export * from './creation/index';
 export * as nn from './nn/index';
+export * as optim from './optim/index';
 export { Tensor };
diff --git a/src/optim/base.ts b/src/optim/base.ts
new file mode 100644
index 00000000..5295ecc1
--- /dev/null
+++ b/src/optim/base.ts
@@ -0,0 +1,19 @@
+import { Parameter } from "../nn/module";
+
+export abstract class Optimizer {
+  params: Parameter[];
+  defaults: { [key: string]: any };
+
+  constructor(params: Parameter[], defaults: { [key: string]: any }) {
+    this.params = params;
+    this.defaults = defaults;
+  }
+
+  public zero_grad(): void {
+    for (const param of this.params) {
+      param.grad = null;
+    }
+  }
+
+  abstract step(): void;
+}
diff --git a/src/optim/index.ts b/src/optim/index.ts
new file mode 100644
index 00000000..6d4aff54
--- /dev/null
+++ b/src/optim/index.ts
@@ -0,0 +1,2 @@
+export * from './base';
+export * from './optimizers';
\ No newline at end of file
diff --git a/src/optim/optimizers.ts b/src/optim/optimizers.ts
new file mode 100644
index 00000000..cfade5c6
--- /dev/null
+++ b/src/optim/optimizers.ts
@@ -0,0 +1,65 @@
+import { Optimizer } from "./base";
+import { Parameter } from "../nn/module";
+import { Tensor } from "../tensor";
+import { zeros } from "../creation";
+
+export class SGD extends Optimizer {
+  private state: Map = new Map();
+  private lr: number;
+  private momentum: number;
+  private dampening: number;
+  private weight_decay: number;
+  private nesterov: boolean;
+  private maximize: boolean;
+  
+  constructor(
+    params: Parameter[],
+    lr: number = 0.001,
+    momentum: number = 0.0,
+    dampening: number = 0.0,
+    weight_decay: number = 0.0,
+    nesterov: boolean = false,
+    maximize: boolean = false,
+  ) {
+    super(params, {});
+    this.lr = lr;
+    this.momentum = momentum;
+    this.dampening = dampening;
+    this.weight_decay = weight_decay;
+    this.nesterov = nesterov;
+    this.maximize = maximize;
+  }
+
+  step(): void {
+    for (const param of this.params) {
+      let g = this.maximize ? param.grad.mul(-1) : param.grad;
+      if (this.weight_decay != 0) {
+        g = g.add(param.mul(this.weight_decay));
+      }
+
+      if (this.momentum != 0) {
+        let dampening = this.dampening;
+        if(!this.state.has(param)) {
+          this.state.set(param, { velocity: zeros(param.shape) });
+          dampening = 0;
+        }
+
+        let buf = this.state.get(param)!.velocity;
+        buf = buf.mul(this.momentum)
+        buf = buf.add(g.mul(dampening));
+
+        if (this.nesterov) {
+          g = g.add(buf.mul(this.momentum));
+        } else {
+          g = g.add(buf);
+        }
+
+        this.state.set(param, { velocity: buf });
+      }
+
+      // potentially unsafe?
+      const newParam = param.sub(g.mul(this.lr));
+      param.data = newParam.data;
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/optimizers.test.ts b/test/optimizers.test.ts
new file mode 100644
index 00000000..dc4a8a75
--- /dev/null
+++ b/test/optimizers.test.ts
@@ -0,0 +1,15 @@
+import * as torch from "../src/index";
+
+describe("Optimizers", () => {
+  describe("SGD", () => {
+    test("should update parameters", () => {
+      const x = new torch.Tensor([1.0], { requires_grad: true });
+      const y = x.mul(new torch.Tensor(2.0));
+      y.backward();
+
+      const sgd = new torch.optim.SGD([x], 0.01);
+      sgd.step();
+      expect(sgd.params[0].data[0]).toBeCloseTo(0.98);
+    });
+  });
+});
\ No newline at end of file

From b7999ab40bee69aaea3aa036e9a8c6c7d111fde7 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 12 Oct 2025 23:39:04 +0800
Subject: [PATCH 017/128] feat: detach

---
 src/tensor.ts | 91 +++++++++++++++++++++++++++++----------------------
 1 file changed, 52 insertions(+), 39 deletions(-)

diff --git a/src/tensor.ts b/src/tensor.ts
index 0e022958..c85b4d8d 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -94,6 +94,58 @@ export class Tensor {
     return operation.forward(this, ...args);
   }
 
+  item(): number {
+    if (this.data.length !== 1) {
+      throw new Error('Tensor.item() is only valid for scalars');
+    }
+    return this.data[0];
+  }
+
+  detach(): Tensor {
+    return new Tensor(this.data, { requires_grad: false }, { shape: this.shape });
+  }
+
+  detach_(): void {
+    this.requires_grad = false;
+    this.grad = null;
+    this.operation = null;
+  }
+
+  backward(grad?: Tensor | null): void {
+    if (!this.requires_grad) {
+      // If this tensor does not require gradients, stop propagation.
+      // TODO: check pytorch behaviour
+      return;
+    }
+
+    if (!grad) {
+      if (this.data.length !== 1) {
+        throw new Error('Gradient is required for non-scalar tensors');
+      }
+
+      grad = new Tensor(1);
+    }
+
+    if (!this.grad) {
+      this.grad = new Tensor(Array(this.data.length).fill(0));
+    }
+
+    // Add grad to this.grad
+    for (let i = 0; i < grad.data.length; i++) {
+      this.grad.data[_get_original_index(this.shape, grad.shape, i)] += grad.data[i];
+    }
+
+    if (this.operation) {
+      // Propagate only the incoming local gradient, not the accumulated one,
+      // to avoid double-counting when a tensor receives gradients from
+      // multiple downstream paths.
+      // this.operation.backward(grad);
+      this.operation.backward(this.grad);
+    }
+  }
+
+  // operations
+
   add(other: Tensor | number): Tensor {
     return this._executeBinaryOp('add', other);
   }
@@ -173,43 +225,4 @@ export class Tensor {
   log(): Tensor {
     return this._executeUnaryOp('log');
   }
-
-  item(): number {
-    if (this.data.length !== 1) {
-      throw new Error('Tensor.item() is only valid for scalars');
-    }
-    return this.data[0];
-  }
-
-  backward(grad?: Tensor | null): void {
-    if (!this.requires_grad) {
-      // If this tensor does not require gradients, stop propagation.
-      return;
-    }
-
-    if (!grad) {
-      if (this.data.length !== 1) {
-        throw new Error('Gradient is required for non-scalar tensors');
-      }
-
-      grad = new Tensor(1);
-    }
-
-    if (!this.grad) {
-      this.grad = new Tensor(Array(this.data.length).fill(0));
-    }
-
-    // Add grad to this.grad
-    for (let i = 0; i < grad.data.length; i++) {
-      this.grad.data[_get_original_index(this.shape, grad.shape, i)] += grad.data[i];
-    }
-
-    if (this.operation) {
-      // Propagate only the incoming local gradient, not the accumulated one,
-      // to avoid double-counting when a tensor receives gradients from
-      // multiple downstream paths.
-      // this.operation.backward(grad);
-      this.operation.backward(this.grad);
-    }
-  }
 }

From 967b39f27a930bfbdefc85a823d887b0131c8d99 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 00:21:02 +0800
Subject: [PATCH 018/128] feat: more operations

---
 src/nn/module.ts             |   1 -
 src/operations/functional.ts |  37 +-
 src/operations/ops.gen.ts    | 736 ++++++++++++++++++++++-------------
 src/operations/ops.ts.j2     |  93 +++--
 src/tensor.ts                |  80 ++--
 5 files changed, 622 insertions(+), 325 deletions(-)

diff --git a/src/nn/module.ts b/src/nn/module.ts
index 2454f19d..6b9eea64 100644
--- a/src/nn/module.ts
+++ b/src/nn/module.ts
@@ -68,7 +68,6 @@ export class Linear extends Module {
     const k = Math.sqrt(1 / in_features);
 
     this.weight = new Parameter(rand([out_features, in_features]).mul(2 * k).sub(k));
-    console.log("weight", this.weight.shape);
     this.bias = new Parameter(rand([out_features]).mul(2 * k).sub(k));
 
     this.register("weight", this.weight);
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 74dac8d7..1a5ee8fc 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -34,23 +34,46 @@ function generate_binary_function(opname: string) {
   };
 }
 
+// binary pointwise
+
 export const add = generate_binary_function('add');
 export const sub = generate_binary_function('sub');
 export const mul = generate_binary_function('mul');
 export const div = generate_binary_function('div');
+export const pow = generate_binary_function('pow');
+export const fmod = generate_binary_function('fmod');
+
+// unary pointwise
+
+export const log = generate_unary_function('log');
+export const sqrt = generate_unary_function('sqrt');
+export const exp = generate_unary_function('exp');
+export const abs = generate_unary_function('abs');
+export const sign = generate_unary_function('sign');
+export const neg = generate_unary_function('neg');
+export const reciprocal = generate_unary_function('reciprocal');
+
+// trigonometric
+
+export const sin = generate_unary_function('sin');
+export const cos = generate_unary_function('cos');
+export const tan = generate_unary_function('tan');
+
+// reduction
+
 export const sum = generate_unary_function('sum');
 export const mean = generate_unary_function('mean');
-export const pow = generate_unary_function('pow');
-export const log = generate_unary_function('log');
+
+// linalg
+
 export const transpose = generate_function('transpose');
 export const matmul = generate_binary_function('matmul');
-export const fmod = generate_binary_function('fmod');
+
+// comparison
+
 export const lt = generate_binary_function('lt');
 export const gt = generate_binary_function('gt');
 export const le = generate_binary_function('le');
 export const ge = generate_binary_function('ge');
 export const eq = generate_binary_function('eq');
-export const ne = generate_binary_function('ne');
-export const sqrt = generate_unary_function('sqrt');
-export const sign = generate_unary_function('sign');
-export const abs = generate_unary_function('abs');
\ No newline at end of file
+export const ne = generate_binary_function('ne');
\ No newline at end of file
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index b41962b7..04778b19 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -11,55 +11,7 @@ import { Operation, BinaryOperation, UnaryOperation } from './base';
 import * as functional from './functional';
 import { registerOperation } from './registry';
 
-function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  return new Tensor(
-    a.data.reduce((acc, val) => acc + val, 0),
-    { requires_grad: a.requires_grad },
-    { operation: operation }
-  );
-}
-
-// class generated from unary_op_class("Sum", "sum", backward_operations)
-export class Sum extends UnaryOperation {
-  private cache: [Tensor];
-  public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sum_tensor(a, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a] = this.cache;
-
-    // backward_operations:
-    const result = new Tensor(Array(a.data.length).fill(dz.data[0]));
-    a.backward(result);
-  }
-}
-registerOperation('sum', Sum);
-
-function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  return new Tensor(
-    a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
-    { requires_grad: a.requires_grad },
-    { operation: operation }
-  );
-}
-
-// class generated from unary_op_class("Mean", "mean", backward_operations)
-export class Mean extends UnaryOperation {
-  private cache: [Tensor];
-  public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _mean_tensor(a, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a] = this.cache;
-
-    // backward_operations:
-    const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));
-    a.backward(result);
-  }
-}
-registerOperation('mean', Mean);
+// binary pointwise
 
 // function generated from binary_op_base("add", "a[a_index] + b[b_index]")
 function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
@@ -216,65 +168,495 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     { operation: operation, shape: broadcast_shape }
   );
 }
-// class generated from binary_op_class("Div", "div", backward_operations)
-export class Div extends BinaryOperation {
-  private cache: [Tensor, Tensor];
-  public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _div_tensor(a, b, this);
+// class generated from binary_op_class("Div", "div", backward_operations)
+export class Div extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _div_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.div(b));
+    b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));
+  }
+}
+registerOperation('div', Div);
+
+// function generated from binary_op_base("pow", "a[a_index] ** b[b_index]")
+function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] ** b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Pow", "pow", backward_operations)
+export class Pow extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _pow_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));
+    b.backward(dz.mul(a.pow(b)).mul(a.log()));
+  }
+}
+registerOperation('pow', Pow);
+
+// function generated from binary_op_base("fmod", "a[a_index] % b[b_index]")
+function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+  const kernel = gpu.createKernel(
+    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+      return a[a_index] % b[b_index];
+    },
+    {
+      constants: {
+        shape_length: broadcast_shape.length
+      },
+      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Fmod", "fmod", backward_operations)
+export class Fmod extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    this.cache = [a, b];
+    return _fmod_tensor(a, b, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz);
+  }
+}
+registerOperation('fmod', Fmod);
+
+// unary pointwise
+
+// function generated from unary_op_base("log", "Math.log(a[this.thread.x])")
+function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.log(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Log", "log", backward_operations)
+export class Log extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _log_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(new Tensor(1).div(a));
+  }
+}
+registerOperation('log', Log);
+
+// function generated from unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])")
+function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.sqrt(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Sqrt", "sqrt", backward_operations)
+export class Sqrt extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sqrt_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(new Tensor(1).div(a.sqrt()).div(2));
+  }
+}
+registerOperation('sqrt', Sqrt);
+
+// function generated from unary_op_base("exp", "Math.exp(a[this.thread.x])")
+function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.exp(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Exp", "exp", backward_operations)
+export class Exp extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _exp_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.exp()));
+  }
+}
+registerOperation('exp', Exp);
+
+// function generated from unary_op_base("abs", "Math.abs(a[this.thread.x])")
+function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.abs(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Abs", "abs", backward_operations)
+export class Abs extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _abs_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(functional.sign(a)));
+  }
+}
+registerOperation('abs', Abs);
+
+// function generated from unary_op_base("sign", "Math.sign(a[this.thread.x])")
+function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.sign(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Sign", "sign", backward_operations)
+export class Sign extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sign_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('sign', Sign);
+
+// function generated from unary_op_base("neg", "Math.sign(a[this.thread.x]) * a[this.thread.x]")
+function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.sign(a[this.thread.x]) * a[this.thread.x];
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Neg", "neg", backward_operations)
+export class Neg extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _neg_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(new Tensor(-1)));
+  }
+}
+registerOperation('neg', Neg);
+
+// function generated from unary_op_base("reciprocal", "1 / a[this.thread.x]")
+function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return 1 / a[this.thread.x];
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Reciprocal", "reciprocal", backward_operations)
+export class Reciprocal extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _reciprocal_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.pow(-2)));
+  }
+}
+registerOperation('reciprocal', Reciprocal);
+
+// trigonometric
+
+// function generated from unary_op_base("sin", "Math.sin(a[this.thread.x])")
+function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.sin(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Sin", "sin", backward_operations)
+export class Sin extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sin_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.cos()));
+  }
+}
+registerOperation('sin', Sin);
+
+// function generated from unary_op_base("cos", "Math.cos(a[this.thread.x])")
+function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.cos(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Cos", "cos", backward_operations)
+export class Cos extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _cos_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.sin().neg()));
+  }
+}
+registerOperation('cos', Cos);
+
+// function generated from unary_op_base("tan", "Math.tan(a[this.thread.x])")
+function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = gpu.createKernel(
+    function (a: number[]) {
+      return Math.tan(a[this.thread.x]);
+    },
+    {
+      output: [a.shape.reduce((acc, val) => acc * val, 1)]
+    }
+  );
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Tan", "tan", backward_operations)
+export class Tan extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _tan_tensor(a, this);
   }
   public backward(dz: Tensor): void {
-    const [a, b] = this.cache;
+    const [a] = this.cache;
 
     // backward_operations:
-    a.backward(dz.div(b));
-    b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));
+    a.backward(dz.mul(a.cos().pow(-2)));
   }
 }
-registerOperation('div', Div);
+registerOperation('tan', Tan);
 
-// function generated from binary_op_base("pow", "a[a_index] ** b[b_index]")
-function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+// reduction
 
-      return a[a_index] ** b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
+function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  return new Tensor(
+    a.data.reduce((acc, val) => acc + val, 0),
+    { requires_grad: a.requires_grad },
+    { operation: operation }
   );
+}
+
+// class generated from unary_op_class("Sum", "sum", backward_operations)
+export class Sum extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _sum_tensor(a, this);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    const result = new Tensor(Array(a.data.length).fill(dz.data[0]));
+    a.backward(result);
+  }
+}
+registerOperation('sum', Sum);
 
+function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
+    a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
+    { requires_grad: a.requires_grad },
+    { operation: operation }
   );
 }
-// class generated from binary_op_class("Pow", "pow", backward_operations)
-export class Pow extends BinaryOperation {
-  private cache: [Tensor, Tensor];
-  public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _pow_tensor(a, b, this);
+
+// class generated from unary_op_class("Mean", "mean", backward_operations)
+export class Mean extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    this.cache = [a];
+    return _mean_tensor(a, this);
   }
   public backward(dz: Tensor): void {
-    const [a, b] = this.cache;
+    const [a] = this.cache;
 
     // backward_operations:
-    a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));
-    b.backward(dz.mul(a.pow(b)).mul(a.log()));
+    const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));
+    a.backward(result);
   }
 }
-registerOperation('pow', Pow);
+registerOperation('mean', Mean);
+
+// linalg
 
 function _transpose_tensor(
   a: Tensor,
@@ -430,47 +812,7 @@ export class Matmul extends BinaryOperation {
 }
 registerOperation('matmul', Matmul);
 
-// function generated from binary_op_base("fmod", "a[a_index] % b[b_index]")
-function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
-  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] % b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: broadcast_shape }
-  );
-}
-// class generated from binary_op_class("Fmod", "fmod", backward_operations)
-export class Fmod extends BinaryOperation {
-  private cache: [Tensor, Tensor];
-  public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _fmod_tensor(a, b, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a, b] = this.cache;
-
-    // backward_operations:
-    a.backward(dz);
-  }
-}
-registerOperation('fmod', Fmod);
+// comparison
 
 // function generated from binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0")
 function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
@@ -722,136 +1064,4 @@ export class Ne extends BinaryOperation {
     
   }
 }
-registerOperation('ne', Ne);
-
-// function generated from unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])")
-function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.sqrt(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: a.shape }
-  );
-}
-// class generated from unary_op_class("Sqrt", "sqrt", backward_operations)
-export class Sqrt extends UnaryOperation {
-  private cache: [Tensor];
-  public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sqrt_tensor(a, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a] = this.cache;
-
-    // backward_operations:
-    a.backward(new Tensor(1).div(a.sqrt()).div(2));
-  }
-}
-registerOperation('sqrt', Sqrt);
-
-// function generated from unary_op_base("sign", "Math.sign(a[this.thread.x])")
-function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.sign(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: a.shape }
-  );
-}
-// class generated from unary_op_class("Sign", "sign", backward_operations)
-export class Sign extends UnaryOperation {
-  private cache: [Tensor];
-  public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sign_tensor(a, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a] = this.cache;
-
-    // backward_operations:
-    
-  }
-}
-registerOperation('sign', Sign);
-
-// function generated from unary_op_base("abs", "Math.abs(a[this.thread.x])")
-function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.abs(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: a.shape }
-  );
-}
-// class generated from unary_op_class("Abs", "abs", backward_operations)
-export class Abs extends UnaryOperation {
-  private cache: [Tensor];
-  public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _abs_tensor(a, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a] = this.cache;
-
-    // backward_operations:
-    a.backward(dz.mul(functional.sign(a)));
-  }
-}
-registerOperation('abs', Abs);
-
-// function generated from unary_op_base("log", "Math.log(a[this.thread.x])")
-function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.log(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
-
-  return new Tensor(
-    kernel(a.data) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: a.shape }
-  );
-}
-// class generated from unary_op_class("Log", "log", backward_operations)
-export class Log extends UnaryOperation {
-  private cache: [Tensor];
-  public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _log_tensor(a, this);
-  }
-  public backward(dz: Tensor): void {
-    const [a] = this.cache;
-
-    // backward_operations:
-    a.backward(new Tensor(1).div(a));
-  }
-}
-registerOperation('log', Log);
+registerOperation('ne', Ne);
\ No newline at end of file
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index 074cd72f..675aae57 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -11,6 +11,65 @@ import { Operation, BinaryOperation, UnaryOperation } from './base';
 import * as functional from './functional';
 import { registerOperation } from './registry';
 
+// binary pointwise
+
+{{ binary_op_base("add", "a[a_index] + b[b_index]") }}
+{{ binary_op_class("Add", "add", ["a.backward(dz);", "b.backward(dz);"]) }}
+
+{{ binary_op_base("sub", "a[a_index] - b[b_index]") }}
+{{ binary_op_class("Sub", "sub", ["a.backward(dz);", "b.backward(dz.mul(new Tensor(-1)));"]) }}
+
+{{ binary_op_base("mul", "a[a_index] * b[b_index]") }}
+{{ binary_op_class("Mul", "mul", ["a.backward(dz.mul(b));", "b.backward(dz.mul(a));"]) }}
+
+{{ binary_op_base("div", "a[a_index] / b[b_index]") }}
+{{ binary_op_class("Div", "div", ["a.backward(dz.div(b));", "b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));"]) }}
+
+{{ binary_op_base("pow", "a[a_index] ** b[b_index]") }}
+{{ binary_op_class("Pow", "pow", [
+  "a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));",
+  "b.backward(dz.mul(a.pow(b)).mul(a.log()));"
+])}}
+
+{{ binary_op_base("fmod", "a[a_index] % b[b_index]") }}
+{{ binary_op_class("Fmod", "fmod", ["a.backward(dz);"]) }}
+
+// unary pointwise
+
+{{ unary_op_base("log", "Math.log(a[this.thread.x])") }}
+{{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }}
+
+{{ unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])") }}
+{{ unary_op_class("Sqrt", "sqrt", ["a.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }}
+
+{{ unary_op_base("exp", "Math.exp(a[this.thread.x])") }}
+{{ unary_op_class("Exp", "exp", ["a.backward(dz.mul(a.exp()));"]) }}
+
+{{ unary_op_base("abs", "Math.abs(a[this.thread.x])") }}
+{{ unary_op_class("Abs", "abs", ["a.backward(dz.mul(functional.sign(a)));"]) }}
+
+{{ unary_op_base("sign", "Math.sign(a[this.thread.x])") }}
+{{ unary_op_class("Sign", "sign", []) }}
+
+{{ unary_op_base("neg", "Math.sign(a[this.thread.x]) * a[this.thread.x]") }}
+{{ unary_op_class("Neg", "neg", ["a.backward(dz.mul(new Tensor(-1)));"]) }}
+
+{{ unary_op_base("reciprocal", "1 / a[this.thread.x]") }}
+{{ unary_op_class("Reciprocal", "reciprocal", ["a.backward(dz.mul(a.pow(-2)));"]) }}
+
+// trigonometric
+
+{{ unary_op_base("sin", "Math.sin(a[this.thread.x])") }}
+{{ unary_op_class("Sin", "sin", ["a.backward(dz.mul(a.cos()));"]) }}
+
+{{ unary_op_base("cos", "Math.cos(a[this.thread.x])") }}
+{{ unary_op_class("Cos", "cos", ["a.backward(dz.mul(a.sin().neg()));"]) }}
+
+{{ unary_op_base("tan", "Math.tan(a[this.thread.x])") }}
+{{ unary_op_class("Tan", "tan", ["a.backward(dz.mul(a.cos().pow(-2)));"]) }}
+
+// reduction
+
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
     a.data.reduce((acc, val) => acc + val, 0),
@@ -31,23 +90,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 
 {{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));", "a.backward(result);"]) }}
 
-{{ binary_op_base("add", "a[a_index] + b[b_index]") }}
-{{ binary_op_class("Add", "add", ["a.backward(dz);", "b.backward(dz);"]) }}
-
-{{ binary_op_base("sub", "a[a_index] - b[b_index]") }}
-{{ binary_op_class("Sub", "sub", ["a.backward(dz);", "b.backward(dz.mul(new Tensor(-1)));"]) }}
-
-{{ binary_op_base("mul", "a[a_index] * b[b_index]") }}
-{{ binary_op_class("Mul", "mul", ["a.backward(dz.mul(b));", "b.backward(dz.mul(a));"]) }}
-
-{{ binary_op_base("div", "a[a_index] / b[b_index]") }}
-{{ binary_op_class("Div", "div", ["a.backward(dz.div(b));", "b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));"]) }}
-
-{{ binary_op_base("pow", "a[a_index] ** b[b_index]") }}
-{{ binary_op_class("Pow", "pow", [
-  "a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));",
-  "b.backward(dz.mul(a.pow(b)).mul(a.log()));"
-])}}
+// linalg
 
 function _transpose_tensor(
   a: Tensor,
@@ -189,8 +232,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
 {{ binary_op_class("Matmul", "matmul", []) }}
 
-{{ binary_op_base("fmod", "a[a_index] % b[b_index]") }}
-{{ binary_op_class("Fmod", "fmod", ["a.backward(dz);"]) }}
+// comparison
 
 {{ binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0") }}
 {{ binary_op_class("Lt", "lt", []) }}
@@ -209,16 +251,3 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 
 {{ binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0") }}
 {{ binary_op_class("Ne", "ne", []) }}
-
-{{ unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])") }}
-{{ unary_op_class("Sqrt", "sqrt", ["a.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }}
-
-{{ unary_op_base("sign", "Math.sign(a[this.thread.x])") }}
-{{ unary_op_class("Sign", "sign", []) }}
-
-{{ unary_op_base("abs", "Math.abs(a[this.thread.x])") }}
-{{ unary_op_class("Abs", "abs", ["a.backward(dz.mul(functional.sign(a)));"]) }}
-
-{{ unary_op_base("log", "Math.log(a[this.thread.x])") }}
-{{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }}
-{# {{ unary_op_base("neg", "-a[this.thread.x]") }} #}
diff --git a/src/tensor.ts b/src/tensor.ts
index c85b4d8d..c24cbb7b 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -146,6 +146,8 @@ export class Tensor {
 
   // operations
 
+  // binary pointwise
+
   add(other: Tensor | number): Tensor {
     return this._executeBinaryOp('add', other);
   }
@@ -162,6 +164,60 @@ export class Tensor {
     return this._executeBinaryOp('div', other);
   }
 
+  pow(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('pow', other);
+  }
+
+  fmod(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('fmod', other);
+  }
+
+  // unary pointwise
+
+  log(): Tensor {
+    return this._executeUnaryOp('log');
+  }
+
+  sqrt(): Tensor {
+    return this._executeUnaryOp('sqrt');
+  }
+
+  exp(): Tensor {
+    return this._executeUnaryOp('exp');
+  }
+
+  abs(): Tensor {
+    return this._executeUnaryOp('abs');
+  }
+
+  sign(): Tensor {
+    return this._executeUnaryOp('sign');
+  }
+
+  neg(): Tensor {
+    return this._executeUnaryOp('neg');
+  }
+
+  reciprocal(): Tensor {
+    return this._executeUnaryOp('reciprocal');
+  }
+  
+  // trigonometric
+
+  sin(): Tensor {
+    return this._executeUnaryOp('sin');
+  }
+  
+  cos(): Tensor {
+    return this._executeUnaryOp('cos');
+  }
+  
+  tan(): Tensor {
+    return this._executeUnaryOp('tan');
+  }
+
+  // reduction
+
   sum(): Tensor {
     return this._executeUnaryOp('sum');
   }
@@ -170,9 +226,7 @@ export class Tensor {
     return this._executeUnaryOp('mean');
   }
 
-  pow(other: Tensor | number): Tensor {
-    return this._executeBinaryOp('pow', other);
-  }
+  // linalg
 
   transpose(dim0: number, dim1: number): Tensor {
     return this._executeOpRaw('transpose', dim0, dim1);
@@ -182,9 +236,7 @@ export class Tensor {
     return this._executeBinaryOp('matmul', other);
   }
 
-  fmod(other: Tensor | number): Tensor {
-    return this._executeBinaryOp('fmod', other);
-  }
+  // comparison
 
   lt(other: Tensor | number): Tensor {
     return this._executeBinaryOp('lt', other);
@@ -209,20 +261,4 @@ export class Tensor {
   ne(other: Tensor | number): Tensor {
     return this._executeBinaryOp('ne', other);
   }
-
-  sqrt(): Tensor {
-    return this._executeUnaryOp('sqrt');
-  }
-
-  sign(): Tensor {
-    return this._executeUnaryOp('sign');
-  }
-
-  abs(): Tensor {
-    return this._executeUnaryOp('abs');
-  }
-
-  log(): Tensor {
-    return this._executeUnaryOp('log');
-  }
 }

From 3f31912d76c8778d0ceab061e1c18d07c6d6dbb1 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 01:24:58 +0800
Subject: [PATCH 019/128] feat: caching operations and kernels

---
 scripts/macros.ts.j2       |  66 ++--
 src/nn/ops.gen.ts          |  26 +-
 src/operations/ops.gen.ts  | 758 ++++++++++++++++++++++---------------
 src/operations/registry.ts |  12 +-
 src/tensor.ts              |  10 +-
 5 files changed, 521 insertions(+), 351 deletions(-)

diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2
index 5038d4c8..2cc0306b 100644
--- a/scripts/macros.ts.j2
+++ b/scripts/macros.ts.j2
@@ -1,26 +1,30 @@
 {% macro binary_op_base(name, operation) -%}
-// function generated from binary_op_base("{{ name }}", "{{ operation }}")
+const _{{ name }}_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return {{ operation }};
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return {{ operation }};
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _{{ name }}_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -29,15 +33,19 @@ function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null =
 
 {% macro unary_op_base(name, operation) -%}
 // function generated from unary_op_base("{{ name }}", "{{ operation }}")
+
+const _{{ name }}_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return {{ operation }};
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return {{ operation }};
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _{{ name }}_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -52,8 +60,10 @@ function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tens
 export class {{ classname }} extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _{{ opname }}_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -70,8 +80,10 @@ registerOperation('{{ opname }}', {{ classname }});
 export class {{ classname }} extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _{{ opname }}_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _{{ opname }}_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts
index 34bc25ac..afac074d 100644
--- a/src/nn/ops.gen.ts
+++ b/src/nn/ops.gen.ts
@@ -11,15 +11,19 @@ import { Operation, BinaryOperation, UnaryOperation } from '../operations/base';
 import { registerOperation } from '../operations/registry';
 
 // function generated from unary_op_base("relu", "Math.max(a[this.thread.x], 0)")
+
+const _relu_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.max(a[this.thread.x], 0);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.max(a[this.thread.x], 0);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _relu_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -31,8 +35,10 @@ function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Relu extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _relu_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _relu_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 04778b19..fd5eaa49 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -13,28 +13,32 @@ import { registerOperation } from './registry';
 
 // binary pointwise
 
-// function generated from binary_op_base("add", "a[a_index] + b[b_index]")
+const _add_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return a[a_index] + b[b_index];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] + b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _add_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -43,8 +47,10 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Add extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _add_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _add_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -56,28 +62,32 @@ export class Add extends BinaryOperation {
 }
 registerOperation('add', Add);
 
-// function generated from binary_op_base("sub", "a[a_index] - b[b_index]")
+const _sub_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return a[a_index] - b[b_index];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] - b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _sub_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -86,8 +96,10 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Sub extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _sub_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _sub_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -99,28 +111,32 @@ export class Sub extends BinaryOperation {
 }
 registerOperation('sub', Sub);
 
-// function generated from binary_op_base("mul", "a[a_index] * b[b_index]")
+const _mul_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return a[a_index] * b[b_index];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] * b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _mul_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -129,8 +145,10 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Mul extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _mul_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _mul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -142,28 +160,32 @@ export class Mul extends BinaryOperation {
 }
 registerOperation('mul', Mul);
 
-// function generated from binary_op_base("div", "a[a_index] / b[b_index]")
+const _div_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return a[a_index] / b[b_index];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] / b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _div_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -172,8 +194,10 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Div extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _div_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _div_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -185,28 +209,32 @@ export class Div extends BinaryOperation {
 }
 registerOperation('div', Div);
 
-// function generated from binary_op_base("pow", "a[a_index] ** b[b_index]")
+const _pow_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return a[a_index] ** b[b_index];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] ** b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _pow_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -215,8 +243,10 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Pow extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _pow_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _pow_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -228,28 +258,32 @@ export class Pow extends BinaryOperation {
 }
 registerOperation('pow', Pow);
 
-// function generated from binary_op_base("fmod", "a[a_index] % b[b_index]")
+const _fmod_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return a[a_index] % b[b_index];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return a[a_index] % b[b_index];
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _fmod_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -258,8 +292,10 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Fmod extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _fmod_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _fmod_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -273,15 +309,19 @@ registerOperation('fmod', Fmod);
 // unary pointwise
 
 // function generated from unary_op_base("log", "Math.log(a[this.thread.x])")
+
+const _log_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.log(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.log(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _log_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -293,8 +333,10 @@ function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Log extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _log_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _log_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -306,15 +348,19 @@ export class Log extends UnaryOperation {
 registerOperation('log', Log);
 
 // function generated from unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])")
+
+const _sqrt_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.sqrt(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.sqrt(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _sqrt_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -326,8 +372,10 @@ function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sqrt extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sqrt_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _sqrt_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -339,15 +387,19 @@ export class Sqrt extends UnaryOperation {
 registerOperation('sqrt', Sqrt);
 
 // function generated from unary_op_base("exp", "Math.exp(a[this.thread.x])")
+
+const _exp_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.exp(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.exp(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _exp_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -359,8 +411,10 @@ function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Exp extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _exp_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _exp_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -372,15 +426,19 @@ export class Exp extends UnaryOperation {
 registerOperation('exp', Exp);
 
 // function generated from unary_op_base("abs", "Math.abs(a[this.thread.x])")
+
+const _abs_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.abs(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.abs(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _abs_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -392,8 +450,10 @@ function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Abs extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _abs_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _abs_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -405,15 +465,19 @@ export class Abs extends UnaryOperation {
 registerOperation('abs', Abs);
 
 // function generated from unary_op_base("sign", "Math.sign(a[this.thread.x])")
+
+const _sign_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.sign(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.sign(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _sign_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -425,8 +489,10 @@ function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sign extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sign_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _sign_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -438,15 +504,19 @@ export class Sign extends UnaryOperation {
 registerOperation('sign', Sign);
 
 // function generated from unary_op_base("neg", "Math.sign(a[this.thread.x]) * a[this.thread.x]")
+
+const _neg_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.sign(a[this.thread.x]) * a[this.thread.x];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.sign(a[this.thread.x]) * a[this.thread.x];
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _neg_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -458,8 +528,10 @@ function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Neg extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _neg_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _neg_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -471,15 +543,19 @@ export class Neg extends UnaryOperation {
 registerOperation('neg', Neg);
 
 // function generated from unary_op_base("reciprocal", "1 / a[this.thread.x]")
+
+const _reciprocal_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return 1 / a[this.thread.x];
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return 1 / a[this.thread.x];
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _reciprocal_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -491,8 +567,10 @@ function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tens
 export class Reciprocal extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _reciprocal_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _reciprocal_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -506,15 +584,19 @@ registerOperation('reciprocal', Reciprocal);
 // trigonometric
 
 // function generated from unary_op_base("sin", "Math.sin(a[this.thread.x])")
+
+const _sin_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.sin(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.sin(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _sin_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -526,8 +608,10 @@ function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sin extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sin_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _sin_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -539,15 +623,19 @@ export class Sin extends UnaryOperation {
 registerOperation('sin', Sin);
 
 // function generated from unary_op_base("cos", "Math.cos(a[this.thread.x])")
+
+const _cos_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.cos(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.cos(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _cos_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -559,8 +647,10 @@ function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Cos extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _cos_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _cos_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -572,15 +662,19 @@ export class Cos extends UnaryOperation {
 registerOperation('cos', Cos);
 
 // function generated from unary_op_base("tan", "Math.tan(a[this.thread.x])")
+
+const _tan_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return Math.tan(a[this.thread.x]);
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[]) {
-      return Math.tan(a[this.thread.x]);
-    },
-    {
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _tan_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   return new Tensor(
     kernel(a.data) as number[],
@@ -592,8 +686,10 @@ function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Tan extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _tan_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _tan_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -618,8 +714,10 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sum extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _sum_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _sum_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -643,8 +741,10 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Mean extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    this.cache = [a];
-    return _mean_tensor(a, this);
+    if(a.requires_grad) {
+      this.cache = [a];
+    }
+    return _mean_tensor(a, a.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a] = this.cache;
@@ -800,8 +900,10 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 export class Matmul extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _matmul_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -814,28 +916,32 @@ registerOperation('matmul', Matmul);
 
 // comparison
 
-// function generated from binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0")
+const _lt_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return (a[a_index] < b[b_index]) ? 1 : 0;
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return (a[a_index] < b[b_index]) ? 1 : 0;
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _lt_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -844,8 +950,10 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Lt extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _lt_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _lt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -856,28 +964,32 @@ export class Lt extends BinaryOperation {
 }
 registerOperation('lt', Lt);
 
-// function generated from binary_op_base("gt", "(a[a_index] > b[b_index]) ? 1 : 0")
+const _gt_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return (a[a_index] > b[b_index]) ? 1 : 0;
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return (a[a_index] > b[b_index]) ? 1 : 0;
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _gt_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -886,8 +998,10 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Gt extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _gt_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _gt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -898,28 +1012,32 @@ export class Gt extends BinaryOperation {
 }
 registerOperation('gt', Gt);
 
-// function generated from binary_op_base("le", "(a[a_index] <= b[b_index]) ? 1 : 0")
+const _le_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return (a[a_index] <= b[b_index]) ? 1 : 0;
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return (a[a_index] <= b[b_index]) ? 1 : 0;
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _le_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -928,8 +1046,10 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Le extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _le_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _le_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -940,28 +1060,32 @@ export class Le extends BinaryOperation {
 }
 registerOperation('le', Le);
 
-// function generated from binary_op_base("ge", "(a[a_index] >= b[b_index]) ? 1 : 0")
+const _ge_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return (a[a_index] >= b[b_index]) ? 1 : 0;
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return (a[a_index] >= b[b_index]) ? 1 : 0;
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _ge_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -970,8 +1094,10 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Ge extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _ge_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _ge_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -982,28 +1108,32 @@ export class Ge extends BinaryOperation {
 }
 registerOperation('ge', Ge);
 
-// function generated from binary_op_base("eq", "(a[a_index] == b[b_index]) ? 1 : 0")
+const _eq_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return (a[a_index] == b[b_index]) ? 1 : 0;
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return (a[a_index] == b[b_index]) ? 1 : 0;
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _eq_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1012,8 +1142,10 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Eq extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _eq_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _eq_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
@@ -1024,28 +1156,32 @@ export class Eq extends BinaryOperation {
 }
 registerOperation('eq', Eq);
 
-// function generated from binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0")
+const _ne_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return (a[a_index] != b[b_index]) ? 1 : 0;
+  },
+  {
+    dynamicOutput: true
+  }
+);
+
 function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
   const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-      const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-      const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-      return (a[a_index] != b[b_index]) ? 1 : 0;
-    },
-    {
-      constants: {
-        shape_length: broadcast_shape.length
-      },
-      output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
 
+  const kernel = _ne_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1054,8 +1190,10 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Ne extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    this.cache = [a, b];
-    return _ne_tensor(a, b, this);
+    if(a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _ne_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
   }
   public backward(dz: Tensor): void {
     const [a, b] = this.cache;
diff --git a/src/operations/registry.ts b/src/operations/registry.ts
index a631ad57..99f39445 100644
--- a/src/operations/registry.ts
+++ b/src/operations/registry.ts
@@ -1,7 +1,8 @@
-import { OperationConstructor } from './base';
+import { Operation, OperationConstructor } from './base';
 
 // Only allow registering concrete, constructible Operation classes
 const operations = new Map();
+const operations_cache = new Map();
 
 export function registerOperation(name: string, func: OperationConstructor) {
   operations.set(name, func);
@@ -14,3 +15,12 @@ export function getOperation(name: string): OperationConstructor {
   }
   return func;
 }
+
+export function getOperationCache(name: string): Operation {
+  const operation = operations_cache.get(name);
+  if (!operation) {
+    operations_cache.set(name, new (getOperation(name))());
+    return operations_cache.get(name)!;
+  }
+  return operation;
+}
\ No newline at end of file
diff --git a/src/tensor.ts b/src/tensor.ts
index c24cbb7b..4f66e95e 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -1,6 +1,6 @@
 import { _get_original_index } from './broadcasting';
 import { Operation } from './operations/base';
-import { getOperation } from './operations/registry';
+import { getOperation, getOperationCache } from './operations/registry';
 
 /*
  * TODO:
@@ -77,7 +77,7 @@ export class Tensor {
   }
 
   private _executeUnaryOp(opName: string): Tensor {
-    const operation = new (getOperation(opName))();
+    const operation = this.requires_grad ? new (getOperation(opName))() : getOperationCache(opName);
     return operation.forward(this);
   }
 
@@ -85,7 +85,7 @@ export class Tensor {
     if (typeof other == 'number') {
       other = new Tensor(other);
     }
-    const operation = new (getOperation(opName))();
+    const operation = this.requires_grad || other.requires_grad ? new (getOperation(opName))() : getOperationCache(opName);
     return operation.forward(this, other);
   }
 
@@ -111,6 +111,10 @@ export class Tensor {
     this.operation = null;
   }
 
+  zero_(): void {
+    this.data = Array(this.data.length).fill(0);
+  }
+
   backward(grad?: Tensor | null): void {
     if (!this.requires_grad) {
       // If this tensor does not require gradients, stop propagation.

From 6010cb8f1a0fafc069e341eb91ac9d6bd26b7d87 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 13:48:37 +0800
Subject: [PATCH 020/128] feat: pipelining

---
 scripts/macros.ts.j2       |  15 +-
 src/gpu.ts                 |   5 +-
 src/nn/ops.gen.ts          |   6 +-
 src/operations/ops.gen.ts  | 293 +++++++++++++++++++++----------------
 src/operations/ops.ts.j2   | 119 ++++++++-------
 src/tensor.ts              |  33 +++--
 test/functional.test.ts    |  18 +--
 test/nn_functional.test.ts |   2 +-
 test/tensor.test.ts        |  16 +-
 9 files changed, 293 insertions(+), 214 deletions(-)

diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2
index 2cc0306b..a98452a6 100644
--- a/scripts/macros.ts.j2
+++ b/scripts/macros.ts.j2
@@ -7,7 +7,9 @@ const _{{ name }}_kernel = gpu.createKernel(
     return {{ operation }};
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -21,10 +23,9 @@ function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null =
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -39,7 +40,9 @@ const _{{ name }}_kernel = gpu.createKernel(
     return {{ operation }};
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -60,7 +63,7 @@ function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tens
 export class {{ classname }} extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -80,7 +83,7 @@ registerOperation('{{ opname }}', {{ classname }});
 export class {{ classname }} extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _{{ opname }}_tensor(a, a.requires_grad ? this : null);
diff --git a/src/gpu.ts b/src/gpu.ts
index 1773b23a..89782d73 100644
--- a/src/gpu.ts
+++ b/src/gpu.ts
@@ -3,14 +3,17 @@
  * - Probably use Source Academy gpu.js
  */
 
-import { GPU } from '@veehz/gpu.js';
+import { GPU, Texture } from '@veehz/gpu.js';
 import {
   _get_original_index_from_transposed_index,
   _get_original_index_kernel
 } from './broadcasting';
 
+export { Texture };
+
 const gpu = new GPU();
 
+// gpu.addFunction(_get_original_index_kernel);
 gpu.addFunction(_get_original_index_kernel, {
   returnType: 'Integer',
   argumentTypes: {
diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts
index afac074d..81f9b3ff 100644
--- a/src/nn/ops.gen.ts
+++ b/src/nn/ops.gen.ts
@@ -17,7 +17,9 @@ const _relu_kernel = gpu.createKernel(
     return Math.max(a[this.thread.x], 0);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -35,7 +37,7 @@ function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Relu extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _relu_tensor(a, a.requires_grad ? this : null);
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index fd5eaa49..021bbf63 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -6,7 +6,7 @@ import {
   _get_original_index_kernel,
   _pad_shape
 } from '../broadcasting';
-import gpu from '../gpu';
+import gpu, { Texture } from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from './base';
 import * as functional from './functional';
 import { registerOperation } from './registry';
@@ -21,7 +21,9 @@ const _add_kernel = gpu.createKernel(
     return a[a_index] + b[b_index];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -35,10 +37,9 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -47,7 +48,7 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Add extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _add_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -70,7 +71,9 @@ const _sub_kernel = gpu.createKernel(
     return a[a_index] - b[b_index];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -84,10 +87,9 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -96,7 +98,7 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Sub extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _sub_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -119,7 +121,9 @@ const _mul_kernel = gpu.createKernel(
     return a[a_index] * b[b_index];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -133,10 +137,9 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -145,7 +148,7 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Mul extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _mul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -168,7 +171,9 @@ const _div_kernel = gpu.createKernel(
     return a[a_index] / b[b_index];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -182,10 +187,9 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -194,7 +198,7 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Div extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _div_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -217,7 +221,9 @@ const _pow_kernel = gpu.createKernel(
     return a[a_index] ** b[b_index];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -231,10 +237,9 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -243,7 +248,7 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Pow extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _pow_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -266,7 +271,9 @@ const _fmod_kernel = gpu.createKernel(
     return a[a_index] % b[b_index];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -280,10 +287,9 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -292,7 +298,7 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
 export class Fmod extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _fmod_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -315,7 +321,9 @@ const _log_kernel = gpu.createKernel(
     return Math.log(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -333,7 +341,7 @@ function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Log extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _log_tensor(a, a.requires_grad ? this : null);
@@ -354,7 +362,9 @@ const _sqrt_kernel = gpu.createKernel(
     return Math.sqrt(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -372,7 +382,7 @@ function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sqrt extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _sqrt_tensor(a, a.requires_grad ? this : null);
@@ -393,7 +403,9 @@ const _exp_kernel = gpu.createKernel(
     return Math.exp(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -411,7 +423,7 @@ function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Exp extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _exp_tensor(a, a.requires_grad ? this : null);
@@ -432,7 +444,9 @@ const _abs_kernel = gpu.createKernel(
     return Math.abs(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -450,7 +464,7 @@ function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Abs extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _abs_tensor(a, a.requires_grad ? this : null);
@@ -471,7 +485,9 @@ const _sign_kernel = gpu.createKernel(
     return Math.sign(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -489,7 +505,7 @@ function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sign extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _sign_tensor(a, a.requires_grad ? this : null);
@@ -510,7 +526,9 @@ const _neg_kernel = gpu.createKernel(
     return Math.sign(a[this.thread.x]) * a[this.thread.x];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -528,7 +546,7 @@ function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Neg extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _neg_tensor(a, a.requires_grad ? this : null);
@@ -549,7 +567,9 @@ const _reciprocal_kernel = gpu.createKernel(
     return 1 / a[this.thread.x];
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -567,7 +587,7 @@ function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tens
 export class Reciprocal extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _reciprocal_tensor(a, a.requires_grad ? this : null);
@@ -590,7 +610,9 @@ const _sin_kernel = gpu.createKernel(
     return Math.sin(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -608,7 +630,7 @@ function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sin extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _sin_tensor(a, a.requires_grad ? this : null);
@@ -629,7 +651,9 @@ const _cos_kernel = gpu.createKernel(
     return Math.cos(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -647,7 +671,7 @@ function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Cos extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _cos_tensor(a, a.requires_grad ? this : null);
@@ -668,7 +692,9 @@ const _tan_kernel = gpu.createKernel(
     return Math.tan(a[this.thread.x]);
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -686,7 +712,7 @@ function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Tan extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _tan_tensor(a, a.requires_grad ? this : null);
@@ -704,7 +730,7 @@ registerOperation('tan', Tan);
 
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
-    a.data.reduce((acc, val) => acc + val, 0),
+    a.toArray().reduce((acc, val) => acc + val, 0),
     { requires_grad: a.requires_grad },
     { operation: operation }
   );
@@ -714,7 +740,7 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Sum extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _sum_tensor(a, a.requires_grad ? this : null);
@@ -723,7 +749,7 @@ export class Sum extends UnaryOperation {
     const [a] = this.cache;
 
     // backward_operations:
-    const result = new Tensor(Array(a.data.length).fill(dz.data[0]));
+    const result = new Tensor(Array(a.dataLength()).fill(dz.data[0]));
     a.backward(result);
   }
 }
@@ -731,7 +757,7 @@ registerOperation('sum', Sum);
 
 function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
-    a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
+    a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(),
     { requires_grad: a.requires_grad },
     { operation: operation }
   );
@@ -741,7 +767,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 export class Mean extends UnaryOperation {
   private cache: [Tensor];
   public forward(a: Tensor): Tensor {
-    if(a.requires_grad) {
+    if (a.requires_grad) {
       this.cache = [a];
     }
     return _mean_tensor(a, a.requires_grad ? this : null);
@@ -750,7 +776,7 @@ export class Mean extends UnaryOperation {
     const [a] = this.cache;
 
     // backward_operations:
-    const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));
+    const result = new Tensor(Array(a.dataLength()).fill(dz.data[0] / a.dataLength()));
     a.backward(result);
   }
 }
@@ -758,24 +784,29 @@ registerOperation('mean', Mean);
 
 // linalg
 
+const _transpose_kernel = gpu.createKernel(
+  function (a: number[], as: number[], dim0: number, dim1: number) {
+    const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
+    return a[a_index];
+  },
+  {
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
+  }
+);
+
 function _transpose_tensor(
   a: Tensor,
   dim0: number,
   dim1: number,
   operation: Operation | null = null
 ): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], dim0: number, dim1: number) {
-      const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
-      return a[a_index];
-    },
-    {
-      constants: {
-        shape_length: a.shape.length
-      },
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _transpose_kernel;
+  kernel.setConstants({
+    shape_length: a.shape.length
+  });
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   const swapped_shape = [...a.shape];
   [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
@@ -802,6 +833,42 @@ export class Transpose extends Operation {
 }
 registerOperation('transpose', Transpose);
 
+function _matmul_kernel_function(
+  a: number[],
+  as: number[],
+  b: number[],
+  bs: number[],
+  bcs: number[]
+) {
+  let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+  let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+  const l = this.constants.shape_length;
+
+  const tmp1 = bcs[l] * bcs[l + 1];
+  const position = this.thread.x % tmp1;
+
+  a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
+  b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
+
+  const b_stride = bs[l + 1];
+
+  let sum = 0;
+  for (let i = 0; i < this.constants.lp; i++) {
+    sum = sum + a[a_index] * b[b_index];
+    a_index = a_index + 1;
+    b_index = b_index + b_stride;
+  }
+
+  return sum;
+}
+
+const _matmul_kernel = gpu.createKernel(_matmul_kernel_function, {
+  dynamicOutput: true,
+  pipeline: true,
+  immutable: true
+});
+
 function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   if (a.shape.length == 1 && b.shape.length == 1) {
     return a.mul(b).sum();
@@ -833,42 +900,13 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
   const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
 
-  function _matmul_kernel(
-    a: number[],
-    as: number[],
-    b: number[],
-    bs: number[],
-    bcs: number[],
-    lp: number
-  ) {
-    let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    const l = this.constants.shape_length;
-
-    const position = this.thread.x % (bcs[l] * bcs[l + 1]);
-    a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
-    b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
-
-    const b_stride = bs[l + 1];
-
-    let sum = 0;
-    for (let i = 0; i < lp; i++) {
-      sum = sum + a[a_index] * b[b_index];
-      a_index = a_index + 1;
-      b_index = b_index + b_stride;
-    }
-
-    return sum;
-  }
-
-  const kernel = gpu.createKernel(_matmul_kernel, {
-    constants: {
-      // assumes that _get_original_index_kernel reads from the front
-      shape_length: broadcast_shape.length - 2
-    },
-    output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+  const kernel = _matmul_kernel;
+  kernel.setConstants({
+    lp: loop_iterations,
+    // assumes that _get_original_index_kernel reads from the front
+    shape_length: broadcast_shape.length - 2
   });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
 
   let shape_after_removing_extra_dims = [...broadcast_shape];
 
@@ -888,8 +926,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
       padded_a_shape,
       b.data,
       padded_b_shape,
-      broadcast_shape,
-      loop_iterations
+      broadcast_shape
     ) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: shape_after_removing_extra_dims }
@@ -900,7 +937,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
 export class Matmul extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -924,7 +961,9 @@ const _lt_kernel = gpu.createKernel(
     return (a[a_index] < b[b_index]) ? 1 : 0;
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -938,10 +977,9 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -950,7 +988,7 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Lt extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _lt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -972,7 +1010,9 @@ const _gt_kernel = gpu.createKernel(
     return (a[a_index] > b[b_index]) ? 1 : 0;
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -986,10 +1026,9 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -998,7 +1037,7 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Gt extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _gt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -1020,7 +1059,9 @@ const _le_kernel = gpu.createKernel(
     return (a[a_index] <= b[b_index]) ? 1 : 0;
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -1034,10 +1075,9 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1046,7 +1086,7 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Le extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _le_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -1068,7 +1108,9 @@ const _ge_kernel = gpu.createKernel(
     return (a[a_index] >= b[b_index]) ? 1 : 0;
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -1082,10 +1124,9 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1094,7 +1135,7 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Ge extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _ge_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -1116,7 +1157,9 @@ const _eq_kernel = gpu.createKernel(
     return (a[a_index] == b[b_index]) ? 1 : 0;
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -1130,10 +1173,9 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1142,7 +1184,7 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Eq extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _eq_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
@@ -1164,7 +1206,9 @@ const _ne_kernel = gpu.createKernel(
     return (a[a_index] != b[b_index]) ? 1 : 0;
   },
   {
-    dynamicOutput: true
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
   }
 );
 
@@ -1178,10 +1222,9 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
     shape_length: broadcast_shape.length
   });
   kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-  
+
   return new Tensor(
     kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
-    // data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1190,7 +1233,7 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
 export class Ne extends BinaryOperation {
   private cache: [Tensor, Tensor];
   public forward(a: Tensor, b: Tensor): Tensor {
-    if(a.requires_grad || b.requires_grad) {
+    if (a.requires_grad || b.requires_grad) {
       this.cache = [a, b];
     }
     return _ne_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index 675aae57..8833b907 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -6,7 +6,7 @@ import {
   _get_original_index_kernel,
   _pad_shape
 } from '../broadcasting';
-import gpu from '../gpu';
+import gpu, { Texture } from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from './base';
 import * as functional from './functional';
 import { registerOperation } from './registry';
@@ -72,44 +72,49 @@ import { registerOperation } from './registry';
 
 function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
-    a.data.reduce((acc, val) => acc + val, 0),
+    a.toArray().reduce((acc, val) => acc + val, 0),
     { requires_grad: a.requires_grad },
     { operation: operation }
   );
 }
 
-{{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.data.length).fill(dz.data[0]));", "a.backward(result);"]) }}
+{{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.dataLength()).fill(dz.data[0]));", "a.backward(result);"]) }}
 
 function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   return new Tensor(
-    a.data.reduce((acc, val) => acc + val, 0) / a.data.length,
+    a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(),
     { requires_grad: a.requires_grad },
     { operation: operation }
   );
 }
 
-{{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.data.length).fill(dz.data[0] / a.data.length));", "a.backward(result);"]) }}
+{{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.dataLength()).fill(dz.data[0] / a.dataLength()));", "a.backward(result);"]) }}
 
 // linalg
 
+const _transpose_kernel = gpu.createKernel(
+  function (a: number[], as: number[], dim0: number, dim1: number) {
+    const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
+    return a[a_index];
+  },
+  {
+    dynamicOutput: true,
+    pipeline: true,
+    immutable: true
+  }
+);
+
 function _transpose_tensor(
   a: Tensor,
   dim0: number,
   dim1: number,
   operation: Operation | null = null
 ): Tensor {
-  const kernel = gpu.createKernel(
-    function (a: number[], as: number[], dim0: number, dim1: number) {
-      const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
-      return a[a_index];
-    },
-    {
-      constants: {
-        shape_length: a.shape.length
-      },
-      output: [a.shape.reduce((acc, val) => acc * val, 1)]
-    }
-  );
+  const kernel = _transpose_kernel;
+  kernel.setConstants({
+    shape_length: a.shape.length
+  });
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
 
   const swapped_shape = [...a.shape];
   [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
@@ -136,6 +141,42 @@ export class Transpose extends Operation {
 }
 registerOperation('transpose', Transpose);
 
+function _matmul_kernel_function(
+  a: number[],
+  as: number[],
+  b: number[],
+  bs: number[],
+  bcs: number[]
+) {
+  let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+  let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+  const l = this.constants.shape_length;
+
+  const tmp1 = bcs[l] * bcs[l + 1];
+  const position = this.thread.x % tmp1;
+
+  a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
+  b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
+
+  const b_stride = bs[l + 1];
+
+  let sum = 0;
+  for (let i = 0; i < this.constants.lp; i++) {
+    sum = sum + a[a_index] * b[b_index];
+    a_index = a_index + 1;
+    b_index = b_index + b_stride;
+  }
+
+  return sum;
+}
+
+const _matmul_kernel = gpu.createKernel(_matmul_kernel_function, {
+  dynamicOutput: true,
+  pipeline: true,
+  immutable: true
+});
+
 function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   if (a.shape.length == 1 && b.shape.length == 1) {
     return a.mul(b).sum();
@@ -167,42 +208,13 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
   const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
 
-  function _matmul_kernel(
-    a: number[],
-    as: number[],
-    b: number[],
-    bs: number[],
-    bcs: number[],
-    lp: number
-  ) {
-    let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    const l = this.constants.shape_length;
-
-    const position = this.thread.x % (bcs[l] * bcs[l + 1]);
-    a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
-    b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
-
-    const b_stride = bs[l + 1];
-
-    let sum = 0;
-    for (let i = 0; i < lp; i++) {
-      sum = sum + a[a_index] * b[b_index];
-      a_index = a_index + 1;
-      b_index = b_index + b_stride;
-    }
-
-    return sum;
-  }
-
-  const kernel = gpu.createKernel(_matmul_kernel, {
-    constants: {
-      // assumes that _get_original_index_kernel reads from the front
-      shape_length: broadcast_shape.length - 2
-    },
-    output: [broadcast_shape.reduce((acc, val) => acc * val, 1)]
+  const kernel = _matmul_kernel;
+  kernel.setConstants({
+    lp: loop_iterations,
+    // assumes that _get_original_index_kernel reads from the front
+    shape_length: broadcast_shape.length - 2
   });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
 
   let shape_after_removing_extra_dims = [...broadcast_shape];
 
@@ -222,8 +234,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
       padded_a_shape,
       b.data,
       padded_b_shape,
-      broadcast_shape,
-      loop_iterations
+      broadcast_shape
     ) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: shape_after_removing_extra_dims }
diff --git a/src/tensor.ts b/src/tensor.ts
index 4f66e95e..49ec2694 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -1,6 +1,7 @@
 import { _get_original_index } from './broadcasting';
 import { Operation } from './operations/base';
 import { getOperation, getOperationCache } from './operations/registry';
+import { Texture } from './gpu';
 
 /*
  * TODO:
@@ -44,7 +45,7 @@ function _flatten(data: NestedNumberArray): number[] {
 }
 
 export class Tensor {
-  data: number[];
+  data: number[] | Texture;
   _shape: number[];
   operation: Operation | null = null;
   public grad: Tensor | null = null;
@@ -52,14 +53,14 @@ export class Tensor {
   requires_grad: boolean;
 
   constructor(
-    data: NestedNumberArray,
+    data: NestedNumberArray | Texture,
     options: { requires_grad?: boolean } = {},
     internal_options: { operation?: Operation; shape?: number[] } = {}
   ) {
-    this.data = _flatten(data);
+    this.data = data instanceof Texture ? data : _flatten(data);
     this.requires_grad = options.requires_grad ?? false;
 
-    this._shape = internal_options.shape ?? _get_shape(data);
+    this._shape = internal_options.shape ?? _get_shape(data instanceof Texture ? data.toArray() : data);
     this.operation = internal_options.operation ?? null;
   }
 
@@ -72,6 +73,20 @@ export class Tensor {
     // return this._shape;
   }
 
+  toArray(): number[] {
+    if (this.data instanceof Texture) {
+      return this.data.toArray() as number[];
+    }
+    return this.data;
+  }
+
+  dataLength(): number {
+    if (this.data instanceof Texture) {
+      return this.shape.reduce((acc, val) => acc * val, 1);
+    }
+    return this.data.length;
+  }
+
   set shape(shape: number[]) {
     this._shape = shape;
   }
@@ -95,7 +110,7 @@ export class Tensor {
   }
 
   item(): number {
-    if (this.data.length !== 1) {
+    if (this.dataLength() !== 1) {
       throw new Error('Tensor.item() is only valid for scalars');
     }
     return this.data[0];
@@ -112,7 +127,7 @@ export class Tensor {
   }
 
   zero_(): void {
-    this.data = Array(this.data.length).fill(0);
+    this.data = Array(this.dataLength()).fill(0);
   }
 
   backward(grad?: Tensor | null): void {
@@ -123,7 +138,7 @@ export class Tensor {
     }
 
     if (!grad) {
-      if (this.data.length !== 1) {
+      if (this.dataLength() !== 1) {
         throw new Error('Gradient is required for non-scalar tensors');
       }
 
@@ -131,11 +146,11 @@ export class Tensor {
     }
 
     if (!this.grad) {
-      this.grad = new Tensor(Array(this.data.length).fill(0));
+      this.grad = new Tensor(Array(this.dataLength()).fill(0));
     }
 
     // Add grad to this.grad
-    for (let i = 0; i < grad.data.length; i++) {
+    for (let i = 0; i < grad.dataLength(); i++) {
       this.grad.data[_get_original_index(this.shape, grad.shape, i)] += grad.data[i];
     }
 
diff --git a/test/functional.test.ts b/test/functional.test.ts
index 5fadfd10..48e59289 100644
--- a/test/functional.test.ts
+++ b/test/functional.test.ts
@@ -8,7 +8,7 @@ describe("Functional", () => {
       const t2 = new Tensor([20]);
       const result = torch.add(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([30]);
+      expect(Array.from(result.toArray())).toEqual([30]);
       expect(result.shape).toEqual([1]);
     });
 
@@ -17,7 +17,7 @@ describe("Functional", () => {
       const t2 = new Tensor([1]);
       const result = torch.add(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([11, 21, 31]);
+      expect(Array.from(result.toArray())).toEqual([11, 21, 31]);
       expect(result.shape).toEqual([3]);
     });
 
@@ -26,7 +26,7 @@ describe("Functional", () => {
       const t2 = new Tensor([4, 5, 6]);
       const result = torch.add(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([5, 7, 9]);
+      expect(Array.from(result.toArray())).toEqual([5, 7, 9]);
       expect(result.shape).toEqual([3]);
     });
   });
@@ -37,7 +37,7 @@ describe("Functional", () => {
       const t2 = new Tensor([20]);
       const result = torch.mul(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([200]);
+      expect(Array.from(result.toArray())).toEqual([200]);
       expect(result.shape).toEqual([1]);
     });
   });
@@ -48,7 +48,7 @@ describe("Functional", () => {
       const t2 = new Tensor([1]);
       const result = torch.mul(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([10, 20, 30]);
+      expect(Array.from(result.toArray())).toEqual([10, 20, 30]);
       expect(result.shape).toEqual([3]);
     });
   });
@@ -59,7 +59,7 @@ describe("Functional", () => {
       const t2 = new Tensor([20]);
       const result = torch.matmul(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([200]);
+      expect(Array.from(result.toArray())).toEqual([200]);
       expect(result.shape).toEqual([1]);
     });
 
@@ -68,7 +68,7 @@ describe("Functional", () => {
       const t2 = new Tensor([5, 6, 7, 8]);
       const result = torch.matmul(t1, t2);
 
-      expect(Array.from(result.data)).toEqual([70]);
+      expect(Array.from(result.toArray())).toEqual([70]);
       expect(result.shape).toEqual([1]);
     });
 
@@ -91,7 +91,7 @@ describe("Functional", () => {
         96, 86, 55
       ];
 
-      expect(Array.from(result.data)).toEqual(expected);
+      expect(Array.from(result.toArray())).toEqual(expected);
       expect(result.shape).toEqual([2, 3]);
     });
 
@@ -115,7 +115,7 @@ describe("Functional", () => {
     test("should transpose a tensor", () => {
       const t = new Tensor([[1, 2], [3, 4]]);
       const result = t.transpose(0, 1);
-      expect(Array.from(result.data)).toEqual([1, 3, 2, 4]);
+      expect(Array.from(result.toArray())).toEqual([1, 3, 2, 4]);
       expect(result.shape).toEqual([2, 2]);
     });
   });
diff --git a/test/nn_functional.test.ts b/test/nn_functional.test.ts
index 134a57f7..902b12c6 100644
--- a/test/nn_functional.test.ts
+++ b/test/nn_functional.test.ts
@@ -5,7 +5,7 @@ describe("NN Functional", () => {
     test("should forward a tensor", () => {
       const x = new torch.Tensor([1, -2, 3, -4, 5]);
       const result = torch.nn.functional.relu(x);
-      expect(Array.from(result.data)).toEqual([1, 0, 3, 0, 5]);
+      expect(Array.from(result.toArray())).toEqual([1, 0, 3, 0, 5]);
       expect(result.shape).toEqual([5]);
     });
   });
diff --git a/test/tensor.test.ts b/test/tensor.test.ts
index 64181a0f..d2309a70 100644
--- a/test/tensor.test.ts
+++ b/test/tensor.test.ts
@@ -21,7 +21,7 @@ describe('Tensor', () => {
       const t2 = new Tensor([20]);
       const result = t1.add(t2);
       
-      expect(Array.from(result.data)).toEqual([30]);
+      expect(Array.from(result.toArray())).toEqual([30]);
       expect(result.shape).toEqual([1]);
     });
 
@@ -29,8 +29,10 @@ describe('Tensor', () => {
       const t1 = new Tensor([10, 20, 30]);
       const t2 = new Tensor([1]);
       const result = t1.add(t2);
+
+      console.log("shsh", result.shape, result.toArray());
       
-      expect(Array.from(result.data)).toEqual([11, 21, 31]);
+      expect(Array.from(result.toArray())).toEqual([11, 21, 31]);
       expect(result.shape).toEqual([3]);
     });
 
@@ -39,7 +41,7 @@ describe('Tensor', () => {
       const t2 = new Tensor([4, 5, 6]);
       const result = t1.add(t2);
       
-      expect(Array.from(result.data)).toEqual([5, 7, 9]);
+      expect(Array.from(result.toArray())).toEqual([5, 7, 9]);
       expect(result.shape).toEqual([3]);
     });
   });
@@ -50,7 +52,7 @@ describe('Tensor', () => {
       const t2 = new Tensor([20]);
       const result = t1.mul(t2);
 
-      expect(Array.from(result.data)).toEqual([200]);
+      expect(Array.from(result.toArray())).toEqual([200]);
       expect(result.shape).toEqual([1]);
     });
   });
@@ -61,7 +63,7 @@ describe('Tensor', () => {
       const t2 = new Tensor([1]);
       const result = t1.mul(t2);
 
-      expect(Array.from(result.data)).toEqual([10, 20, 30]);
+      expect(Array.from(result.toArray())).toEqual([10, 20, 30]);
       expect(result.shape).toEqual([3]);
     });
   });
@@ -72,7 +74,7 @@ describe('Tensor', () => {
       const t2 = new Tensor([20]);
       const result = t1.matmul(t2);
 
-      expect(Array.from(result.data)).toEqual([200]);
+      expect(Array.from(result.toArray())).toEqual([200]);
       expect(result.shape).toEqual([1]);
     });
 
@@ -95,7 +97,7 @@ describe('Tensor', () => {
         96, 86, 55
       ];
 
-      expect(Array.from(result.data)).toEqual(expected);
+      expect(Array.from(result.toArray())).toEqual(expected);
       expect(result.shape).toEqual([2, 3]);
     });
   });

From 9e31d7f68fe75d2df83e1cd5cd454c404524f199 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 13:56:03 +0800
Subject: [PATCH 021/128] fix: remove unused utils file

---
 src/utils.ts | 7 -------
 1 file changed, 7 deletions(-)
 delete mode 100644 src/utils.ts

diff --git a/src/utils.ts b/src/utils.ts
deleted file mode 100644
index fd9225e2..00000000
--- a/src/utils.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Tensor } from './tensor';
-
-export function ones_like(other: Tensor): Tensor {
-  const tensor = new Tensor(Array(other.data.length).fill(1));
-  tensor.shape = other.shape;
-  return tensor;
-}

From 42f91dd70088e1925dcf5731e1070b073325fc5f Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 13:56:16 +0800
Subject: [PATCH 022/128] feat: gpu support inspection

---
 examples/is_gpu_supported.js | 12 ++++++++++++
 src/gpu.ts                   |  3 +++
 src/index.ts                 |  4 ++++
 3 files changed, 19 insertions(+)
 create mode 100644 examples/is_gpu_supported.js

diff --git a/examples/is_gpu_supported.js b/examples/is_gpu_supported.js
new file mode 100644
index 00000000..63dcc0f4
--- /dev/null
+++ b/examples/is_gpu_supported.js
@@ -0,0 +1,12 @@
+// Script to check if GPU is supported on the system
+import { GPU } from "../build/node/torch.node.es.js";
+
+console.log("Is GPU supported:", GPU.isGPUSupported);
+console.log("Is kernel map supported:", GPU.isKernelMapSupported);
+console.log("Is off-screen canvas supported:", GPU.isOffscreenCanvasSupported);
+console.log("Is WebGL supported:", GPU.isWebGLSupported);
+console.log("Is WebGL2 supported:", GPU.isWebGL2Supported);
+console.log("Is HeadlessGL supported:", GPU.isHeadlessGLSupported);
+console.log("Is Canvas supported:", GPU.isCanvasSupported);
+console.log("Is GPUHTMLImageArray supported:", GPU.isGPUHTMLImageArraySupported);
+console.log("Is SinglePrecision supported:", GPU.isSinglePrecisionSupported);
diff --git a/src/gpu.ts b/src/gpu.ts
index 89782d73..cc88c19e 100644
--- a/src/gpu.ts
+++ b/src/gpu.ts
@@ -34,3 +34,6 @@ gpu.addFunction(_get_original_index_from_transposed_index, {
 });
 
 export default gpu;
+
+// for debugging purposes
+export { GPU };
diff --git a/src/index.ts b/src/index.ts
index 89d9a6c5..703a65ab 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,4 @@
+import gpu, { GPU } from './gpu';
 import { Tensor } from './tensor';
 
 export * from './operations/ops.gen';
@@ -6,3 +7,6 @@ export * from './creation/index';
 export * as nn from './nn/index';
 export * as optim from './optim/index';
 export { Tensor };
+
+// For debugging purposes
+export { gpu, GPU };

From e6c5977972731fb766c1e81de2de2579be0c284d Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 14:09:48 +0800
Subject: [PATCH 023/128] feat: build and publish built files to github pages

---
 .github/workflows/push.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index ca8492e6..0449bf2e 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -48,9 +48,15 @@ jobs:
         - name: Install dependencies
           run: yarn install --immutable
 
+        - name: Build
+          run: yarn build
+
         - name: Build docs
           run: yarn docs
 
+        - name: Copy build to docs/build
+          run: cp -r build docs/build
+
         - name: Deploy docs
           uses: peaceiris/actions-gh-pages@v4
           with:

From cae6f71029a44e7fb847a325d8ad73c935ac85c7 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 16:26:12 +0800
Subject: [PATCH 024/128] feat: gpu support inspection browser

---
 examples/browser/index.html | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/examples/browser/index.html b/examples/browser/index.html
index 1fe3cc2b..920e8bfb 100644
--- a/examples/browser/index.html
+++ b/examples/browser/index.html
@@ -13,6 +13,18 @@
 
 
   

+
+  
   
+    
+
+    
+    
+    
+  
+
\ No newline at end of file
diff --git a/test/module.test.js b/test/module.test.js
new file mode 100644
index 00000000..255ea096
--- /dev/null
+++ b/test/module.test.js
@@ -0,0 +1,28 @@
+import { assert } from 'chai';
+import * as torch from 'torch';
+
+describe('Module', () => {
+  describe('Linear', () => {
+    it('should create a linear module', () => {
+      const linear = new torch.nn.Linear(10, 20);
+      assert.deepStrictEqual(linear.parameters().length, 2);
+      assert.deepStrictEqual(linear.parameters()[0].shape, [20, 10]);
+      assert.deepStrictEqual(linear.parameters()[1].shape, [20]);
+    });
+
+    it('should forward a tensor', () => {
+      const linear = new torch.nn.Linear(10, 20);
+      const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+      const output = linear.forward(input);
+      assert.deepStrictEqual(output.shape, [20]);
+    });
+
+    it('should forward a tensor (2D)', () => {
+      // example from https://docs.pytorch.org/docs/stable/generated/torch.nn.Linear.html
+      const m = new torch.nn.Linear(20, 30);
+      const input = torch.randn(128, 20);
+      const output = m.forward(input);
+      assert.deepStrictEqual(output.shape, [128, 30]);
+    });
+  });
+});
diff --git a/test/module.test.ts b/test/module.test.ts
deleted file mode 100644
index 6f281a70..00000000
--- a/test/module.test.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as torch from "../src/index";
-
-describe("Module", () => {
-  describe("Linear", () => {
-    test("should create a linear module", () => {
-      const linear = new torch.nn.Linear(10, 20);
-      expect(linear.parameters().length).toEqual(2);
-      expect(linear.parameters()[0].shape).toEqual([20, 10]);
-      expect(linear.parameters()[1].shape).toEqual([20]);
-    });
-
-    test("should forward a tensor", () => {
-      const linear = new torch.nn.Linear(10, 20);
-      const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
-      const output = linear.forward(input);
-      expect(output.shape).toEqual([20]);
-    });
-
-    test("should forward a tensor (2D)", () => {
-      // example from https://docs.pytorch.org/docs/stable/generated/torch.nn.Linear.html
-      const m = new torch.nn.Linear(20, 30);
-      const input = torch.randn(128, 20);
-      const output = m.forward(input);
-      expect(output.shape).toEqual([128, 30]);
-    });
-  });
-});
\ No newline at end of file
diff --git a/test/nn_functional.test.js b/test/nn_functional.test.js
new file mode 100644
index 00000000..2dbdf18a
--- /dev/null
+++ b/test/nn_functional.test.js
@@ -0,0 +1,13 @@
+import { assert } from 'chai';
+import * as torch from 'torch';
+
+describe('NN Functional', () => {
+  describe('Relu', () => {
+    it('should forward a tensor', () => {
+      const x = new torch.Tensor([1, -2, 3, -4, 5]);
+      const result = torch.nn.functional.relu(x);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 0, 3, 0, 5]);
+      assert.deepStrictEqual(result.shape, [5]);
+    });
+  });
+});
diff --git a/test/nn_functional.test.ts b/test/nn_functional.test.ts
deleted file mode 100644
index 902b12c6..00000000
--- a/test/nn_functional.test.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import * as torch from "../src/index";
-
-describe("NN Functional", () => {
-  describe("Relu", () => {
-    test("should forward a tensor", () => {
-      const x = new torch.Tensor([1, -2, 3, -4, 5]);
-      const result = torch.nn.functional.relu(x);
-      expect(Array.from(result.toArray())).toEqual([1, 0, 3, 0, 5]);
-      expect(result.shape).toEqual([5]);
-    });
-  });
-});
\ No newline at end of file
diff --git a/test/optimizers.test.js b/test/optimizers.test.js
new file mode 100644
index 00000000..45c10e61
--- /dev/null
+++ b/test/optimizers.test.js
@@ -0,0 +1,18 @@
+import { assert } from 'chai';
+import * as torch from 'torch';
+
+describe('Optimizers', () => {
+  describe('SGD', () => {
+    it('should update parameters', () => {
+      const x = new torch.Tensor([1.0], { requires_grad: true });
+      const y = x.mul(new torch.Tensor(2.0));
+      y.backward();
+
+      const sgd = new torch.optim.SGD([x], 0.01);
+      sgd.step();
+      const actual = sgd.params[0].data[0];
+      const expected = 0.98;
+      assert.ok(Math.abs(actual - expected) < 1e-6);
+    });
+  });
+});
diff --git a/test/optimizers.test.ts b/test/optimizers.test.ts
deleted file mode 100644
index dc4a8a75..00000000
--- a/test/optimizers.test.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as torch from "../src/index";
-
-describe("Optimizers", () => {
-  describe("SGD", () => {
-    test("should update parameters", () => {
-      const x = new torch.Tensor([1.0], { requires_grad: true });
-      const y = x.mul(new torch.Tensor(2.0));
-      y.backward();
-
-      const sgd = new torch.optim.SGD([x], 0.01);
-      sgd.step();
-      expect(sgd.params[0].data[0]).toBeCloseTo(0.98);
-    });
-  });
-});
\ No newline at end of file
diff --git a/test/tensor.test.js b/test/tensor.test.js
new file mode 100644
index 00000000..d0ac90cf
--- /dev/null
+++ b/test/tensor.test.js
@@ -0,0 +1,105 @@
+import { assert } from 'chai';
+import { Tensor } from 'torch';
+
+describe('Tensor', () => {
+  describe('Constructor', () => {
+    it('should create a tensor with correct data and shape', () => {
+      const tensor = new Tensor([10, 20, 30]);
+      assert.deepStrictEqual(tensor.data, [10, 20, 30]);
+      assert.deepStrictEqual(tensor.shape, [3]);
+    });
+
+    it('should create a tensor with nested array', () => {
+      const tensor = new Tensor([
+        [1, 2],
+        [3, 4]
+      ]);
+      assert.deepStrictEqual(tensor.data, [1, 2, 3, 4]);
+      assert.deepStrictEqual(tensor.shape, [2, 2]);
+    });
+  });
+
+  describe('Addition', () => {
+    it('should add two tensors with same shape', () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = t1.add(t2);
+
+      assert.deepStrictEqual(Array.from(result.toArray()), [30]);
+      assert.deepStrictEqual(result.shape, [1]);
+    });
+
+    it('should add tensors with different shapes (broadcasting)', () => {
+      const t1 = new Tensor([10, 20, 30]);
+      const t2 = new Tensor([1]);
+      const result = t1.add(t2);
+
+      console.log('shsh', result.shape, result.toArray());
+
+      assert.deepStrictEqual(Array.from(result.toArray()), [11, 21, 31]);
+      assert.deepStrictEqual(result.shape, [3]);
+    });
+
+    it('should add two 1D tensors of same length', () => {
+      const t1 = new Tensor([1, 2, 3]);
+      const t2 = new Tensor([4, 5, 6]);
+      const result = t1.add(t2);
+
+      assert.deepStrictEqual(Array.from(result.toArray()), [5, 7, 9]);
+      assert.deepStrictEqual(result.shape, [3]);
+    });
+  });
+
+  describe('Multiplication', () => {
+    it('should multiply two tensors with same shape', () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = t1.mul(t2);
+
+      assert.deepStrictEqual(Array.from(result.toArray()), [200]);
+      assert.deepStrictEqual(result.shape, [1]);
+    });
+  });
+
+  describe('should multiply tensors with different shapes (broadcasting)', () => {
+    it('should multiply two tensors with different shapes (broadcasting)', () => {
+      const t1 = new Tensor([10, 20, 30]);
+      const t2 = new Tensor([1]);
+      const result = t1.mul(t2);
+
+      assert.deepStrictEqual(Array.from(result.toArray()), [10, 20, 30]);
+      assert.deepStrictEqual(result.shape, [3]);
+    });
+  });
+
+  describe('Matrix Multiplication', () => {
+    it('should multiply two tensors with dim 1', () => {
+      const t1 = new Tensor([10]);
+      const t2 = new Tensor([20]);
+      const result = t1.matmul(t2);
+
+      assert.deepStrictEqual(Array.from(result.toArray()), [200]);
+      assert.deepStrictEqual(result.shape, [1]);
+    });
+
+    it('should multiply two tensors with the correct values', () => {
+      const t1 = new Tensor([
+        [1, 2, 3],
+        [4, 5, 6]
+      ]);
+
+      const t2 = new Tensor([
+        [9, 9, 1],
+        [6, 4, 3],
+        [5, 5, 6]
+      ]);
+
+      const result = t1.matmul(t2);
+
+      const expected = [36, 32, 25, 96, 86, 55];
+
+      assert.deepStrictEqual(Array.from(result.toArray()), expected);
+      assert.deepStrictEqual(result.shape, [2, 3]);
+    });
+  });
+});
diff --git a/test/tensor.test.ts b/test/tensor.test.ts
deleted file mode 100644
index d2309a70..00000000
--- a/test/tensor.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import { Tensor } from '../src/index';
-
-describe('Tensor', () => {
-  describe('Constructor', () => {
-    test('should create a tensor with correct data and shape', () => {
-      const tensor = new Tensor([10, 20, 30]);
-      expect(tensor.data).toEqual([10, 20, 30]);
-      expect(tensor.shape).toEqual([3]);
-    });
-
-    test('should create a tensor with nested array', () => {
-      const tensor = new Tensor([[1, 2], [3, 4]]);
-      expect(tensor.data).toEqual([1, 2, 3, 4]);
-      expect(tensor.shape).toEqual([2, 2]);
-    });
-  });
-
-  describe('Addition', () => {
-    test('should add two tensors with same shape', () => {
-      const t1 = new Tensor([10]);
-      const t2 = new Tensor([20]);
-      const result = t1.add(t2);
-      
-      expect(Array.from(result.toArray())).toEqual([30]);
-      expect(result.shape).toEqual([1]);
-    });
-
-    test('should add tensors with different shapes (broadcasting)', () => {
-      const t1 = new Tensor([10, 20, 30]);
-      const t2 = new Tensor([1]);
-      const result = t1.add(t2);
-
-      console.log("shsh", result.shape, result.toArray());
-      
-      expect(Array.from(result.toArray())).toEqual([11, 21, 31]);
-      expect(result.shape).toEqual([3]);
-    });
-
-    test('should add two 1D tensors of same length', () => {
-      const t1 = new Tensor([1, 2, 3]);
-      const t2 = new Tensor([4, 5, 6]);
-      const result = t1.add(t2);
-      
-      expect(Array.from(result.toArray())).toEqual([5, 7, 9]);
-      expect(result.shape).toEqual([3]);
-    });
-  });
-
-  describe('Multiplication', () => {
-    test('should multiply two tensors with same shape', () => {
-      const t1 = new Tensor([10]);
-      const t2 = new Tensor([20]);
-      const result = t1.mul(t2);
-
-      expect(Array.from(result.toArray())).toEqual([200]);
-      expect(result.shape).toEqual([1]);
-    });
-  });
-
-  describe('should multiply tensors with different shapes (broadcasting)', () => {
-    test('should multiply two tensors with different shapes (broadcasting)', () => {
-      const t1 = new Tensor([10, 20, 30]);
-      const t2 = new Tensor([1]);
-      const result = t1.mul(t2);
-
-      expect(Array.from(result.toArray())).toEqual([10, 20, 30]);
-      expect(result.shape).toEqual([3]);
-    });
-  });
-
-  describe("Matrix Multiplication", () => {
-    test("should multiply two tensors with dim 1", () => {
-      const t1 = new Tensor([10]);
-      const t2 = new Tensor([20]);
-      const result = t1.matmul(t2);
-
-      expect(Array.from(result.toArray())).toEqual([200]);
-      expect(result.shape).toEqual([1]);
-    });
-
-    test("should multiply two tensors with the correct values", () => {
-      const t1 = new Tensor([
-        [1, 2, 3],
-        [4, 5, 6]
-      ]);
-
-      const t2 = new Tensor([
-        [9, 9, 1],
-        [6, 4, 3],
-        [5, 5, 6]
-      ])
-
-      const result = t1.matmul(t2);
-
-      const expected = [
-        36, 32, 25,
-        96, 86, 55
-      ];
-
-      expect(Array.from(result.toArray())).toEqual(expected);
-      expect(result.shape).toEqual([2, 3]);
-    });
-  });
-
-
-});
diff --git a/tsconfig.json b/tsconfig.json
index eafdb462..e2a5a6fe 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,7 +11,7 @@
       "esModuleInterop": true,
       "noEmit": true,
       "skipLibCheck": true,
-      "types": ["node", "jest"]
+      "types": ["node", "mocha"]
     },
     "include": ["src", "test", "vite.config.browser.ts", "vite.config.node.ts"]
   }
diff --git a/yarn.lock b/yarn.lock
index fa610f7e..a402cc6c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5,110 +5,6 @@ __metadata:
   version: 8
   cacheKey: 10c0
 
-"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.27.1":
-  version: 7.27.1
-  resolution: "@babel/code-frame@npm:7.27.1"
-  dependencies:
-    "@babel/helper-validator-identifier": "npm:^7.27.1"
-    js-tokens: "npm:^4.0.0"
-    picocolors: "npm:^1.1.1"
-  checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00
-  languageName: node
-  linkType: hard
-
-"@babel/compat-data@npm:^7.27.2":
-  version: 7.28.4
-  resolution: "@babel/compat-data@npm:7.28.4"
-  checksum: 10c0/9d346471e0a016641df9a325f42ad1e8324bbdc0243ce4af4dd2b10b974128590da9eb179eea2c36647b9bb987343119105e96773c1f6981732cd4f87e5a03b9
-  languageName: node
-  linkType: hard
-
-"@babel/core@npm:^7.23.9, @babel/core@npm:^7.27.4":
-  version: 7.28.4
-  resolution: "@babel/core@npm:7.28.4"
-  dependencies:
-    "@babel/code-frame": "npm:^7.27.1"
-    "@babel/generator": "npm:^7.28.3"
-    "@babel/helper-compilation-targets": "npm:^7.27.2"
-    "@babel/helper-module-transforms": "npm:^7.28.3"
-    "@babel/helpers": "npm:^7.28.4"
-    "@babel/parser": "npm:^7.28.4"
-    "@babel/template": "npm:^7.27.2"
-    "@babel/traverse": "npm:^7.28.4"
-    "@babel/types": "npm:^7.28.4"
-    "@jridgewell/remapping": "npm:^2.3.5"
-    convert-source-map: "npm:^2.0.0"
-    debug: "npm:^4.1.0"
-    gensync: "npm:^1.0.0-beta.2"
-    json5: "npm:^2.2.3"
-    semver: "npm:^6.3.1"
-  checksum: 10c0/ef5a6c3c6bf40d3589b5593f8118cfe2602ce737412629fb6e26d595be2fcbaae0807b43027a5c42ec4fba5b895ff65891f2503b5918c8a3ea3542ab44d4c278
-  languageName: node
-  linkType: hard
-
-"@babel/generator@npm:^7.27.5, @babel/generator@npm:^7.28.3":
-  version: 7.28.3
-  resolution: "@babel/generator@npm:7.28.3"
-  dependencies:
-    "@babel/parser": "npm:^7.28.3"
-    "@babel/types": "npm:^7.28.2"
-    "@jridgewell/gen-mapping": "npm:^0.3.12"
-    "@jridgewell/trace-mapping": "npm:^0.3.28"
-    jsesc: "npm:^3.0.2"
-  checksum: 10c0/0ff58bcf04f8803dcc29479b547b43b9b0b828ec1ee0668e92d79f9e90f388c28589056637c5ff2fd7bcf8d153c990d29c448d449d852bf9d1bc64753ca462bc
-  languageName: node
-  linkType: hard
-
-"@babel/helper-compilation-targets@npm:^7.27.2":
-  version: 7.27.2
-  resolution: "@babel/helper-compilation-targets@npm:7.27.2"
-  dependencies:
-    "@babel/compat-data": "npm:^7.27.2"
-    "@babel/helper-validator-option": "npm:^7.27.1"
-    browserslist: "npm:^4.24.0"
-    lru-cache: "npm:^5.1.1"
-    semver: "npm:^6.3.1"
-  checksum: 10c0/f338fa00dcfea931804a7c55d1a1c81b6f0a09787e528ec580d5c21b3ecb3913f6cb0f361368973ce953b824d910d3ac3e8a8ee15192710d3563826447193ad1
-  languageName: node
-  linkType: hard
-
-"@babel/helper-globals@npm:^7.28.0":
-  version: 7.28.0
-  resolution: "@babel/helper-globals@npm:7.28.0"
-  checksum: 10c0/5a0cd0c0e8c764b5f27f2095e4243e8af6fa145daea2b41b53c0c1414fe6ff139e3640f4e2207ae2b3d2153a1abd346f901c26c290ee7cb3881dd922d4ee9232
-  languageName: node
-  linkType: hard
-
-"@babel/helper-module-imports@npm:^7.27.1":
-  version: 7.27.1
-  resolution: "@babel/helper-module-imports@npm:7.27.1"
-  dependencies:
-    "@babel/traverse": "npm:^7.27.1"
-    "@babel/types": "npm:^7.27.1"
-  checksum: 10c0/e00aace096e4e29290ff8648455c2bc4ed982f0d61dbf2db1b5e750b9b98f318bf5788d75a4f974c151bd318fd549e81dbcab595f46b14b81c12eda3023f51e8
-  languageName: node
-  linkType: hard
-
-"@babel/helper-module-transforms@npm:^7.28.3":
-  version: 7.28.3
-  resolution: "@babel/helper-module-transforms@npm:7.28.3"
-  dependencies:
-    "@babel/helper-module-imports": "npm:^7.27.1"
-    "@babel/helper-validator-identifier": "npm:^7.27.1"
-    "@babel/traverse": "npm:^7.28.3"
-  peerDependencies:
-    "@babel/core": ^7.0.0
-  checksum: 10c0/549be62515a6d50cd4cfefcab1b005c47f89bd9135a22d602ee6a5e3a01f27571868ada10b75b033569f24dc4a2bb8d04bfa05ee75c16da7ade2d0db1437fcdb
-  languageName: node
-  linkType: hard
-
-"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0":
-  version: 7.27.1
-  resolution: "@babel/helper-plugin-utils@npm:7.27.1"
-  checksum: 10c0/94cf22c81a0c11a09b197b41ab488d416ff62254ce13c57e62912c85700dc2e99e555225787a4099ff6bae7a1812d622c80fbaeda824b79baa10a6c5ac4cf69b
-  languageName: node
-  linkType: hard
-
 "@babel/helper-string-parser@npm:^7.27.1":
   version: 7.27.1
   resolution: "@babel/helper-string-parser@npm:7.27.1"
@@ -123,24 +19,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/helper-validator-option@npm:^7.27.1":
-  version: 7.27.1
-  resolution: "@babel/helper-validator-option@npm:7.27.1"
-  checksum: 10c0/6fec5f006eba40001a20f26b1ef5dbbda377b7b68c8ad518c05baa9af3f396e780bdfded24c4eef95d14bb7b8fd56192a6ed38d5d439b97d10efc5f1a191d148
-  languageName: node
-  linkType: hard
-
-"@babel/helpers@npm:^7.28.4":
-  version: 7.28.4
-  resolution: "@babel/helpers@npm:7.28.4"
-  dependencies:
-    "@babel/template": "npm:^7.27.2"
-    "@babel/types": "npm:^7.28.4"
-  checksum: 10c0/aaa5fb8098926dfed5f223adf2c5e4c7fbba4b911b73dfec2d7d3083f8ba694d201a206db673da2d9b3ae8c01793e795767654558c450c8c14b4c2175b4fcb44
-  languageName: node
-  linkType: hard
-
-"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4":
+"@babel/parser@npm:^7.28.4":
   version: 7.28.4
   resolution: "@babel/parser@npm:7.28.4"
   dependencies:
@@ -151,220 +30,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/plugin-syntax-async-generators@npm:^7.8.4":
-  version: 7.8.4
-  resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-bigint@npm:^7.8.3":
-  version: 7.8.3
-  resolution: "@babel/plugin-syntax-bigint@npm:7.8.3"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/686891b81af2bc74c39013655da368a480f17dd237bf9fbc32048e5865cb706d5a8f65438030da535b332b1d6b22feba336da8fa931f663b6b34e13147d12dde
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-class-properties@npm:^7.12.13":
-  version: 7.12.13
-  resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.12.13"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-class-static-block@npm:^7.14.5":
-  version: 7.14.5
-  resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.14.5"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/4464bf9115f4a2d02ce1454411baf9cfb665af1da53709c5c56953e5e2913745b0fcce82982a00463d6facbdd93445c691024e310b91431a1e2f024b158f6371
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-import-attributes@npm:^7.24.7":
-  version: 7.27.1
-  resolution: "@babel/plugin-syntax-import-attributes@npm:7.27.1"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.27.1"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/e66f7a761b8360419bbb93ab67d87c8a97465ef4637a985ff682ce7ba6918b34b29d81190204cf908d0933058ee7b42737423cd8a999546c21b3aabad4affa9a
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-import-meta@npm:^7.10.4":
-  version: 7.10.4
-  resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.10.4"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-json-strings@npm:^7.8.3":
-  version: 7.8.3
-  resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-jsx@npm:^7.27.1":
-  version: 7.27.1
-  resolution: "@babel/plugin-syntax-jsx@npm:7.27.1"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.27.1"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/bc5afe6a458d5f0492c02a54ad98c5756a0c13bd6d20609aae65acd560a9e141b0876da5f358dce34ea136f271c1016df58b461184d7ae9c4321e0f98588bc84
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4":
-  version: 7.10.4
-  resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.10.4"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3":
-  version: 7.8.3
-  resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-numeric-separator@npm:^7.10.4":
-  version: 7.10.4
-  resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.10.4"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3":
-  version: 7.8.3
-  resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3":
-  version: 7.8.3
-  resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-optional-chaining@npm:^7.8.3":
-  version: 7.8.3
-  resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.8.0"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5":
-  version: 7.14.5
-  resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.14.5"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/69822772561706c87f0a65bc92d0772cea74d6bc0911537904a676d5ff496a6d3ac4e05a166d8125fce4a16605bace141afc3611074e170a994e66e5397787f3
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-top-level-await@npm:^7.14.5":
-  version: 7.14.5
-  resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.14.5"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f
-  languageName: node
-  linkType: hard
-
-"@babel/plugin-syntax-typescript@npm:^7.27.1":
-  version: 7.27.1
-  resolution: "@babel/plugin-syntax-typescript@npm:7.27.1"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.27.1"
-  peerDependencies:
-    "@babel/core": ^7.0.0-0
-  checksum: 10c0/11589b4c89c66ef02d57bf56c6246267851ec0c361f58929327dc3e070b0dab644be625bbe7fb4c4df30c3634bfdfe31244e1f517be397d2def1487dbbe3c37d
-  languageName: node
-  linkType: hard
-
-"@babel/template@npm:^7.27.2":
-  version: 7.27.2
-  resolution: "@babel/template@npm:7.27.2"
-  dependencies:
-    "@babel/code-frame": "npm:^7.27.1"
-    "@babel/parser": "npm:^7.27.2"
-    "@babel/types": "npm:^7.27.1"
-  checksum: 10c0/ed9e9022651e463cc5f2cc21942f0e74544f1754d231add6348ff1b472985a3b3502041c0be62dc99ed2d12cfae0c51394bf827452b98a2f8769c03b87aadc81
-  languageName: node
-  linkType: hard
-
-"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4":
-  version: 7.28.4
-  resolution: "@babel/traverse@npm:7.28.4"
-  dependencies:
-    "@babel/code-frame": "npm:^7.27.1"
-    "@babel/generator": "npm:^7.28.3"
-    "@babel/helper-globals": "npm:^7.28.0"
-    "@babel/parser": "npm:^7.28.4"
-    "@babel/template": "npm:^7.27.2"
-    "@babel/types": "npm:^7.28.4"
-    debug: "npm:^4.3.1"
-  checksum: 10c0/ee678fdd49c9f54a32e07e8455242390d43ce44887cea6567b233fe13907b89240c377e7633478a32c6cf1be0e17c2f7f3b0c59f0666e39c5074cc47b968489c
-  languageName: node
-  linkType: hard
-
-"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4":
+"@babel/types@npm:^7.28.4":
   version: 7.28.4
   resolution: "@babel/types@npm:7.28.4"
   dependencies:
@@ -374,13 +40,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@bcoe/v8-coverage@npm:^0.2.3":
-  version: 0.2.3
-  resolution: "@bcoe/v8-coverage@npm:0.2.3"
-  checksum: 10c0/6b80ae4cb3db53f486da2dc63b6e190a74c8c3cca16bb2733f234a0b6a9382b09b146488ae08e2b22cf00f6c83e20f3e040a2f7894f05c045c946d6a090b1d52
-  languageName: node
-  linkType: hard
-
 "@cspotcode/source-map-support@npm:^0.8.0":
   version: 0.8.1
   resolution: "@cspotcode/source-map-support@npm:0.8.1"
@@ -390,34 +49,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@emnapi/core@npm:^1.4.3":
-  version: 1.5.0
-  resolution: "@emnapi/core@npm:1.5.0"
-  dependencies:
-    "@emnapi/wasi-threads": "npm:1.1.0"
-    tslib: "npm:^2.4.0"
-  checksum: 10c0/52ba3485277706d92fa27d92b37e5b4f6ef0742c03ed68f8096f294c6bfa30f0752c82d4c2bfa14bff4dc30d63c9f71a8f9fb64a92743d00807d9e468fafd5ff
-  languageName: node
-  linkType: hard
-
-"@emnapi/runtime@npm:^1.4.3":
-  version: 1.5.0
-  resolution: "@emnapi/runtime@npm:1.5.0"
-  dependencies:
-    tslib: "npm:^2.4.0"
-  checksum: 10c0/a85c9fc4e3af49cbe41e5437e5be2551392a931910cd0a5b5d3572532786927810c9cc1db11b232ec8f9657b33d4e6f7c4f985f1a052917d7cd703b5b2a20faa
-  languageName: node
-  linkType: hard
-
-"@emnapi/wasi-threads@npm:1.1.0":
-  version: 1.1.0
-  resolution: "@emnapi/wasi-threads@npm:1.1.0"
-  dependencies:
-    tslib: "npm:^2.4.0"
-  checksum: 10c0/e6d54bf2b1e64cdd83d2916411e44e579b6ae35d5def0dea61a3c452d9921373044dff32a8b8473ae60c80692bdc39323e98b96a3f3d87ba6886b24dd0ef7ca1
-  languageName: node
-  linkType: hard
-
 "@esbuild/aix-ppc64@npm:0.25.10":
   version: 0.25.10
   resolution: "@esbuild/aix-ppc64@npm:0.25.10"
@@ -771,320 +402,14 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@istanbuljs/load-nyc-config@npm:^1.0.0":
-  version: 1.1.0
-  resolution: "@istanbuljs/load-nyc-config@npm:1.1.0"
-  dependencies:
-    camelcase: "npm:^5.3.1"
-    find-up: "npm:^4.1.0"
-    get-package-type: "npm:^0.1.0"
-    js-yaml: "npm:^3.13.1"
-    resolve-from: "npm:^5.0.0"
-  checksum: 10c0/dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42
-  languageName: node
-  linkType: hard
-
-"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3":
-  version: 0.1.3
-  resolution: "@istanbuljs/schema@npm:0.1.3"
-  checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a
-  languageName: node
-  linkType: hard
-
-"@jest/console@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/console@npm:30.2.0"
-  dependencies:
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    chalk: "npm:^4.1.2"
-    jest-message-util: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-  checksum: 10c0/ecf7ca43698863095500710a5aa08c38b1731c9d89ba32f4d9da7424b53ce1e86b3db8ccbbb27b695f49b4f94bc1d7d0c63c751d73c83d59488a682bc98b7e70
-  languageName: node
-  linkType: hard
-
-"@jest/core@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/core@npm:30.2.0"
-  dependencies:
-    "@jest/console": "npm:30.2.0"
-    "@jest/pattern": "npm:30.0.1"
-    "@jest/reporters": "npm:30.2.0"
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/transform": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    ansi-escapes: "npm:^4.3.2"
-    chalk: "npm:^4.1.2"
-    ci-info: "npm:^4.2.0"
-    exit-x: "npm:^0.2.2"
-    graceful-fs: "npm:^4.2.11"
-    jest-changed-files: "npm:30.2.0"
-    jest-config: "npm:30.2.0"
-    jest-haste-map: "npm:30.2.0"
-    jest-message-util: "npm:30.2.0"
-    jest-regex-util: "npm:30.0.1"
-    jest-resolve: "npm:30.2.0"
-    jest-resolve-dependencies: "npm:30.2.0"
-    jest-runner: "npm:30.2.0"
-    jest-runtime: "npm:30.2.0"
-    jest-snapshot: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    jest-validate: "npm:30.2.0"
-    jest-watcher: "npm:30.2.0"
-    micromatch: "npm:^4.0.8"
-    pretty-format: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-  peerDependencies:
-    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-  peerDependenciesMeta:
-    node-notifier:
-      optional: true
-  checksum: 10c0/03b3e35df3bbbbe28e2b53c0fe82d39b748d99b3bc88bb645c76593cdca44d7115f03ef6e6a1715f0862151d0ebab496199283def248fc05eb520f6aec6b20f3
-  languageName: node
-  linkType: hard
-
-"@jest/diff-sequences@npm:30.0.1":
-  version: 30.0.1
-  resolution: "@jest/diff-sequences@npm:30.0.1"
-  checksum: 10c0/3a840404e6021725ef7f86b11f7b2d13dd02846481264db0e447ee33b7ee992134e402cdc8b8b0ac969d37c6c0183044e382dedee72001cdf50cfb3c8088de74
-  languageName: node
-  linkType: hard
-
-"@jest/environment@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/environment@npm:30.2.0"
-  dependencies:
-    "@jest/fake-timers": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    jest-mock: "npm:30.2.0"
-  checksum: 10c0/56a9f1b82ee2623c13eece7d58188be35bd6e5c3c4ee3fbaedb1c4d7242c1b57d020f1a26ab127fa9496fdc11306c7ad1c4a2b7eba1fc726a27ae0873e907e47
-  languageName: node
-  linkType: hard
-
-"@jest/expect-utils@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/expect-utils@npm:30.2.0"
-  dependencies:
-    "@jest/get-type": "npm:30.1.0"
-  checksum: 10c0/e25a809ff2ab62292e2569f8d97f89168d27d078903f0306af5f70f1771b7efc62c458eca1dcb491ab1ed96cefedf403bd7acbb050c997105bc29b220fd9d61a
-  languageName: node
-  linkType: hard
-
-"@jest/expect@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/expect@npm:30.2.0"
-  dependencies:
-    expect: "npm:30.2.0"
-    jest-snapshot: "npm:30.2.0"
-  checksum: 10c0/3984879022780dd480301c560cef465156b29d610f2c698fcdf81ad76930411d7816eff7cb721e81a1d9aaa8c2240a73c20be9385d1978c14b405a2ac6c9104a
-  languageName: node
-  linkType: hard
-
-"@jest/fake-timers@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/fake-timers@npm:30.2.0"
-  dependencies:
-    "@jest/types": "npm:30.2.0"
-    "@sinonjs/fake-timers": "npm:^13.0.0"
-    "@types/node": "npm:*"
-    jest-message-util: "npm:30.2.0"
-    jest-mock: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-  checksum: 10c0/b29505528e546f08489535814f7dfcd3a2318660b987d605f44d41672e91a0c8c0dfc01e3dd1302e66e511409c3012d41e2e16703b214502b54ccc023773e3dc
-  languageName: node
-  linkType: hard
-
-"@jest/get-type@npm:30.1.0":
-  version: 30.1.0
-  resolution: "@jest/get-type@npm:30.1.0"
-  checksum: 10c0/3e65fd5015f551c51ec68fca31bbd25b466be0e8ee8075d9610fa1c686ea1e70a942a0effc7b10f4ea9a338c24337e1ad97ff69d3ebacc4681b7e3e80d1b24ac
-  languageName: node
-  linkType: hard
-
-"@jest/globals@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/globals@npm:30.2.0"
-  dependencies:
-    "@jest/environment": "npm:30.2.0"
-    "@jest/expect": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    jest-mock: "npm:30.2.0"
-  checksum: 10c0/7433a501e3122e94b24a7bacc44fdc3921b20abf67c9d795f5bdd169f1beac058cff8109e4fddf71fdc8b18e532cb88c55412ca9927966f354930d6bb3fcaf9c
-  languageName: node
-  linkType: hard
-
-"@jest/pattern@npm:30.0.1":
-  version: 30.0.1
-  resolution: "@jest/pattern@npm:30.0.1"
-  dependencies:
-    "@types/node": "npm:*"
-    jest-regex-util: "npm:30.0.1"
-  checksum: 10c0/32c5a7bfb6c591f004dac0ed36d645002ed168971e4c89bd915d1577031672870032594767557b855c5bc330aa1e39a2f54bf150d2ee88a7a0886e9cb65318bc
-  languageName: node
-  linkType: hard
-
-"@jest/reporters@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/reporters@npm:30.2.0"
-  dependencies:
-    "@bcoe/v8-coverage": "npm:^0.2.3"
-    "@jest/console": "npm:30.2.0"
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/transform": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@jridgewell/trace-mapping": "npm:^0.3.25"
-    "@types/node": "npm:*"
-    chalk: "npm:^4.1.2"
-    collect-v8-coverage: "npm:^1.0.2"
-    exit-x: "npm:^0.2.2"
-    glob: "npm:^10.3.10"
-    graceful-fs: "npm:^4.2.11"
-    istanbul-lib-coverage: "npm:^3.0.0"
-    istanbul-lib-instrument: "npm:^6.0.0"
-    istanbul-lib-report: "npm:^3.0.0"
-    istanbul-lib-source-maps: "npm:^5.0.0"
-    istanbul-reports: "npm:^3.1.3"
-    jest-message-util: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    jest-worker: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-    string-length: "npm:^4.0.2"
-    v8-to-istanbul: "npm:^9.0.1"
-  peerDependencies:
-    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-  peerDependenciesMeta:
-    node-notifier:
-      optional: true
-  checksum: 10c0/1f25d0896f857f220466cae3145a20f9e13e7d73aeccf87a1f8a5accb42bb7a564864ba63befa3494d76d1335b86c24d66054d62330c3dcffc9c2c5f4e740d6e
-  languageName: node
-  linkType: hard
-
-"@jest/schemas@npm:30.0.5":
-  version: 30.0.5
-  resolution: "@jest/schemas@npm:30.0.5"
-  dependencies:
-    "@sinclair/typebox": "npm:^0.34.0"
-  checksum: 10c0/449dcd7ec5c6505e9ac3169d1143937e67044ae3e66a729ce4baf31812dfd30535f2b3b2934393c97cfdf5984ff581120e6b38f62b8560c8b5b7cc07f4175f65
-  languageName: node
-  linkType: hard
-
-"@jest/snapshot-utils@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/snapshot-utils@npm:30.2.0"
-  dependencies:
-    "@jest/types": "npm:30.2.0"
-    chalk: "npm:^4.1.2"
-    graceful-fs: "npm:^4.2.11"
-    natural-compare: "npm:^1.4.0"
-  checksum: 10c0/df69ee3b95d64db6d1e79e39d5dc226e417b412a1d5113264b487eb3a8887366a7952c350c378e2292f8e83ec1b3be22040317b795e85eb431830cbde06d09d8
-  languageName: node
-  linkType: hard
-
-"@jest/source-map@npm:30.0.1":
-  version: 30.0.1
-  resolution: "@jest/source-map@npm:30.0.1"
-  dependencies:
-    "@jridgewell/trace-mapping": "npm:^0.3.25"
-    callsites: "npm:^3.1.0"
-    graceful-fs: "npm:^4.2.11"
-  checksum: 10c0/e7bda2786fc9f483d9dd7566c58c4bd948830997be862dfe80a3ae5550ff3f84753abb52e705d02ebe9db9f34ba7ebec4c2db11882048cdeef7a66f6332b3897
-  languageName: node
-  linkType: hard
-
-"@jest/test-result@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/test-result@npm:30.2.0"
-  dependencies:
-    "@jest/console": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/istanbul-lib-coverage": "npm:^2.0.6"
-    collect-v8-coverage: "npm:^1.0.2"
-  checksum: 10c0/87566d56b4f90630282c103f41ea9031f4647902f2cd9839bc49af6248301c1a95cbc4432a9512e61f6c6d778e8b925d0573588b26a211d3198c62471ba08c81
-  languageName: node
-  linkType: hard
-
-"@jest/test-sequencer@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/test-sequencer@npm:30.2.0"
-  dependencies:
-    "@jest/test-result": "npm:30.2.0"
-    graceful-fs: "npm:^4.2.11"
-    jest-haste-map: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-  checksum: 10c0/b8366e629b885bfc4b2b95f34f47405e70120eb8601f42de20ea4de308a5088d7bd9f535abf67a2a0d083a2b49864176e1333e036426a5d6b6bd02c1c4dda40b
-  languageName: node
-  linkType: hard
-
-"@jest/transform@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/transform@npm:30.2.0"
-  dependencies:
-    "@babel/core": "npm:^7.27.4"
-    "@jest/types": "npm:30.2.0"
-    "@jridgewell/trace-mapping": "npm:^0.3.25"
-    babel-plugin-istanbul: "npm:^7.0.1"
-    chalk: "npm:^4.1.2"
-    convert-source-map: "npm:^2.0.0"
-    fast-json-stable-stringify: "npm:^2.1.0"
-    graceful-fs: "npm:^4.2.11"
-    jest-haste-map: "npm:30.2.0"
-    jest-regex-util: "npm:30.0.1"
-    jest-util: "npm:30.2.0"
-    micromatch: "npm:^4.0.8"
-    pirates: "npm:^4.0.7"
-    slash: "npm:^3.0.0"
-    write-file-atomic: "npm:^5.0.1"
-  checksum: 10c0/c0f21576de9f7ad8a2647450b5cd127d7c60176c19a666230241d121b9f928b036dd19973363e4acd7db2f8b82caff2b624930f57471be6092d73a7775365606
-  languageName: node
-  linkType: hard
-
-"@jest/types@npm:30.2.0":
-  version: 30.2.0
-  resolution: "@jest/types@npm:30.2.0"
-  dependencies:
-    "@jest/pattern": "npm:30.0.1"
-    "@jest/schemas": "npm:30.0.5"
-    "@types/istanbul-lib-coverage": "npm:^2.0.6"
-    "@types/istanbul-reports": "npm:^3.0.4"
-    "@types/node": "npm:*"
-    "@types/yargs": "npm:^17.0.33"
-    chalk: "npm:^4.1.2"
-  checksum: 10c0/ae121f6963bd9ed1cd9651db7be91bf14c05bff0d0eec4fca9fecf586bea4005e8f1de8cc9b8ef72e424ea96a309d123bef510b55a6a17a3b4b91a39d775e5cd
-  languageName: node
-  linkType: hard
-
-"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5":
-  version: 0.3.13
-  resolution: "@jridgewell/gen-mapping@npm:0.3.13"
-  dependencies:
-    "@jridgewell/sourcemap-codec": "npm:^1.5.0"
-    "@jridgewell/trace-mapping": "npm:^0.3.24"
-  checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b
-  languageName: node
-  linkType: hard
-
-"@jridgewell/remapping@npm:^2.3.5":
-  version: 2.3.5
-  resolution: "@jridgewell/remapping@npm:2.3.5"
-  dependencies:
-    "@jridgewell/gen-mapping": "npm:^0.3.5"
-    "@jridgewell/trace-mapping": "npm:^0.3.24"
-  checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194
-  languageName: node
-  linkType: hard
-
-"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0":
+"@jridgewell/resolve-uri@npm:^3.0.3":
   version: 3.1.2
   resolution: "@jridgewell/resolve-uri@npm:3.1.2"
   checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e
   languageName: node
   linkType: hard
 
-"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5":
+"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.5.5":
   version: 1.5.5
   resolution: "@jridgewell/sourcemap-codec@npm:1.5.5"
   checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0
@@ -1101,16 +426,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28":
-  version: 0.3.31
-  resolution: "@jridgewell/trace-mapping@npm:0.3.31"
-  dependencies:
-    "@jridgewell/resolve-uri": "npm:^3.1.0"
-    "@jridgewell/sourcemap-codec": "npm:^1.4.14"
-  checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9
-  languageName: node
-  linkType: hard
-
 "@microsoft/api-extractor-model@npm:7.31.0":
   version: 7.31.0
   resolution: "@microsoft/api-extractor-model@npm:7.31.0"
@@ -1164,17 +479,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@napi-rs/wasm-runtime@npm:^0.2.11":
-  version: 0.2.12
-  resolution: "@napi-rs/wasm-runtime@npm:0.2.12"
-  dependencies:
-    "@emnapi/core": "npm:^1.4.3"
-    "@emnapi/runtime": "npm:^1.4.3"
-    "@tybys/wasm-util": "npm:^0.10.0"
-  checksum: 10c0/6d07922c0613aab30c6a497f4df297ca7c54e5b480e00035e0209b872d5c6aab7162fc49477267556109c2c7ed1eb9c65a174e27e9b87568106a87b0a6e3ca7d
-  languageName: node
-  linkType: hard
-
 "@nodelib/fs.scandir@npm:2.1.5":
   version: 2.1.5
   resolution: "@nodelib/fs.scandir@npm:2.1.5"
@@ -1253,13 +557,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@pkgr/core@npm:^0.2.9":
-  version: 0.2.9
-  resolution: "@pkgr/core@npm:0.2.9"
-  checksum: 10c0/ac8e4e8138b1a7a4ac6282873aef7389c352f1f8b577b4850778f5182e4a39a5241facbe48361fec817f56d02b51691b383010843fb08b34a8e8ea3614688fd5
-  languageName: node
-  linkType: hard
-
 "@rollup/pluginutils@npm:^5.1.4":
   version: 5.3.0
   resolution: "@rollup/pluginutils@npm:5.3.0"
@@ -1553,31 +850,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@sinclair/typebox@npm:^0.34.0":
-  version: 0.34.41
-  resolution: "@sinclair/typebox@npm:0.34.41"
-  checksum: 10c0/0fb61fc2f90c25e30b19b0096eb8ab3ccef401d3e2acfce42168ff0ee877ba5981c8243fa6b1035ac756cde95316724e978b2837dd642d7e4e095de03a999c90
-  languageName: node
-  linkType: hard
-
-"@sinonjs/commons@npm:^3.0.1":
-  version: 3.0.1
-  resolution: "@sinonjs/commons@npm:3.0.1"
-  dependencies:
-    type-detect: "npm:4.0.8"
-  checksum: 10c0/1227a7b5bd6c6f9584274db996d7f8cee2c8c350534b9d0141fc662eaf1f292ea0ae3ed19e5e5271c8fd390d27e492ca2803acd31a1978be2cdc6be0da711403
-  languageName: node
-  linkType: hard
-
-"@sinonjs/fake-timers@npm:^13.0.0":
-  version: 13.0.5
-  resolution: "@sinonjs/fake-timers@npm:13.0.5"
-  dependencies:
-    "@sinonjs/commons": "npm:^3.0.1"
-  checksum: 10c0/a707476efd523d2138ef6bba916c83c4a377a8372ef04fad87499458af9f01afc58f4f245c5fd062793d6d70587309330c6f96947b5bd5697961c18004dc3e26
-  languageName: node
-  linkType: hard
-
 "@tsconfig/node10@npm:^1.0.7":
   version: 1.0.11
   resolution: "@tsconfig/node10@npm:1.0.11"
@@ -1606,15 +878,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@tybys/wasm-util@npm:^0.10.0":
-  version: 0.10.1
-  resolution: "@tybys/wasm-util@npm:0.10.1"
-  dependencies:
-    tslib: "npm:^2.4.0"
-  checksum: 10c0/b255094f293794c6d2289300c5fbcafbb5532a3aed3a5ffd2f8dc1828e639b88d75f6a376dd8f94347a44813fd7a7149d8463477a9a49525c8b2dcaa38c2d1e8
-  languageName: node
-  linkType: hard
-
 "@types/argparse@npm:1.0.38":
   version: 1.0.38
   resolution: "@types/argparse@npm:1.0.38"
@@ -1622,47 +885,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/babel__core@npm:^7.20.5":
-  version: 7.20.5
-  resolution: "@types/babel__core@npm:7.20.5"
-  dependencies:
-    "@babel/parser": "npm:^7.20.7"
-    "@babel/types": "npm:^7.20.7"
-    "@types/babel__generator": "npm:*"
-    "@types/babel__template": "npm:*"
-    "@types/babel__traverse": "npm:*"
-  checksum: 10c0/bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff
-  languageName: node
-  linkType: hard
-
-"@types/babel__generator@npm:*":
-  version: 7.27.0
-  resolution: "@types/babel__generator@npm:7.27.0"
-  dependencies:
-    "@babel/types": "npm:^7.0.0"
-  checksum: 10c0/9f9e959a8792df208a9d048092fda7e1858bddc95c6314857a8211a99e20e6830bdeb572e3587ae8be5429e37f2a96fcf222a9f53ad232f5537764c9e13a2bbd
-  languageName: node
-  linkType: hard
-
-"@types/babel__template@npm:*":
-  version: 7.4.4
-  resolution: "@types/babel__template@npm:7.4.4"
-  dependencies:
-    "@babel/parser": "npm:^7.1.0"
-    "@babel/types": "npm:^7.0.0"
-  checksum: 10c0/cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b
-  languageName: node
-  linkType: hard
-
-"@types/babel__traverse@npm:*":
-  version: 7.28.0
-  resolution: "@types/babel__traverse@npm:7.28.0"
-  dependencies:
-    "@babel/types": "npm:^7.28.2"
-  checksum: 10c0/b52d7d4e8fc6a9018fe7361c4062c1c190f5778cf2466817cb9ed19d69fbbb54f9a85ffedeb748ed8062d2cf7d4cc088ee739848f47c57740de1c48cbf0d0994
-  languageName: node
-  linkType: hard
-
 "@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
   version: 1.0.8
   resolution: "@types/estree@npm:1.0.8"
@@ -1679,41 +901,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6":
-  version: 2.0.6
-  resolution: "@types/istanbul-lib-coverage@npm:2.0.6"
-  checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7
-  languageName: node
-  linkType: hard
-
-"@types/istanbul-lib-report@npm:*":
-  version: 3.0.3
-  resolution: "@types/istanbul-lib-report@npm:3.0.3"
-  dependencies:
-    "@types/istanbul-lib-coverage": "npm:*"
-  checksum: 10c0/247e477bbc1a77248f3c6de5dadaae85ff86ac2d76c5fc6ab1776f54512a745ff2a5f791d22b942e3990ddbd40f3ef5289317c4fca5741bedfaa4f01df89051c
-  languageName: node
-  linkType: hard
-
-"@types/istanbul-reports@npm:^3.0.4":
-  version: 3.0.4
-  resolution: "@types/istanbul-reports@npm:3.0.4"
-  dependencies:
-    "@types/istanbul-lib-report": "npm:*"
-  checksum: 10c0/1647fd402aced5b6edac87274af14ebd6b3a85447ef9ad11853a70fd92a98d35f81a5d3ea9fcb5dbb5834e800c6e35b64475e33fcae6bfa9acc70d61497c54ee
-  languageName: node
-  linkType: hard
-
-"@types/jest@npm:^30.0.0":
-  version: 30.0.0
-  resolution: "@types/jest@npm:30.0.0"
-  dependencies:
-    expect: "npm:^30.0.0"
-    pretty-format: "npm:^30.0.0"
-  checksum: 10c0/20c6ce574154bc16f8dd6a97afacca4b8c4921a819496a3970382031c509ebe87a1b37b152a1b8475089b82d8ca951a9e95beb4b9bf78fbf579b1536f0b65969
-  languageName: node
-  linkType: hard
-
 "@types/json-schema@npm:^7.0.15":
   version: 7.0.15
   resolution: "@types/json-schema@npm:7.0.15"
@@ -1728,7 +915,14 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/node@npm:*, @types/node@npm:^24.6.2":
+"@types/mocha@npm:^10.0.10":
+  version: 10.0.10
+  resolution: "@types/mocha@npm:10.0.10"
+  checksum: 10c0/d2b8c48138cde6923493e42b38e839695eb42edd04629abe480a8f34c0e3f50dd82a55832c2e8d2b6e6f9e4deb492d7d733e600fbbdd5a0ceccbcfc6844ff9d5
+  languageName: node
+  linkType: hard
+
+"@types/node@npm:^24.6.2":
   version: 24.6.2
   resolution: "@types/node@npm:24.6.2"
   dependencies:
@@ -1737,13 +931,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/stack-utils@npm:^2.0.3":
-  version: 2.0.3
-  resolution: "@types/stack-utils@npm:2.0.3"
-  checksum: 10c0/1f4658385ae936330581bcb8aa3a066df03867d90281cdf89cc356d404bd6579be0f11902304e1f775d92df22c6dd761d4451c804b0a4fba973e06211e9bd77c
-  languageName: node
-  linkType: hard
-
 "@types/unist@npm:*":
   version: 3.0.3
   resolution: "@types/unist@npm:3.0.3"
@@ -1751,22 +938,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/yargs-parser@npm:*":
-  version: 21.0.3
-  resolution: "@types/yargs-parser@npm:21.0.3"
-  checksum: 10c0/e71c3bd9d0b73ca82e10bee2064c384ab70f61034bbfb78e74f5206283fc16a6d85267b606b5c22cb2a3338373586786fed595b2009825d6a9115afba36560a0
-  languageName: node
-  linkType: hard
-
-"@types/yargs@npm:^17.0.33":
-  version: 17.0.33
-  resolution: "@types/yargs@npm:17.0.33"
-  dependencies:
-    "@types/yargs-parser": "npm:*"
-  checksum: 10c0/d16937d7ac30dff697801c3d6f235be2166df42e4a88bf730fa6dc09201de3727c0a9500c59a672122313341de5f24e45ee0ff579c08ce91928e519090b7906b
-  languageName: node
-  linkType: hard
-
 "@typescript-eslint/eslint-plugin@npm:8.46.0":
   version: 8.46.0
   resolution: "@typescript-eslint/eslint-plugin@npm:8.46.0"
@@ -1804,245 +975,103 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@typescript-eslint/project-service@npm:8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/project-service@npm:8.46.0"
-  dependencies:
-    "@typescript-eslint/tsconfig-utils": "npm:^8.46.0"
-    "@typescript-eslint/types": "npm:^8.46.0"
-    debug: "npm:^4.3.4"
-  peerDependencies:
-    typescript: ">=4.8.4 <6.0.0"
-  checksum: 10c0/c3164c795570edfa141917f3099724eca70383b016be1b08f656a491b459d68cf8e2547ac416d75048d3511ca5feaea0586aabad339e3dfe2ae6fddb650d7bc8
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/scope-manager@npm:8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/scope-manager@npm:8.46.0"
-  dependencies:
-    "@typescript-eslint/types": "npm:8.46.0"
-    "@typescript-eslint/visitor-keys": "npm:8.46.0"
-  checksum: 10c0/9c242d1edd51247559f99dd8986bdb571db0a2a583a2d02ee8f5f346d265e956f413b442c27e1b02d55ce3944609f6593050ec657be672d9b24b7ed0a359a6ad
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/tsconfig-utils@npm:8.46.0, @typescript-eslint/tsconfig-utils@npm:^8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.0"
-  peerDependencies:
-    typescript: ">=4.8.4 <6.0.0"
-  checksum: 10c0/306b27c741709f2435dd1c7eabdf552775dff1b3ced01d791c5b9755394ceb3f37c9bcceec92adb6fe60c622523f9d47d9b0d9e515071f47d50527705a4706f7
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/type-utils@npm:8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/type-utils@npm:8.46.0"
-  dependencies:
-    "@typescript-eslint/types": "npm:8.46.0"
-    "@typescript-eslint/typescript-estree": "npm:8.46.0"
-    "@typescript-eslint/utils": "npm:8.46.0"
-    debug: "npm:^4.3.4"
-    ts-api-utils: "npm:^2.1.0"
-  peerDependencies:
-    eslint: ^8.57.0 || ^9.0.0
-    typescript: ">=4.8.4 <6.0.0"
-  checksum: 10c0/a0fa4617a998094bc217be1989b76a3e45c058117cda027a723ff6f98f15e5237abfa123284afbdea7f320b4da65e1053ed47c8a211dd012591908a9daa46f02
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/types@npm:8.46.0, @typescript-eslint/types@npm:^8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/types@npm:8.46.0"
-  checksum: 10c0/2f986852139bcbe940b4aafe79bbd28dcca7176e95ba4e3880984ef58c81ad077ca9d9191aad56d2b1df6d16060f5744a96ab3118ddbc9766e5035ed470445c1
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/typescript-estree@npm:8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/typescript-estree@npm:8.46.0"
-  dependencies:
-    "@typescript-eslint/project-service": "npm:8.46.0"
-    "@typescript-eslint/tsconfig-utils": "npm:8.46.0"
-    "@typescript-eslint/types": "npm:8.46.0"
-    "@typescript-eslint/visitor-keys": "npm:8.46.0"
-    debug: "npm:^4.3.4"
-    fast-glob: "npm:^3.3.2"
-    is-glob: "npm:^4.0.3"
-    minimatch: "npm:^9.0.4"
-    semver: "npm:^7.6.0"
-    ts-api-utils: "npm:^2.1.0"
-  peerDependencies:
-    typescript: ">=4.8.4 <6.0.0"
-  checksum: 10c0/39aed033dc23c3356e39891c9eba6dde0dc618406f0e13e9adc5967fb81790ec199b1d6eb1144e35ad13a0daaf72157f5f3fc7ac1b7c58d152ade68fe27ad221
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/utils@npm:8.46.0, @typescript-eslint/utils@npm:^8.0.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/utils@npm:8.46.0"
-  dependencies:
-    "@eslint-community/eslint-utils": "npm:^4.7.0"
-    "@typescript-eslint/scope-manager": "npm:8.46.0"
-    "@typescript-eslint/types": "npm:8.46.0"
-    "@typescript-eslint/typescript-estree": "npm:8.46.0"
-  peerDependencies:
-    eslint: ^8.57.0 || ^9.0.0
-    typescript: ">=4.8.4 <6.0.0"
-  checksum: 10c0/77cc7dff9132d9f02e8766d128edbeb7c2f2b56f9ebdac7308e75a04924e2369857da27b23f0054476c9640609a9707b8dd8ca8b1c59a067e45f65bf5ef4cc1b
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/visitor-keys@npm:8.46.0":
-  version: 8.46.0
-  resolution: "@typescript-eslint/visitor-keys@npm:8.46.0"
-  dependencies:
-    "@typescript-eslint/types": "npm:8.46.0"
-    eslint-visitor-keys: "npm:^4.2.1"
-  checksum: 10c0/473dd4861b81238c1df10008b3b6d4684b2fa5ec4f3a8eeb544ea1278a5e2119f839447d16653ea3070164d7e742e3516fe9b0faf16e12a457fa26d5e14a7498
-  languageName: node
-  linkType: hard
-
-"@ungap/structured-clone@npm:^1.3.0":
-  version: 1.3.0
-  resolution: "@ungap/structured-clone@npm:1.3.0"
-  checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1"
-  conditions: os=android & cpu=arm
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-android-arm64@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1"
-  conditions: os=android & cpu=arm64
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-darwin-arm64@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1"
-  conditions: os=darwin & cpu=arm64
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-darwin-x64@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1"
-  conditions: os=darwin & cpu=x64
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-freebsd-x64@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1"
-  conditions: os=freebsd & cpu=x64
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1"
-  conditions: os=linux & cpu=arm
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1"
-  conditions: os=linux & cpu=arm
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1"
-  conditions: os=linux & cpu=arm64 & libc=glibc
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1"
-  conditions: os=linux & cpu=arm64 & libc=musl
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1"
-  conditions: os=linux & cpu=ppc64 & libc=glibc
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1"
-  conditions: os=linux & cpu=riscv64 & libc=glibc
+"@typescript-eslint/project-service@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/project-service@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/tsconfig-utils": "npm:^8.46.0"
+    "@typescript-eslint/types": "npm:^8.46.0"
+    debug: "npm:^4.3.4"
+  peerDependencies:
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/c3164c795570edfa141917f3099724eca70383b016be1b08f656a491b459d68cf8e2547ac416d75048d3511ca5feaea0586aabad339e3dfe2ae6fddb650d7bc8
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1"
-  conditions: os=linux & cpu=riscv64 & libc=musl
+"@typescript-eslint/scope-manager@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/scope-manager@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/visitor-keys": "npm:8.46.0"
+  checksum: 10c0/9c242d1edd51247559f99dd8986bdb571db0a2a583a2d02ee8f5f346d265e956f413b442c27e1b02d55ce3944609f6593050ec657be672d9b24b7ed0a359a6ad
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1"
-  conditions: os=linux & cpu=s390x & libc=glibc
+"@typescript-eslint/tsconfig-utils@npm:8.46.0, @typescript-eslint/tsconfig-utils@npm:^8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.0"
+  peerDependencies:
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/306b27c741709f2435dd1c7eabdf552775dff1b3ced01d791c5b9755394ceb3f37c9bcceec92adb6fe60c622523f9d47d9b0d9e515071f47d50527705a4706f7
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1"
-  conditions: os=linux & cpu=x64 & libc=glibc
+"@typescript-eslint/type-utils@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/type-utils@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/typescript-estree": "npm:8.46.0"
+    "@typescript-eslint/utils": "npm:8.46.0"
+    debug: "npm:^4.3.4"
+    ts-api-utils: "npm:^2.1.0"
+  peerDependencies:
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/a0fa4617a998094bc217be1989b76a3e45c058117cda027a723ff6f98f15e5237abfa123284afbdea7f320b4da65e1053ed47c8a211dd012591908a9daa46f02
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1"
-  conditions: os=linux & cpu=x64 & libc=musl
+"@typescript-eslint/types@npm:8.46.0, @typescript-eslint/types@npm:^8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/types@npm:8.46.0"
+  checksum: 10c0/2f986852139bcbe940b4aafe79bbd28dcca7176e95ba4e3880984ef58c81ad077ca9d9191aad56d2b1df6d16060f5744a96ab3118ddbc9766e5035ed470445c1
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1"
+"@typescript-eslint/typescript-estree@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/typescript-estree@npm:8.46.0"
   dependencies:
-    "@napi-rs/wasm-runtime": "npm:^0.2.11"
-  conditions: cpu=wasm32
-  languageName: node
-  linkType: hard
-
-"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1"
-  conditions: os=win32 & cpu=arm64
+    "@typescript-eslint/project-service": "npm:8.46.0"
+    "@typescript-eslint/tsconfig-utils": "npm:8.46.0"
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/visitor-keys": "npm:8.46.0"
+    debug: "npm:^4.3.4"
+    fast-glob: "npm:^3.3.2"
+    is-glob: "npm:^4.0.3"
+    minimatch: "npm:^9.0.4"
+    semver: "npm:^7.6.0"
+    ts-api-utils: "npm:^2.1.0"
+  peerDependencies:
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/39aed033dc23c3356e39891c9eba6dde0dc618406f0e13e9adc5967fb81790ec199b1d6eb1144e35ad13a0daaf72157f5f3fc7ac1b7c58d152ade68fe27ad221
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1"
-  conditions: os=win32 & cpu=ia32
+"@typescript-eslint/utils@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/utils@npm:8.46.0"
+  dependencies:
+    "@eslint-community/eslint-utils": "npm:^4.7.0"
+    "@typescript-eslint/scope-manager": "npm:8.46.0"
+    "@typescript-eslint/types": "npm:8.46.0"
+    "@typescript-eslint/typescript-estree": "npm:8.46.0"
+  peerDependencies:
+    eslint: ^8.57.0 || ^9.0.0
+    typescript: ">=4.8.4 <6.0.0"
+  checksum: 10c0/77cc7dff9132d9f02e8766d128edbeb7c2f2b56f9ebdac7308e75a04924e2369857da27b23f0054476c9640609a9707b8dd8ca8b1c59a067e45f65bf5ef4cc1b
   languageName: node
   linkType: hard
 
-"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1":
-  version: 1.11.1
-  resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1"
-  conditions: os=win32 & cpu=x64
+"@typescript-eslint/visitor-keys@npm:8.46.0":
+  version: 8.46.0
+  resolution: "@typescript-eslint/visitor-keys@npm:8.46.0"
+  dependencies:
+    "@typescript-eslint/types": "npm:8.46.0"
+    eslint-visitor-keys: "npm:^4.2.1"
+  checksum: 10c0/473dd4861b81238c1df10008b3b6d4684b2fa5ec4f3a8eeb544ea1278a5e2119f839447d16653ea3070164d7e742e3516fe9b0faf16e12a457fa26d5e14a7498
   languageName: node
   linkType: hard
 
@@ -2303,15 +1332,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ansi-escapes@npm:^4.3.2":
-  version: 4.3.2
-  resolution: "ansi-escapes@npm:4.3.2"
-  dependencies:
-    type-fest: "npm:^0.21.3"
-  checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50
-  languageName: node
-  linkType: hard
-
 "ansi-regex@npm:^5.0.1":
   version: 5.0.1
   resolution: "ansi-regex@npm:5.0.1"
@@ -2335,13 +1355,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ansi-styles@npm:^5.2.0":
-  version: 5.2.0
-  resolution: "ansi-styles@npm:5.2.0"
-  checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df
-  languageName: node
-  linkType: hard
-
 "ansi-styles@npm:^6.1.0":
   version: 6.2.3
   resolution: "ansi-styles@npm:6.2.3"
@@ -2349,16 +1362,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"anymatch@npm:^3.1.3":
-  version: 3.1.3
-  resolution: "anymatch@npm:3.1.3"
-  dependencies:
-    normalize-path: "npm:^3.0.0"
-    picomatch: "npm:^2.0.4"
-  checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac
-  languageName: node
-  linkType: hard
-
 "arg@npm:^4.1.0":
   version: 4.1.3
   resolution: "arg@npm:4.1.3"
@@ -2366,7 +1369,14 @@ __metadata:
   languageName: node
   linkType: hard
 
-"argparse@npm:^1.0.7, argparse@npm:~1.0.9":
+"argparse@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "argparse@npm:2.0.1"
+  checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e
+  languageName: node
+  linkType: hard
+
+"argparse@npm:~1.0.9":
   version: 1.0.10
   resolution: "argparse@npm:1.0.10"
   dependencies:
@@ -2375,13 +1385,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"argparse@npm:^2.0.1":
-  version: 2.0.1
-  resolution: "argparse@npm:2.0.1"
-  checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e
-  languageName: node
-  linkType: hard
-
 "array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2":
   version: 1.0.2
   resolution: "array-buffer-byte-length@npm:1.0.2"
@@ -2497,82 +1500,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"babel-jest@npm:30.2.0":
-  version: 30.2.0
-  resolution: "babel-jest@npm:30.2.0"
-  dependencies:
-    "@jest/transform": "npm:30.2.0"
-    "@types/babel__core": "npm:^7.20.5"
-    babel-plugin-istanbul: "npm:^7.0.1"
-    babel-preset-jest: "npm:30.2.0"
-    chalk: "npm:^4.1.2"
-    graceful-fs: "npm:^4.2.11"
-    slash: "npm:^3.0.0"
-  peerDependencies:
-    "@babel/core": ^7.11.0 || ^8.0.0-0
-  checksum: 10c0/673b8c87e5aec97c4f7372319c005d1e2b018e2f2e973378c7fb0a4f1e111f89872e6f1e49dd50aff6290cd881c865117ade67f2c78a356a8275ab21af47340d
-  languageName: node
-  linkType: hard
-
-"babel-plugin-istanbul@npm:^7.0.1":
-  version: 7.0.1
-  resolution: "babel-plugin-istanbul@npm:7.0.1"
-  dependencies:
-    "@babel/helper-plugin-utils": "npm:^7.0.0"
-    "@istanbuljs/load-nyc-config": "npm:^1.0.0"
-    "@istanbuljs/schema": "npm:^0.1.3"
-    istanbul-lib-instrument: "npm:^6.0.2"
-    test-exclude: "npm:^6.0.0"
-  checksum: 10c0/92975e3df12503b168695463b451468da0c20e117807221652eb8e33a26c160f3b9d4c5c4e65495657420e871c6a54e5e31f539e2e1da37ef2261d7ddd4b1dfd
-  languageName: node
-  linkType: hard
-
-"babel-plugin-jest-hoist@npm:30.2.0":
-  version: 30.2.0
-  resolution: "babel-plugin-jest-hoist@npm:30.2.0"
-  dependencies:
-    "@types/babel__core": "npm:^7.20.5"
-  checksum: 10c0/a2bd862aaa4875127c02e6020d3da67556a8f25981060252668dda65cf9a146202937ae80d2e8612c3c47afe19ac85577647b8cc216faa98567c685525a3f203
-  languageName: node
-  linkType: hard
-
-"babel-preset-current-node-syntax@npm:^1.2.0":
-  version: 1.2.0
-  resolution: "babel-preset-current-node-syntax@npm:1.2.0"
-  dependencies:
-    "@babel/plugin-syntax-async-generators": "npm:^7.8.4"
-    "@babel/plugin-syntax-bigint": "npm:^7.8.3"
-    "@babel/plugin-syntax-class-properties": "npm:^7.12.13"
-    "@babel/plugin-syntax-class-static-block": "npm:^7.14.5"
-    "@babel/plugin-syntax-import-attributes": "npm:^7.24.7"
-    "@babel/plugin-syntax-import-meta": "npm:^7.10.4"
-    "@babel/plugin-syntax-json-strings": "npm:^7.8.3"
-    "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4"
-    "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3"
-    "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4"
-    "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3"
-    "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3"
-    "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3"
-    "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5"
-    "@babel/plugin-syntax-top-level-await": "npm:^7.14.5"
-  peerDependencies:
-    "@babel/core": ^7.0.0 || ^8.0.0-0
-  checksum: 10c0/94a4f81cddf9b051045d08489e4fff7336292016301664c138cfa3d9ffe3fe2ba10a24ad6ae589fd95af1ac72ba0216e1653555c187e694d7b17be0c002bea10
-  languageName: node
-  linkType: hard
-
-"babel-preset-jest@npm:30.2.0":
-  version: 30.2.0
-  resolution: "babel-preset-jest@npm:30.2.0"
-  dependencies:
-    babel-plugin-jest-hoist: "npm:30.2.0"
-    babel-preset-current-node-syntax: "npm:^1.2.0"
-  peerDependencies:
-    "@babel/core": ^7.11.0 || ^8.0.0-beta.1
-  checksum: 10c0/fb2727bad450256146d63b5231b83a7638e73b96c9612296a20afd65fb8c76678ef9bc6fa56e81d1303109258aeb4fccea5b96568744059e47d3c6e3ebc98bd9
-  languageName: node
-  linkType: hard
-
 "balanced-match@npm:^1.0.0":
   version: 1.0.2
   resolution: "balanced-match@npm:1.0.2"
@@ -2594,15 +1521,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"baseline-browser-mapping@npm:^2.8.9":
-  version: 2.8.11
-  resolution: "baseline-browser-mapping@npm:2.8.11"
-  bin:
-    baseline-browser-mapping: dist/cli.js
-  checksum: 10c0/9c345d41152782c20cc11ad0aff273d252d6063efdfc45a602abd8798b50d81deeb89aa3ab6eedd33dce2ad714d16de96783e248f850e95b6063e81cd2ea62ba
-  languageName: node
-  linkType: hard
-
 "bindings@npm:^1.5.0":
   version: 1.5.0
   resolution: "bindings@npm:1.5.0"
@@ -2658,43 +1576,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"browserslist@npm:^4.24.0":
-  version: 4.26.3
-  resolution: "browserslist@npm:4.26.3"
-  dependencies:
-    baseline-browser-mapping: "npm:^2.8.9"
-    caniuse-lite: "npm:^1.0.30001746"
-    electron-to-chromium: "npm:^1.5.227"
-    node-releases: "npm:^2.0.21"
-    update-browserslist-db: "npm:^1.1.3"
-  bin:
-    browserslist: cli.js
-  checksum: 10c0/3899ee3b7fd205ece4ffe4392697c3f2b120b68f3741ef1789212b4971771aee3f66cf37c5c3accf86ce59c0605b5980c0f132711abbcc9e62c132e6e0ee45f3
-  languageName: node
-  linkType: hard
-
-"bs-logger@npm:^0.2.6":
-  version: 0.2.6
-  resolution: "bs-logger@npm:0.2.6"
-  dependencies:
-    fast-json-stable-stringify: "npm:2.x"
-  checksum: 10c0/80e89aaaed4b68e3374ce936f2eb097456a0dddbf11f75238dbd53140b1e39259f0d248a5089ed456f1158984f22191c3658d54a713982f676709fbe1a6fa5a0
-  languageName: node
-  linkType: hard
-
-"bser@npm:2.1.1":
-  version: 2.1.1
-  resolution: "bser@npm:2.1.1"
-  dependencies:
-    node-int64: "npm:^0.4.0"
-  checksum: 10c0/24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227
-  languageName: node
-  linkType: hard
-
-"buffer-from@npm:^1.0.0":
-  version: 1.1.2
-  resolution: "buffer-from@npm:1.1.2"
-  checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34
+"browser-stdout@npm:^1.3.1":
+  version: 1.3.1
+  resolution: "browser-stdout@npm:1.3.1"
+  checksum: 10c0/c40e482fd82be872b6ea7b9f7591beafbf6f5ba522fe3dade98ba1573a1c29a11101564993e4eb44e5488be8f44510af072df9a9637c739217eb155ceb639205
   languageName: node
   linkType: hard
 
@@ -2780,35 +1665,28 @@ __metadata:
   languageName: node
   linkType: hard
 
-"callsites@npm:^3.0.0, callsites@npm:^3.1.0":
+"callsites@npm:^3.0.0":
   version: 3.1.0
   resolution: "callsites@npm:3.1.0"
   checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301
   languageName: node
   linkType: hard
 
-"camelcase@npm:^5.3.1":
-  version: 5.3.1
-  resolution: "camelcase@npm:5.3.1"
-  checksum: 10c0/92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23
-  languageName: node
-  linkType: hard
-
-"camelcase@npm:^6.3.0":
+"camelcase@npm:^6.0.0":
   version: 6.3.0
   resolution: "camelcase@npm:6.3.0"
   checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710
   languageName: node
   linkType: hard
 
-"caniuse-lite@npm:^1.0.30001746":
-  version: 1.0.30001747
-  resolution: "caniuse-lite@npm:1.0.30001747"
-  checksum: 10c0/cef0c7fff34d4c0ac3edc33660f07785301c98858bb4a6b8702b7b09ca2b0fd5457a7772af7b9fc3591fdd13862f649e57eed824f4cb6cf4aedf563e58fc7d0c
+"chai@npm:^6.2.0":
+  version: 6.2.0
+  resolution: "chai@npm:6.2.0"
+  checksum: 10c0/a4b7d7f5907187e09f1847afa838d6d1608adc7d822031b7900813c4ed5d9702911ac2468bf290676f22fddb3d727b1be90b57c1d0a69b902534ee29cdc6ff8a
   languageName: node
   linkType: hard
 
-"chalk@npm:^4.0.0, chalk@npm:^4.1.2":
+"chalk@npm:^4.0.0, chalk@npm:^4.1.0":
   version: 4.1.2
   resolution: "chalk@npm:4.1.2"
   dependencies:
@@ -2818,10 +1696,12 @@ __metadata:
   languageName: node
   linkType: hard
 
-"char-regex@npm:^1.0.2":
-  version: 1.0.2
-  resolution: "char-regex@npm:1.0.2"
-  checksum: 10c0/57a09a86371331e0be35d9083ba429e86c4f4648ecbe27455dbfb343037c16ee6fdc7f6b61f433a57cc5ded5561d71c56a150e018f40c2ffb7bc93a26dae341e
+"chokidar@npm:^4.0.1":
+  version: 4.0.3
+  resolution: "chokidar@npm:4.0.3"
+  dependencies:
+    readdirp: "npm:^4.0.1"
+  checksum: 10c0/a58b9df05bb452f7d105d9e7229ac82fa873741c0c40ddcc7bb82f8a909fbe3f7814c9ebe9bc9a2bef9b737c0ec6e2d699d179048ef06ad3ec46315df0ebe6ad
   languageName: node
   linkType: hard
 
@@ -2846,20 +1726,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ci-info@npm:^4.2.0":
-  version: 4.3.0
-  resolution: "ci-info@npm:4.3.0"
-  checksum: 10c0/60d3dfe95d75c01454ec1cfd5108617dd598a28a2a3e148bd7e1523c1c208b5f5a3007cafcbe293e6fd0a5a310cc32217c5dc54743eeabc0a2bec80072fc055c
-  languageName: node
-  linkType: hard
-
-"cjs-module-lexer@npm:^2.1.0":
-  version: 2.1.0
-  resolution: "cjs-module-lexer@npm:2.1.0"
-  checksum: 10c0/91cf28686dc3948e4a06dfa03a2fccb14b7a97471ffe7ae0124f62060ddf2de28e8e997f60007babe6e122b1b06a47c01a1b72cc015f185824d9cac3ccfa5533
-  languageName: node
-  linkType: hard
-
 "clean-stack@npm:^2.0.0":
   version: 2.2.0
   resolution: "clean-stack@npm:2.2.0"
@@ -2878,20 +1744,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"co@npm:^4.6.0":
-  version: 4.6.0
-  resolution: "co@npm:4.6.0"
-  checksum: 10c0/c0e85ea0ca8bf0a50cbdca82efc5af0301240ca88ebe3644a6ffb8ffe911f34d40f8fbcf8f1d52c5ddd66706abd4d3bfcd64259f1e8e2371d4f47573b0dc8c28
-  languageName: node
-  linkType: hard
-
-"collect-v8-coverage@npm:^1.0.2":
-  version: 1.0.2
-  resolution: "collect-v8-coverage@npm:1.0.2"
-  checksum: 10c0/ed7008e2e8b6852c5483b444a3ae6e976e088d4335a85aa0a9db2861c5f1d31bd2d7ff97a60469b3388deeba661a619753afbe201279fb159b4b9548ab8269a1
-  languageName: node
-  linkType: hard
-
 "color-convert@npm:^2.0.1":
   version: 2.0.1
   resolution: "color-convert@npm:2.0.1"
@@ -2936,13 +1788,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"convert-source-map@npm:^2.0.0":
-  version: 2.0.0
-  resolution: "convert-source-map@npm:2.0.0"
-  checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b
-  languageName: node
-  linkType: hard
-
 "core-util-is@npm:~1.0.0":
   version: 1.0.3
   resolution: "core-util-is@npm:1.0.3"
@@ -2957,7 +1802,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
+"cross-spawn@npm:^7.0.6":
   version: 7.0.6
   resolution: "cross-spawn@npm:7.0.6"
   dependencies:
@@ -3008,7 +1853,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0":
+"debug@npm:4, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0":
   version: 4.4.3
   resolution: "debug@npm:4.4.3"
   dependencies:
@@ -3029,6 +1874,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"decamelize@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "decamelize@npm:4.0.0"
+  checksum: 10c0/e06da03fc05333e8cd2778c1487da67ffbea5b84e03ca80449519b8fa61f888714bbc6f459ea963d5641b4aa98832130eb5cd193d90ae9f0a27eee14be8e278d
+  languageName: node
+  linkType: hard
+
 "decompress-response@npm:^6.0.0":
   version: 6.0.0
   resolution: "decompress-response@npm:6.0.0"
@@ -3038,18 +1890,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"dedent@npm:^1.6.0":
-  version: 1.7.0
-  resolution: "dedent@npm:1.7.0"
-  peerDependencies:
-    babel-plugin-macros: ^3.1.0
-  peerDependenciesMeta:
-    babel-plugin-macros:
-      optional: true
-  checksum: 10c0/c5e8a8beb5072bd5e520cb64b27a82d7ec3c2a63ee5ce47dbc2a05d5b7700cefd77a992a752cd0a8b1d979c1db06b14fb9486e805f3ad6088eda6e07cd9bf2d5
-  languageName: node
-  linkType: hard
-
 "deep-extend@npm:^0.6.0":
   version: 0.6.0
   resolution: "deep-extend@npm:0.6.0"
@@ -3064,13 +1904,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"deepmerge@npm:^4.3.1":
-  version: 4.3.1
-  resolution: "deepmerge@npm:4.3.1"
-  checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044
-  languageName: node
-  linkType: hard
-
 "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
   version: 1.1.4
   resolution: "define-data-property@npm:1.1.4"
@@ -3100,13 +1933,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"detect-newline@npm:^3.1.0":
-  version: 3.1.0
-  resolution: "detect-newline@npm:3.1.0"
-  checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d
-  languageName: node
-  linkType: hard
-
 "diff@npm:^4.0.1":
   version: 4.0.2
   resolution: "diff@npm:4.0.2"
@@ -3114,6 +1940,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"diff@npm:^7.0.0":
+  version: 7.0.0
+  resolution: "diff@npm:7.0.0"
+  checksum: 10c0/251fd15f85ffdf814cfc35a728d526b8d2ad3de338dcbd011ac6e57c461417090766b28995f8ff733135b5fbc3699c392db1d5e27711ac4e00244768cd1d577b
+  languageName: node
+  linkType: hard
+
 "doctrine@npm:^2.1.0":
   version: 2.1.0
   resolution: "doctrine@npm:2.1.0"
@@ -3141,20 +1974,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"electron-to-chromium@npm:^1.5.227":
-  version: 1.5.230
-  resolution: "electron-to-chromium@npm:1.5.230"
-  checksum: 10c0/b8bf382868b2780fa0c7ba3bce0644e94ec21af8f9b199ee094273904a575b46c8705fa4c10a22a0ed90e42dbbf72efbc3089bbecf8324a9db099c8c6c1c1101
-  languageName: node
-  linkType: hard
-
-"emittery@npm:^0.13.1":
-  version: 0.13.1
-  resolution: "emittery@npm:0.13.1"
-  checksum: 10c0/1573d0ae29ab34661b6c63251ff8f5facd24ccf6a823f19417ae8ba8c88ea450325788c67f16c99edec8de4b52ce93a10fe441ece389fd156e88ee7dab9bfa35
-  languageName: node
-  linkType: hard
-
 "emoji-regex@npm:^8.0.0":
   version: 8.0.0
   resolution: "emoji-regex@npm:8.0.0"
@@ -3208,15 +2027,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"error-ex@npm:^1.3.1":
-  version: 1.3.4
-  resolution: "error-ex@npm:1.3.4"
-  dependencies:
-    is-arrayish: "npm:^0.2.1"
-  checksum: 10c0/b9e34ff4778b8f3b31a8377e1c654456f4c41aeaa3d10a1138c3b7635d8b7b2e03eb2475d46d8ae055c1f180a1063e100bffabf64ea7e7388b37735df5328664
-  languageName: node
-  linkType: hard
-
 "es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0":
   version: 1.24.0
   resolution: "es-abstract@npm:1.24.0"
@@ -3334,7 +2144,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"esbuild@npm:^0.25.0":
+"esbuild@npm:^0.25.0, esbuild@npm:~0.25.0":
   version: 0.25.10
   resolution: "esbuild@npm:0.25.10"
   dependencies:
@@ -3423,20 +2233,13 @@ __metadata:
   languageName: node
   linkType: hard
 
-"escalade@npm:^3.1.1, escalade@npm:^3.2.0":
+"escalade@npm:^3.1.1":
   version: 3.2.0
   resolution: "escalade@npm:3.2.0"
   checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65
   languageName: node
   linkType: hard
 
-"escape-string-regexp@npm:^2.0.0":
-  version: 2.0.0
-  resolution: "escape-string-regexp@npm:2.0.0"
-  checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507
-  languageName: node
-  linkType: hard
-
 "escape-string-regexp@npm:^4.0.0":
   version: 4.0.0
   resolution: "escape-string-regexp@npm:4.0.0"
@@ -3496,24 +2299,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"eslint-plugin-jest@npm:^29.0.1":
-  version: 29.0.1
-  resolution: "eslint-plugin-jest@npm:29.0.1"
-  dependencies:
-    "@typescript-eslint/utils": "npm:^8.0.0"
-  peerDependencies:
-    "@typescript-eslint/eslint-plugin": ^8.0.0
-    eslint: ^8.57.0 || ^9.0.0
-    jest: "*"
-  peerDependenciesMeta:
-    "@typescript-eslint/eslint-plugin":
-      optional: true
-    jest:
-      optional: true
-  checksum: 10c0/20edc166503a50c10b45f733797d530a5107c91efa25410ef405780d12222a796b5b41ed8f6d2b939632a1af273af6cc5732233463d1f36dbe7680bbb86c4eec
-  languageName: node
-  linkType: hard
-
 "eslint-scope@npm:^8.4.0":
   version: 8.4.0
   resolution: "eslint-scope@npm:8.4.0"
@@ -3599,16 +2384,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"esprima@npm:^4.0.0":
-  version: 4.0.1
-  resolution: "esprima@npm:4.0.1"
-  bin:
-    esparse: ./bin/esparse.js
-    esvalidate: ./bin/esvalidate.js
-  checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3
-  languageName: node
-  linkType: hard
-
 "esquery@npm:^1.5.0":
   version: 1.6.0
   resolution: "esquery@npm:1.6.0"
@@ -3657,30 +2432,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"execa@npm:^5.1.1":
-  version: 5.1.1
-  resolution: "execa@npm:5.1.1"
-  dependencies:
-    cross-spawn: "npm:^7.0.3"
-    get-stream: "npm:^6.0.0"
-    human-signals: "npm:^2.1.0"
-    is-stream: "npm:^2.0.0"
-    merge-stream: "npm:^2.0.0"
-    npm-run-path: "npm:^4.0.1"
-    onetime: "npm:^5.1.2"
-    signal-exit: "npm:^3.0.3"
-    strip-final-newline: "npm:^2.0.0"
-  checksum: 10c0/c8e615235e8de4c5addf2fa4c3da3e3aa59ce975a3e83533b4f6a71750fb816a2e79610dc5f1799b6e28976c9ae86747a36a606655bf8cb414a74d8d507b304f
-  languageName: node
-  linkType: hard
-
-"exit-x@npm:^0.2.2":
-  version: 0.2.2
-  resolution: "exit-x@npm:0.2.2"
-  checksum: 10c0/212a7a095ca5540e9581f1ef2d1d6a40df7a6027c8cc96e78ce1d16b86d1a88326d4a0eff8dff2b5ec1e68bb0c1edd5d0dfdde87df1869bf7514d4bc6a5cbd72
-  languageName: node
-  linkType: hard
-
 "expand-template@npm:^2.0.3":
   version: 2.0.3
   resolution: "expand-template@npm:2.0.3"
@@ -3688,20 +2439,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"expect@npm:30.2.0, expect@npm:^30.0.0":
-  version: 30.2.0
-  resolution: "expect@npm:30.2.0"
-  dependencies:
-    "@jest/expect-utils": "npm:30.2.0"
-    "@jest/get-type": "npm:30.1.0"
-    jest-matcher-utils: "npm:30.2.0"
-    jest-message-util: "npm:30.2.0"
-    jest-mock: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-  checksum: 10c0/fe440b3a036e2de1a3ede84bc6a699925328056e74324fbd2fdd9ce7b7358d03e515ac8db559c33828bcb0b7887b493dbaaece565e67d88748685850da5d9209
-  languageName: node
-  linkType: hard
-
 "exponential-backoff@npm:^3.1.1":
   version: 3.1.2
   resolution: "exponential-backoff@npm:3.1.2"
@@ -3743,7 +2480,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0":
+"fast-json-stable-stringify@npm:^2.0.0":
   version: 2.1.0
   resolution: "fast-json-stable-stringify@npm:2.1.0"
   checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b
@@ -3769,16 +2506,7 @@ __metadata:
   resolution: "fastq@npm:1.19.1"
   dependencies:
     reusify: "npm:^1.0.4"
-  checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630
-  languageName: node
-  linkType: hard
-
-"fb-watchman@npm:^2.0.2":
-  version: 2.0.2
-  resolution: "fb-watchman@npm:2.0.2"
-  dependencies:
-    bser: "npm:2.1.1"
-  checksum: 10c0/feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581
+  checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630
   languageName: node
   linkType: hard
 
@@ -3819,16 +2547,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"find-up@npm:^4.0.0, find-up@npm:^4.1.0":
-  version: 4.1.0
-  resolution: "find-up@npm:4.1.0"
-  dependencies:
-    locate-path: "npm:^5.0.0"
-    path-exists: "npm:^4.0.0"
-  checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1
-  languageName: node
-  linkType: hard
-
 "find-up@npm:^5.0.0":
   version: 5.0.0
   resolution: "find-up@npm:5.0.0"
@@ -3849,6 +2567,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"flat@npm:^5.0.2":
+  version: 5.0.2
+  resolution: "flat@npm:5.0.2"
+  bin:
+    flat: cli.js
+  checksum: 10c0/f178b13482f0cd80c7fede05f4d10585b1f2fdebf26e12edc138e32d3150c6ea6482b7f12813a1091143bad52bb6d3596bca51a162257a21163c0ff438baa5fe
+  languageName: node
+  linkType: hard
+
 "flatted@npm:^3.2.9":
   version: 3.3.3
   resolution: "flatted@npm:3.3.3"
@@ -3911,14 +2638,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fs.realpath@npm:^1.0.0":
-  version: 1.0.0
-  resolution: "fs.realpath@npm:1.0.0"
-  checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948
-  languageName: node
-  linkType: hard
-
-"fsevents@npm:^2.3.3, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
+"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
   version: 2.3.3
   resolution: "fsevents@npm:2.3.3"
   dependencies:
@@ -3928,7 +2648,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin":
+"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin":
   version: 2.3.3
   resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1"
   dependencies:
@@ -3972,13 +2692,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"gensync@npm:^1.0.0-beta.2":
-  version: 1.0.0-beta.2
-  resolution: "gensync@npm:1.0.0-beta.2"
-  checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8
-  languageName: node
-  linkType: hard
-
 "get-caller-file@npm:^2.0.5":
   version: 2.0.5
   resolution: "get-caller-file@npm:2.0.5"
@@ -4007,13 +2720,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"get-package-type@npm:^0.1.0":
-  version: 0.1.0
-  resolution: "get-package-type@npm:0.1.0"
-  checksum: 10c0/e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be
-  languageName: node
-  linkType: hard
-
 "get-proto@npm:^1.0.1":
   version: 1.0.1
   resolution: "get-proto@npm:1.0.1"
@@ -4024,13 +2730,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"get-stream@npm:^6.0.0":
-  version: 6.0.1
-  resolution: "get-stream@npm:6.0.1"
-  checksum: 10c0/49825d57d3fd6964228e6200a58169464b8e8970489b3acdc24906c782fb7f01f9f56f8e6653c4a50713771d6658f7cfe051e5eb8c12e334138c9c918b296341
-  languageName: node
-  linkType: hard
-
 "get-symbol-description@npm:^1.1.0":
   version: 1.1.0
   resolution: "get-symbol-description@npm:1.1.0"
@@ -4042,6 +2741,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"get-tsconfig@npm:^4.7.5":
+  version: 4.12.0
+  resolution: "get-tsconfig@npm:4.12.0"
+  dependencies:
+    resolve-pkg-maps: "npm:^1.0.0"
+  checksum: 10c0/3438106bd46bfc6595fce6117190f1ac0998de2e6916b40ec23b20c784b0b47e79ea2b920895b9ed26029b1f80b8867626fb24795d5f45abbdab716a4ba1ef92
+  languageName: node
+  linkType: hard
+
 "github-from-package@npm:0.0.0":
   version: 0.0.0
   resolution: "github-from-package@npm:0.0.0"
@@ -4089,7 +2797,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"glob@npm:^10.2.2, glob@npm:^10.3.10":
+"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.5":
   version: 10.4.5
   resolution: "glob@npm:10.4.5"
   dependencies:
@@ -4121,20 +2829,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"glob@npm:^7.1.4":
-  version: 7.2.3
-  resolution: "glob@npm:7.2.3"
-  dependencies:
-    fs.realpath: "npm:^1.0.0"
-    inflight: "npm:^1.0.4"
-    inherits: "npm:2"
-    minimatch: "npm:^3.1.1"
-    once: "npm:^1.3.0"
-    path-is-absolute: "npm:^1.0.0"
-  checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe
-  languageName: node
-  linkType: hard
-
 "globals@npm:^14.0.0":
   version: 14.0.0
   resolution: "globals@npm:14.0.0"
@@ -4175,7 +2869,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6":
+"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6":
   version: 4.2.11
   resolution: "graceful-fs@npm:4.2.11"
   checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
@@ -4189,24 +2883,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"handlebars@npm:^4.7.8":
-  version: 4.7.8
-  resolution: "handlebars@npm:4.7.8"
-  dependencies:
-    minimist: "npm:^1.2.5"
-    neo-async: "npm:^2.6.2"
-    source-map: "npm:^0.6.1"
-    uglify-js: "npm:^3.1.4"
-    wordwrap: "npm:^1.0.0"
-  dependenciesMeta:
-    uglify-js:
-      optional: true
-  bin:
-    handlebars: bin/handlebars
-  checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d
-  languageName: node
-  linkType: hard
-
 "has-bigints@npm:^1.0.2":
   version: 1.1.0
   resolution: "has-bigints@npm:1.1.0"
@@ -4273,13 +2949,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"html-escaper@npm:^2.0.0":
-  version: 2.0.2
-  resolution: "html-escaper@npm:2.0.2"
-  checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0
-  languageName: node
-  linkType: hard
-
 "http-cache-semantics@npm:^4.1.1":
   version: 4.2.0
   resolution: "http-cache-semantics@npm:4.2.0"
@@ -4307,13 +2976,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"human-signals@npm:^2.1.0":
-  version: 2.1.0
-  resolution: "human-signals@npm:2.1.0"
-  checksum: 10c0/695edb3edfcfe9c8b52a76926cd31b36978782062c0ed9b1192b36bebc75c4c87c82e178dfcb0ed0fc27ca59d434198aac0bd0be18f5781ded775604db22304a
-  languageName: node
-  linkType: hard
-
 "iconv-lite@npm:^0.6.2":
   version: 0.6.3
   resolution: "iconv-lite@npm:0.6.3"
@@ -4361,18 +3023,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"import-local@npm:^3.2.0":
-  version: 3.2.0
-  resolution: "import-local@npm:3.2.0"
-  dependencies:
-    pkg-dir: "npm:^4.2.0"
-    resolve-cwd: "npm:^3.0.0"
-  bin:
-    import-local-fixture: fixtures/cli.js
-  checksum: 10c0/94cd6367a672b7e0cb026970c85b76902d2710a64896fa6de93bd5c571dd03b228c5759308959de205083e3b1c61e799f019c9e36ee8e9c523b993e1057f0433
-  languageName: node
-  linkType: hard
-
 "imurmurhash@npm:^0.1.4":
   version: 0.1.4
   resolution: "imurmurhash@npm:0.1.4"
@@ -4387,17 +3037,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"inflight@npm:^1.0.4":
-  version: 1.0.6
-  resolution: "inflight@npm:1.0.6"
-  dependencies:
-    once: "npm:^1.3.0"
-    wrappy: "npm:1"
-  checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2
-  languageName: node
-  linkType: hard
-
-"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1":
+"inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1":
   version: 2.0.4
   resolution: "inherits@npm:2.0.4"
   checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2
@@ -4440,13 +3080,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-arrayish@npm:^0.2.1":
-  version: 0.2.1
-  resolution: "is-arrayish@npm:0.2.1"
-  checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729
-  languageName: node
-  linkType: hard
-
 "is-async-function@npm:^2.0.0":
   version: 2.1.1
   resolution: "is-async-function@npm:2.1.1"
@@ -4539,13 +3172,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-generator-fn@npm:^2.1.0":
-  version: 2.1.0
-  resolution: "is-generator-fn@npm:2.1.0"
-  checksum: 10c0/2957cab387997a466cd0bf5c1b6047bd21ecb32bdcfd8996b15747aa01002c1c88731802f1b3d34ac99f4f6874b626418bd118658cf39380fe5fff32a3af9c4d
-  languageName: node
-  linkType: hard
-
 "is-generator-function@npm:^1.0.10":
   version: 1.1.2
   resolution: "is-generator-function@npm:1.1.2"
@@ -4606,6 +3232,20 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-path-inside@npm:^3.0.3":
+  version: 3.0.3
+  resolution: "is-path-inside@npm:3.0.3"
+  checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05
+  languageName: node
+  linkType: hard
+
+"is-plain-obj@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "is-plain-obj@npm:2.1.0"
+  checksum: 10c0/e5c9814cdaa627a9ad0a0964ded0e0491bfd9ace405c49a5d63c88b30a162f1512c069d5b80997893c4d0181eadc3fed02b4ab4b81059aba5620bfcdfdeb9c53
+  languageName: node
+  linkType: hard
+
 "is-regex@npm:^1.2.1":
   version: 1.2.1
   resolution: "is-regex@npm:1.2.1"
@@ -4634,13 +3274,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-stream@npm:^2.0.0":
-  version: 2.0.1
-  resolution: "is-stream@npm:2.0.1"
-  checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5
-  languageName: node
-  linkType: hard
-
 "is-string@npm:^1.1.1":
   version: 1.1.1
   resolution: "is-string@npm:1.1.1"
@@ -4671,6 +3304,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-unicode-supported@npm:^0.1.0":
+  version: 0.1.0
+  resolution: "is-unicode-supported@npm:0.1.0"
+  checksum: 10c0/00cbe3455c3756be68d2542c416cab888aebd5012781d6819749fefb15162ff23e38501fe681b3d751c73e8ff561ac09a5293eba6f58fdf0178462ce6dcb3453
+  languageName: node
+  linkType: hard
+
 "is-weakmap@npm:^2.0.2":
   version: 2.0.2
   resolution: "is-weakmap@npm:2.0.2"
@@ -4725,58 +3365,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0":
-  version: 3.2.2
-  resolution: "istanbul-lib-coverage@npm:3.2.2"
-  checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b
-  languageName: node
-  linkType: hard
-
-"istanbul-lib-instrument@npm:^6.0.0, istanbul-lib-instrument@npm:^6.0.2":
-  version: 6.0.3
-  resolution: "istanbul-lib-instrument@npm:6.0.3"
-  dependencies:
-    "@babel/core": "npm:^7.23.9"
-    "@babel/parser": "npm:^7.23.9"
-    "@istanbuljs/schema": "npm:^0.1.3"
-    istanbul-lib-coverage: "npm:^3.2.0"
-    semver: "npm:^7.5.4"
-  checksum: 10c0/a1894e060dd2a3b9f046ffdc87b44c00a35516f5e6b7baf4910369acca79e506fc5323a816f811ae23d82334b38e3ddeb8b3b331bd2c860540793b59a8689128
-  languageName: node
-  linkType: hard
-
-"istanbul-lib-report@npm:^3.0.0":
-  version: 3.0.1
-  resolution: "istanbul-lib-report@npm:3.0.1"
-  dependencies:
-    istanbul-lib-coverage: "npm:^3.0.0"
-    make-dir: "npm:^4.0.0"
-    supports-color: "npm:^7.1.0"
-  checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7
-  languageName: node
-  linkType: hard
-
-"istanbul-lib-source-maps@npm:^5.0.0":
-  version: 5.0.6
-  resolution: "istanbul-lib-source-maps@npm:5.0.6"
-  dependencies:
-    "@jridgewell/trace-mapping": "npm:^0.3.23"
-    debug: "npm:^4.1.1"
-    istanbul-lib-coverage: "npm:^3.0.0"
-  checksum: 10c0/ffe75d70b303a3621ee4671554f306e0831b16f39ab7f4ab52e54d356a5d33e534d97563e318f1333a6aae1d42f91ec49c76b6cd3f3fb378addcb5c81da0255f
-  languageName: node
-  linkType: hard
-
-"istanbul-reports@npm:^3.1.3":
-  version: 3.2.0
-  resolution: "istanbul-reports@npm:3.2.0"
-  dependencies:
-    html-escaper: "npm:^2.0.0"
-    istanbul-lib-report: "npm:^3.0.0"
-  checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc
-  languageName: node
-  linkType: hard
-
 "jackspeak@npm:^3.1.2":
   version: 3.4.3
   resolution: "jackspeak@npm:3.4.3"
@@ -4799,444 +3387,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"jest-changed-files@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-changed-files@npm:30.2.0"
-  dependencies:
-    execa: "npm:^5.1.1"
-    jest-util: "npm:30.2.0"
-    p-limit: "npm:^3.1.0"
-  checksum: 10c0/0ce838f8bffdadcdc19028f4b7a24c04d2f9885ee5c5c1bb4746c205cb96649934090ef6492c3dc45b1be097672b4f8043ad141278bc82f390579fa3ea4c11fe
-  languageName: node
-  linkType: hard
-
-"jest-circus@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-circus@npm:30.2.0"
-  dependencies:
-    "@jest/environment": "npm:30.2.0"
-    "@jest/expect": "npm:30.2.0"
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    chalk: "npm:^4.1.2"
-    co: "npm:^4.6.0"
-    dedent: "npm:^1.6.0"
-    is-generator-fn: "npm:^2.1.0"
-    jest-each: "npm:30.2.0"
-    jest-matcher-utils: "npm:30.2.0"
-    jest-message-util: "npm:30.2.0"
-    jest-runtime: "npm:30.2.0"
-    jest-snapshot: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    p-limit: "npm:^3.1.0"
-    pretty-format: "npm:30.2.0"
-    pure-rand: "npm:^7.0.0"
-    slash: "npm:^3.0.0"
-    stack-utils: "npm:^2.0.6"
-  checksum: 10c0/32fc88e13d3e811a9af5ca02d31f7cc742e726a0128df0b023330d6dff6ac29bf981da09937162f7c0705cf327df8d24e46de84860f6817dbc134438315c2967
-  languageName: node
-  linkType: hard
-
-"jest-cli@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-cli@npm:30.2.0"
-  dependencies:
-    "@jest/core": "npm:30.2.0"
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    chalk: "npm:^4.1.2"
-    exit-x: "npm:^0.2.2"
-    import-local: "npm:^3.2.0"
-    jest-config: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    jest-validate: "npm:30.2.0"
-    yargs: "npm:^17.7.2"
-  peerDependencies:
-    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-  peerDependenciesMeta:
-    node-notifier:
-      optional: true
-  bin:
-    jest: ./bin/jest.js
-  checksum: 10c0/b722a98cdf7b0ff1c273dd4efbaf331d683335f1f338a76a24492574e582a4e5a12a9df66e41bf4c92c7cffe0f51b759818ecd42044cd9bbef67d40359240989
-  languageName: node
-  linkType: hard
-
-"jest-config@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-config@npm:30.2.0"
-  dependencies:
-    "@babel/core": "npm:^7.27.4"
-    "@jest/get-type": "npm:30.1.0"
-    "@jest/pattern": "npm:30.0.1"
-    "@jest/test-sequencer": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    babel-jest: "npm:30.2.0"
-    chalk: "npm:^4.1.2"
-    ci-info: "npm:^4.2.0"
-    deepmerge: "npm:^4.3.1"
-    glob: "npm:^10.3.10"
-    graceful-fs: "npm:^4.2.11"
-    jest-circus: "npm:30.2.0"
-    jest-docblock: "npm:30.2.0"
-    jest-environment-node: "npm:30.2.0"
-    jest-regex-util: "npm:30.0.1"
-    jest-resolve: "npm:30.2.0"
-    jest-runner: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    jest-validate: "npm:30.2.0"
-    micromatch: "npm:^4.0.8"
-    parse-json: "npm:^5.2.0"
-    pretty-format: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-    strip-json-comments: "npm:^3.1.1"
-  peerDependencies:
-    "@types/node": "*"
-    esbuild-register: ">=3.4.0"
-    ts-node: ">=9.0.0"
-  peerDependenciesMeta:
-    "@types/node":
-      optional: true
-    esbuild-register:
-      optional: true
-    ts-node:
-      optional: true
-  checksum: 10c0/f02bb747e3382cdbb5a00abd583e9118a0b4f1d9d4cad01b5cc06b7fab9b817419ec183856cd791b2e9167051cad52b3d22ea34319a28c8f3e70a5ce73d05faa
-  languageName: node
-  linkType: hard
-
-"jest-diff@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-diff@npm:30.2.0"
-  dependencies:
-    "@jest/diff-sequences": "npm:30.0.1"
-    "@jest/get-type": "npm:30.1.0"
-    chalk: "npm:^4.1.2"
-    pretty-format: "npm:30.2.0"
-  checksum: 10c0/5fac2cd89a10b282c5a68fc6206a95dfff9955ed0b758d24ffb0edcb20fb2f98e1fa5045c5c4205d952712ea864c6a086654f80cdd500cce054a2f5daf5b4419
-  languageName: node
-  linkType: hard
-
-"jest-docblock@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-docblock@npm:30.2.0"
-  dependencies:
-    detect-newline: "npm:^3.1.0"
-  checksum: 10c0/2578366604eef1b36d59ffe1fc52a710995571535d437f83d94ff94756a83f78e699c1ba004c38a34c01859d669fd6c64e865c23c5a7d5bf4837cfca4bef3dda
-  languageName: node
-  linkType: hard
-
-"jest-each@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-each@npm:30.2.0"
-  dependencies:
-    "@jest/get-type": "npm:30.1.0"
-    "@jest/types": "npm:30.2.0"
-    chalk: "npm:^4.1.2"
-    jest-util: "npm:30.2.0"
-    pretty-format: "npm:30.2.0"
-  checksum: 10c0/4fa7e88a2741daaebd58cf49f9add8bd6c68657d2c106a170ebe4d7f86082c9eede2b13924304277a92e02b31b59a3c34949877da077bc27712b57913bb88321
-  languageName: node
-  linkType: hard
-
-"jest-environment-node@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-environment-node@npm:30.2.0"
-  dependencies:
-    "@jest/environment": "npm:30.2.0"
-    "@jest/fake-timers": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    jest-mock: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    jest-validate: "npm:30.2.0"
-  checksum: 10c0/866ba2c04ccf003845a8ca1f372081d76923849ae8e06e50cdfed792e41a976b5f953e15f3af17ff51b111b9540cf846f7f582530ca724c2a2abf15d15a99728
-  languageName: node
-  linkType: hard
-
-"jest-haste-map@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-haste-map@npm:30.2.0"
-  dependencies:
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    anymatch: "npm:^3.1.3"
-    fb-watchman: "npm:^2.0.2"
-    fsevents: "npm:^2.3.3"
-    graceful-fs: "npm:^4.2.11"
-    jest-regex-util: "npm:30.0.1"
-    jest-util: "npm:30.2.0"
-    jest-worker: "npm:30.2.0"
-    micromatch: "npm:^4.0.8"
-    walker: "npm:^1.0.8"
-  dependenciesMeta:
-    fsevents:
-      optional: true
-  checksum: 10c0/61b4ad5a59b4dfadac2f903f3d723d9017aada268c49b9222ec1e15c4892fd4c36af59b65f37f026d747d829672ab9679509fea5d4248d07a93b892963e1bb4e
-  languageName: node
-  linkType: hard
-
-"jest-leak-detector@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-leak-detector@npm:30.2.0"
-  dependencies:
-    "@jest/get-type": "npm:30.1.0"
-    pretty-format: "npm:30.2.0"
-  checksum: 10c0/68e2822aabe302983b65a08b19719a2444259af8a23ff20a6e2b6ce7759f55730f51c7cf16c65cb6be930c80a6cc70a4820239c84e8f333c9670a8e3a4a21801
-  languageName: node
-  linkType: hard
-
-"jest-matcher-utils@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-matcher-utils@npm:30.2.0"
-  dependencies:
-    "@jest/get-type": "npm:30.1.0"
-    chalk: "npm:^4.1.2"
-    jest-diff: "npm:30.2.0"
-    pretty-format: "npm:30.2.0"
-  checksum: 10c0/f221c8afa04cee693a2be735482c5db4ec6f845f8ca3a04cb419be34c6257f4531dab89c836251f31d1859318c38997e8e9f34bf7b4cdcc8c7be8ae6e2ecb9f2
-  languageName: node
-  linkType: hard
-
-"jest-message-util@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-message-util@npm:30.2.0"
-  dependencies:
-    "@babel/code-frame": "npm:^7.27.1"
-    "@jest/types": "npm:30.2.0"
-    "@types/stack-utils": "npm:^2.0.3"
-    chalk: "npm:^4.1.2"
-    graceful-fs: "npm:^4.2.11"
-    micromatch: "npm:^4.0.8"
-    pretty-format: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-    stack-utils: "npm:^2.0.6"
-  checksum: 10c0/9c4aae95f9e73a754e5ecababa06e5c00cf549ff1651bbbf9aadc671ee57e688b01606ef0e9932d9dfe3d4b8f4511b6e8d01e131a49d2f82761c820ab93ae519
-  languageName: node
-  linkType: hard
-
-"jest-mock@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-mock@npm:30.2.0"
-  dependencies:
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    jest-util: "npm:30.2.0"
-  checksum: 10c0/dfc8eb87f4075242f1b31d9dcac606f945c4f6a245d2bb67273738d266bea6345e10de3afa675076d545361bc96b754f764cffb0ccc2e99767484bece981b2f8
-  languageName: node
-  linkType: hard
-
-"jest-pnp-resolver@npm:^1.2.3":
-  version: 1.2.3
-  resolution: "jest-pnp-resolver@npm:1.2.3"
-  peerDependencies:
-    jest-resolve: "*"
-  peerDependenciesMeta:
-    jest-resolve:
-      optional: true
-  checksum: 10c0/86eec0c78449a2de733a6d3e316d49461af6a858070e113c97f75fb742a48c2396ea94150cbca44159ffd4a959f743a47a8b37a792ef6fdad2cf0a5cba973fac
-  languageName: node
-  linkType: hard
-
-"jest-regex-util@npm:30.0.1":
-  version: 30.0.1
-  resolution: "jest-regex-util@npm:30.0.1"
-  checksum: 10c0/f30c70524ebde2d1012afe5ffa5691d5d00f7d5ba9e43d588f6460ac6fe96f9e620f2f9b36a02d0d3e7e77bc8efb8b3450ae3b80ac53c8be5099e01bf54f6728
-  languageName: node
-  linkType: hard
-
-"jest-resolve-dependencies@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-resolve-dependencies@npm:30.2.0"
-  dependencies:
-    jest-regex-util: "npm:30.0.1"
-    jest-snapshot: "npm:30.2.0"
-  checksum: 10c0/f98f2187b490f402dd9ed6b15b5d324b1220d250a5768d46b1f1582cef05b830311351532a7d19f1868a2ce0049856ae6c26587f3869995cae7850739088b879
-  languageName: node
-  linkType: hard
-
-"jest-resolve@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-resolve@npm:30.2.0"
-  dependencies:
-    chalk: "npm:^4.1.2"
-    graceful-fs: "npm:^4.2.11"
-    jest-haste-map: "npm:30.2.0"
-    jest-pnp-resolver: "npm:^1.2.3"
-    jest-util: "npm:30.2.0"
-    jest-validate: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-    unrs-resolver: "npm:^1.7.11"
-  checksum: 10c0/149576b81609a79889d08298a95d52920839f796d24f8701beacaf998a4916df205acf86b64d0bc294172a821b88d144facf44ae5a4cb3cfaa03fa06a3fc666d
-  languageName: node
-  linkType: hard
-
-"jest-runner@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-runner@npm:30.2.0"
-  dependencies:
-    "@jest/console": "npm:30.2.0"
-    "@jest/environment": "npm:30.2.0"
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/transform": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    chalk: "npm:^4.1.2"
-    emittery: "npm:^0.13.1"
-    exit-x: "npm:^0.2.2"
-    graceful-fs: "npm:^4.2.11"
-    jest-docblock: "npm:30.2.0"
-    jest-environment-node: "npm:30.2.0"
-    jest-haste-map: "npm:30.2.0"
-    jest-leak-detector: "npm:30.2.0"
-    jest-message-util: "npm:30.2.0"
-    jest-resolve: "npm:30.2.0"
-    jest-runtime: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    jest-watcher: "npm:30.2.0"
-    jest-worker: "npm:30.2.0"
-    p-limit: "npm:^3.1.0"
-    source-map-support: "npm:0.5.13"
-  checksum: 10c0/68cb5eb993b4a02143fc442c245b17567432709879ad5f859fec635ccdf4ad0ef128c9fc6765c1582b3f5136b36cad5c5dd173926081bfc527d490b27406383e
-  languageName: node
-  linkType: hard
-
-"jest-runtime@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-runtime@npm:30.2.0"
-  dependencies:
-    "@jest/environment": "npm:30.2.0"
-    "@jest/fake-timers": "npm:30.2.0"
-    "@jest/globals": "npm:30.2.0"
-    "@jest/source-map": "npm:30.0.1"
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/transform": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    chalk: "npm:^4.1.2"
-    cjs-module-lexer: "npm:^2.1.0"
-    collect-v8-coverage: "npm:^1.0.2"
-    glob: "npm:^10.3.10"
-    graceful-fs: "npm:^4.2.11"
-    jest-haste-map: "npm:30.2.0"
-    jest-message-util: "npm:30.2.0"
-    jest-mock: "npm:30.2.0"
-    jest-regex-util: "npm:30.0.1"
-    jest-resolve: "npm:30.2.0"
-    jest-snapshot: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    slash: "npm:^3.0.0"
-    strip-bom: "npm:^4.0.0"
-  checksum: 10c0/d77b7eb75485f2b4913f635aeffa8e3e1b9baafb7a7f901f3c212195beb31f519e4b03358b5e454caee5cc94a2b9952c962fa7e5b0ff2ed06009a661924fd23e
-  languageName: node
-  linkType: hard
-
-"jest-snapshot@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-snapshot@npm:30.2.0"
-  dependencies:
-    "@babel/core": "npm:^7.27.4"
-    "@babel/generator": "npm:^7.27.5"
-    "@babel/plugin-syntax-jsx": "npm:^7.27.1"
-    "@babel/plugin-syntax-typescript": "npm:^7.27.1"
-    "@babel/types": "npm:^7.27.3"
-    "@jest/expect-utils": "npm:30.2.0"
-    "@jest/get-type": "npm:30.1.0"
-    "@jest/snapshot-utils": "npm:30.2.0"
-    "@jest/transform": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    babel-preset-current-node-syntax: "npm:^1.2.0"
-    chalk: "npm:^4.1.2"
-    expect: "npm:30.2.0"
-    graceful-fs: "npm:^4.2.11"
-    jest-diff: "npm:30.2.0"
-    jest-matcher-utils: "npm:30.2.0"
-    jest-message-util: "npm:30.2.0"
-    jest-util: "npm:30.2.0"
-    pretty-format: "npm:30.2.0"
-    semver: "npm:^7.7.2"
-    synckit: "npm:^0.11.8"
-  checksum: 10c0/961b13a3c9dcf8c533fe2ab8375bcdf441bd8680a7a7878245d8d8a4697432d806f7817cfaa061904e0c6cc939a38f1fe9f5af868b86328e77833a58822b3b63
-  languageName: node
-  linkType: hard
-
-"jest-util@npm:30.2.0, jest-util@npm:^30.2.0":
-  version: 30.2.0
-  resolution: "jest-util@npm:30.2.0"
-  dependencies:
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    chalk: "npm:^4.1.2"
-    ci-info: "npm:^4.2.0"
-    graceful-fs: "npm:^4.2.11"
-    picomatch: "npm:^4.0.2"
-  checksum: 10c0/896d663554b35258a87ec1a0a0fdd8741fdf4f3239d09fc52fdd88fa5c411a5ece7903bbbbd7d5194743fcb69f62afc3287e90f57736a91e7df95ad421937936
-  languageName: node
-  linkType: hard
-
-"jest-validate@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-validate@npm:30.2.0"
-  dependencies:
-    "@jest/get-type": "npm:30.1.0"
-    "@jest/types": "npm:30.2.0"
-    camelcase: "npm:^6.3.0"
-    chalk: "npm:^4.1.2"
-    leven: "npm:^3.1.0"
-    pretty-format: "npm:30.2.0"
-  checksum: 10c0/56566643d79ca07f021fa14cebb62c423ae405757cb8d742113ff0070f0761b80c77f665fac8d89622faaab71fc5452e1471939028187a88c8445303d7976255
-  languageName: node
-  linkType: hard
-
-"jest-watcher@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-watcher@npm:30.2.0"
-  dependencies:
-    "@jest/test-result": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    "@types/node": "npm:*"
-    ansi-escapes: "npm:^4.3.2"
-    chalk: "npm:^4.1.2"
-    emittery: "npm:^0.13.1"
-    jest-util: "npm:30.2.0"
-    string-length: "npm:^4.0.2"
-  checksum: 10c0/51587968fabb5b180383d638a04db253b82d9cc3f53fbba06ba7b0544146178d50becc090aca7931e2d4eb9aa1624bb3fbd1a2571484c9391554404e8b5d8fe7
-  languageName: node
-  linkType: hard
-
-"jest-worker@npm:30.2.0":
-  version: 30.2.0
-  resolution: "jest-worker@npm:30.2.0"
-  dependencies:
-    "@types/node": "npm:*"
-    "@ungap/structured-clone": "npm:^1.3.0"
-    jest-util: "npm:30.2.0"
-    merge-stream: "npm:^2.0.0"
-    supports-color: "npm:^8.1.1"
-  checksum: 10c0/1ea47f6c682ba6cdbd50630544236aabccacf1d88335607206c10871a9777a45b0fc6336c8eb6344e32e69dd7681de17b2199b4d4552b00d48aade303627125c
-  languageName: node
-  linkType: hard
-
-"jest@npm:^30.2.0":
-  version: 30.2.0
-  resolution: "jest@npm:30.2.0"
-  dependencies:
-    "@jest/core": "npm:30.2.0"
-    "@jest/types": "npm:30.2.0"
-    import-local: "npm:^3.2.0"
-    jest-cli: "npm:30.2.0"
-  peerDependencies:
-    node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-  peerDependenciesMeta:
-    node-notifier:
-      optional: true
-  bin:
-    jest: ./bin/jest.js
-  checksum: 10c0/af580c6e265d21870c2c98e31f17f2f5cb5c9e6cf9be26b95eaf4fad4140a01579f3b5844d4264cd8357eb24908e95f983ea84d20b8afef46e62aed3dd9452eb
-  languageName: node
-  linkType: hard
-
 "jju@npm:~1.4.0":
   version: 1.4.0
   resolution: "jju@npm:1.4.0"
@@ -5244,25 +3394,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"js-tokens@npm:^4.0.0":
-  version: 4.0.0
-  resolution: "js-tokens@npm:4.0.0"
-  checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed
-  languageName: node
-  linkType: hard
-
-"js-yaml@npm:^3.13.1":
-  version: 3.14.1
-  resolution: "js-yaml@npm:3.14.1"
-  dependencies:
-    argparse: "npm:^1.0.7"
-    esprima: "npm:^4.0.0"
-  bin:
-    js-yaml: bin/js-yaml.js
-  checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b
-  languageName: node
-  linkType: hard
-
 "js-yaml@npm:^4.1.0":
   version: 4.1.0
   resolution: "js-yaml@npm:4.1.0"
@@ -5274,15 +3405,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"jsesc@npm:^3.0.2":
-  version: 3.1.0
-  resolution: "jsesc@npm:3.1.0"
-  bin:
-    jsesc: bin/jsesc
-  checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1
-  languageName: node
-  linkType: hard
-
 "json-buffer@npm:3.0.1":
   version: 3.0.1
   resolution: "json-buffer@npm:3.0.1"
@@ -5290,13 +3412,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"json-parse-even-better-errors@npm:^2.3.0":
-  version: 2.3.1
-  resolution: "json-parse-even-better-errors@npm:2.3.1"
-  checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3
-  languageName: node
-  linkType: hard
-
 "json-schema-traverse@npm:^0.4.1":
   version: 0.4.1
   resolution: "json-schema-traverse@npm:0.4.1"
@@ -5329,15 +3444,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"json5@npm:^2.2.3":
-  version: 2.2.3
-  resolution: "json5@npm:2.2.3"
-  bin:
-    json5: lib/cli.js
-  checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c
-  languageName: node
-  linkType: hard
-
 "jsonfile@npm:^6.0.1":
   version: 6.2.0
   resolution: "jsonfile@npm:6.2.0"
@@ -5367,13 +3473,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"leven@npm:^3.1.0":
-  version: 3.1.0
-  resolution: "leven@npm:3.1.0"
-  checksum: 10c0/cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df
-  languageName: node
-  linkType: hard
-
 "levn@npm:^0.4.1":
   version: 0.4.1
   resolution: "levn@npm:0.4.1"
@@ -5384,13 +3483,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"lines-and-columns@npm:^1.1.6":
-  version: 1.2.4
-  resolution: "lines-and-columns@npm:1.2.4"
-  checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d
-  languageName: node
-  linkType: hard
-
 "linkify-it@npm:^5.0.0":
   version: 5.0.0
   resolution: "linkify-it@npm:5.0.0"
@@ -5411,15 +3503,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"locate-path@npm:^5.0.0":
-  version: 5.0.0
-  resolution: "locate-path@npm:5.0.0"
-  dependencies:
-    p-locate: "npm:^4.1.0"
-  checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59
-  languageName: node
-  linkType: hard
-
 "locate-path@npm:^6.0.0":
   version: 6.0.0
   resolution: "locate-path@npm:6.0.0"
@@ -5429,13 +3512,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"lodash.memoize@npm:^4.1.2":
-  version: 4.1.2
-  resolution: "lodash.memoize@npm:4.1.2"
-  checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8
-  languageName: node
-  linkType: hard
-
 "lodash.merge@npm:^4.6.2":
   version: 4.6.2
   resolution: "lodash.merge@npm:4.6.2"
@@ -5450,6 +3526,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"log-symbols@npm:^4.1.0":
+  version: 4.1.0
+  resolution: "log-symbols@npm:4.1.0"
+  dependencies:
+    chalk: "npm:^4.1.0"
+    is-unicode-supported: "npm:^0.1.0"
+  checksum: 10c0/67f445a9ffa76db1989d0fa98586e5bc2fd5247260dafb8ad93d9f0ccd5896d53fb830b0e54dade5ad838b9de2006c826831a3c528913093af20dff8bd24aca6
+  languageName: node
+  linkType: hard
+
 "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0":
   version: 10.4.3
   resolution: "lru-cache@npm:10.4.3"
@@ -5464,15 +3550,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"lru-cache@npm:^5.1.1":
-  version: 5.1.1
-  resolution: "lru-cache@npm:5.1.1"
-  dependencies:
-    yallist: "npm:^3.0.2"
-  checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482
-  languageName: node
-  linkType: hard
-
 "lru-cache@npm:^6.0.0":
   version: 6.0.0
   resolution: "lru-cache@npm:6.0.0"
@@ -5491,23 +3568,14 @@ __metadata:
 
 "magic-string@npm:^0.30.17":
   version: 0.30.19
-  resolution: "magic-string@npm:0.30.19"
-  dependencies:
-    "@jridgewell/sourcemap-codec": "npm:^1.5.5"
-  checksum: 10c0/db23fd2e2ee98a1aeb88a4cdb2353137fcf05819b883c856dd79e4c7dfb25151e2a5a4d5dbd88add5e30ed8ae5c51bcf4accbc6becb75249d924ec7b4fbcae27
-  languageName: node
-  linkType: hard
-
-"make-dir@npm:^4.0.0":
-  version: 4.0.0
-  resolution: "make-dir@npm:4.0.0"
+  resolution: "magic-string@npm:0.30.19"
   dependencies:
-    semver: "npm:^7.5.3"
-  checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68
+    "@jridgewell/sourcemap-codec": "npm:^1.5.5"
+  checksum: 10c0/db23fd2e2ee98a1aeb88a4cdb2353137fcf05819b883c856dd79e4c7dfb25151e2a5a4d5dbd88add5e30ed8ae5c51bcf4accbc6becb75249d924ec7b4fbcae27
   languageName: node
   linkType: hard
 
-"make-error@npm:^1.1.1, make-error@npm:^1.3.6":
+"make-error@npm:^1.1.1":
   version: 1.3.6
   resolution: "make-error@npm:1.3.6"
   checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f
@@ -5553,15 +3621,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"makeerror@npm:1.0.12":
-  version: 1.0.12
-  resolution: "makeerror@npm:1.0.12"
-  dependencies:
-    tmpl: "npm:1.0.5"
-  checksum: 10c0/b0e6e599780ce6bab49cc413eba822f7d1f0dfebd1c103eaa3785c59e43e22c59018323cf9e1708f0ef5329e94a745d163fcbb6bff8e4c6742f9be9e86f3500c
-  languageName: node
-  linkType: hard
-
 "markdown-it@npm:^14.1.0":
   version: 14.1.0
   resolution: "markdown-it@npm:14.1.0"
@@ -5592,13 +3651,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"merge-stream@npm:^2.0.0":
-  version: 2.0.0
-  resolution: "merge-stream@npm:2.0.0"
-  checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5
-  languageName: node
-  linkType: hard
-
 "merge2@npm:^1.3.0":
   version: 1.4.1
   resolution: "merge2@npm:1.4.1"
@@ -5616,13 +3668,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"mimic-fn@npm:^2.1.0":
-  version: 2.1.0
-  resolution: "mimic-fn@npm:2.1.0"
-  checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4
-  languageName: node
-  linkType: hard
-
 "mimic-response@npm:^3.1.0":
   version: 3.1.0
   resolution: "mimic-response@npm:3.1.0"
@@ -5639,7 +3684,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
+"minimatch@npm:^3.1.2":
   version: 3.1.2
   resolution: "minimatch@npm:3.1.2"
   dependencies:
@@ -5657,7 +3702,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
+"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6":
   version: 1.2.8
   resolution: "minimist@npm:1.2.8"
   checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
@@ -5800,6 +3845,38 @@ __metadata:
   languageName: node
   linkType: hard
 
+"mocha@npm:^11.7.4":
+  version: 11.7.4
+  resolution: "mocha@npm:11.7.4"
+  dependencies:
+    browser-stdout: "npm:^1.3.1"
+    chokidar: "npm:^4.0.1"
+    debug: "npm:^4.3.5"
+    diff: "npm:^7.0.0"
+    escape-string-regexp: "npm:^4.0.0"
+    find-up: "npm:^5.0.0"
+    glob: "npm:^10.4.5"
+    he: "npm:^1.2.0"
+    is-path-inside: "npm:^3.0.3"
+    js-yaml: "npm:^4.1.0"
+    log-symbols: "npm:^4.1.0"
+    minimatch: "npm:^9.0.5"
+    ms: "npm:^2.1.3"
+    picocolors: "npm:^1.1.1"
+    serialize-javascript: "npm:^6.0.2"
+    strip-json-comments: "npm:^3.1.1"
+    supports-color: "npm:^8.1.1"
+    workerpool: "npm:^9.2.0"
+    yargs: "npm:^17.7.2"
+    yargs-parser: "npm:^21.1.1"
+    yargs-unparser: "npm:^2.0.0"
+  bin:
+    _mocha: bin/_mocha
+    mocha: bin/mocha.js
+  checksum: 10c0/f84252dd93b7d67e20e3ca09c6be0da77d43795d502132a976450c5c19025de632bbaab6751dd1d8fd6311a3063d2f3647e61db84feb17900995d52e01cfb3b8
+  languageName: node
+  linkType: hard
+
 "ms@npm:^2.1.1, ms@npm:^2.1.3":
   version: 2.1.3
   resolution: "ms@npm:2.1.3"
@@ -5839,15 +3916,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"napi-postinstall@npm:^0.3.0":
-  version: 0.3.3
-  resolution: "napi-postinstall@npm:0.3.3"
-  bin:
-    napi-postinstall: lib/cli.js
-  checksum: 10c0/3f3297c002abd1f1c64730c442e9047e4b50335666bd2821e990e0546ab917f9cd000d3837930a81dbe89075495e884ed526918a85667abeef0654f659217cea
-  languageName: node
-  linkType: hard
-
 "natural-compare@npm:^1.4.0":
   version: 1.4.0
   resolution: "natural-compare@npm:1.4.0"
@@ -5869,13 +3937,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"neo-async@npm:^2.6.2":
-  version: 2.6.2
-  resolution: "neo-async@npm:2.6.2"
-  checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d
-  languageName: node
-  linkType: hard
-
 "node-abi@npm:^3.3.0, node-abi@npm:^3.71.0":
   version: 3.77.0
   resolution: "node-abi@npm:3.77.0"
@@ -5925,20 +3986,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"node-int64@npm:^0.4.0":
-  version: 0.4.0
-  resolution: "node-int64@npm:0.4.0"
-  checksum: 10c0/a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a
-  languageName: node
-  linkType: hard
-
-"node-releases@npm:^2.0.21":
-  version: 2.0.23
-  resolution: "node-releases@npm:2.0.23"
-  checksum: 10c0/3fdcddb574a9d56c050469b027f3fd2b8830fd321edd12f34b862969b67d0a3d6713eb2af8916f91618d555354f6c7bd33ae39e3b37117b1e7ddf2e42bc3f4be
-  languageName: node
-  linkType: hard
-
 "nopt@npm:^7.0.0":
   version: 7.2.1
   resolution: "nopt@npm:7.2.1"
@@ -5961,22 +4008,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"normalize-path@npm:^3.0.0":
-  version: 3.0.0
-  resolution: "normalize-path@npm:3.0.0"
-  checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046
-  languageName: node
-  linkType: hard
-
-"npm-run-path@npm:^4.0.1":
-  version: 4.0.1
-  resolution: "npm-run-path@npm:4.0.1"
-  dependencies:
-    path-key: "npm:^3.0.0"
-  checksum: 10c0/6f9353a95288f8455cf64cbeb707b28826a7f29690244c1e4bb61ec573256e021b6ad6651b394eb1ccfd00d6ec50147253aba2c5fe58a57ceb111fad62c519ac
-  languageName: node
-  linkType: hard
-
 "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4":
   version: 1.13.4
   resolution: "object-inspect@npm:1.13.4"
@@ -6040,7 +4071,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
+"once@npm:^1.3.1, once@npm:^1.4.0":
   version: 1.4.0
   resolution: "once@npm:1.4.0"
   dependencies:
@@ -6049,15 +4080,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"onetime@npm:^5.1.2":
-  version: 5.1.2
-  resolution: "onetime@npm:5.1.2"
-  dependencies:
-    mimic-fn: "npm:^2.1.0"
-  checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f
-  languageName: node
-  linkType: hard
-
 "optionator@npm:^0.9.3":
   version: 0.9.4
   resolution: "optionator@npm:0.9.4"
@@ -6092,16 +4114,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"p-limit@npm:^2.2.0":
-  version: 2.3.0
-  resolution: "p-limit@npm:2.3.0"
-  dependencies:
-    p-try: "npm:^2.0.0"
-  checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12
-  languageName: node
-  linkType: hard
-
-"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0":
+"p-limit@npm:^3.0.2":
   version: 3.1.0
   resolution: "p-limit@npm:3.1.0"
   dependencies:
@@ -6110,15 +4123,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"p-locate@npm:^4.1.0":
-  version: 4.1.0
-  resolution: "p-locate@npm:4.1.0"
-  dependencies:
-    p-limit: "npm:^2.2.0"
-  checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9
-  languageName: node
-  linkType: hard
-
 "p-locate@npm:^5.0.0":
   version: 5.0.0
   resolution: "p-locate@npm:5.0.0"
@@ -6144,13 +4148,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"p-try@npm:^2.0.0":
-  version: 2.2.0
-  resolution: "p-try@npm:2.2.0"
-  checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f
-  languageName: node
-  linkType: hard
-
 "package-json-from-dist@npm:^1.0.0":
   version: 1.0.1
   resolution: "package-json-from-dist@npm:1.0.1"
@@ -6167,18 +4164,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"parse-json@npm:^5.2.0":
-  version: 5.2.0
-  resolution: "parse-json@npm:5.2.0"
-  dependencies:
-    "@babel/code-frame": "npm:^7.0.0"
-    error-ex: "npm:^1.3.1"
-    json-parse-even-better-errors: "npm:^2.3.0"
-    lines-and-columns: "npm:^1.1.6"
-  checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585
-  languageName: node
-  linkType: hard
-
 "path-browserify@npm:^1.0.1":
   version: 1.0.1
   resolution: "path-browserify@npm:1.0.1"
@@ -6193,14 +4178,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"path-is-absolute@npm:^1.0.0":
-  version: 1.0.1
-  resolution: "path-is-absolute@npm:1.0.1"
-  checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078
-  languageName: node
-  linkType: hard
-
-"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
+"path-key@npm:^3.1.0":
   version: 3.1.1
   resolution: "path-key@npm:3.1.1"
   checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c
@@ -6248,7 +4226,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"picomatch@npm:^2.0.4, picomatch@npm:^2.3.1":
+"picomatch@npm:^2.3.1":
   version: 2.3.1
   resolution: "picomatch@npm:2.3.1"
   checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
@@ -6262,22 +4240,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"pirates@npm:^4.0.7":
-  version: 4.0.7
-  resolution: "pirates@npm:4.0.7"
-  checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a
-  languageName: node
-  linkType: hard
-
-"pkg-dir@npm:^4.2.0":
-  version: 4.2.0
-  resolution: "pkg-dir@npm:4.2.0"
-  dependencies:
-    find-up: "npm:^4.0.0"
-  checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728
-  languageName: node
-  linkType: hard
-
 "pkg-types@npm:^1.3.1":
   version: 1.3.1
   resolution: "pkg-types@npm:1.3.1"
@@ -6356,17 +4318,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"pretty-format@npm:30.2.0, pretty-format@npm:^30.0.0":
-  version: 30.2.0
-  resolution: "pretty-format@npm:30.2.0"
-  dependencies:
-    "@jest/schemas": "npm:30.0.5"
-    ansi-styles: "npm:^5.2.0"
-    react-is: "npm:^18.3.1"
-  checksum: 10c0/8fdacfd281aa98124e5df80b2c17223fdcb84433876422b54863a6849381b3059eb42b9806d92d2853826bcb966bcb98d499bea5b1e912d869a3c3107fd38d35
-  languageName: node
-  linkType: hard
-
 "proc-log@npm:^4.1.0, proc-log@npm:^4.2.0":
   version: 4.2.0
   resolution: "proc-log@npm:4.2.0"
@@ -6415,13 +4366,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"pure-rand@npm:^7.0.0":
-  version: 7.0.1
-  resolution: "pure-rand@npm:7.0.1"
-  checksum: 10c0/9cade41030f5ec95f5d55a11a71404cd6f46b69becaad892097cd7f58e2c6248cd0a933349ca7d21336ab629f1da42ffe899699b671bc4651600eaf6e57f837e
-  languageName: node
-  linkType: hard
-
 "quansync@npm:^0.2.11":
   version: 0.2.11
   resolution: "quansync@npm:0.2.11"
@@ -6436,6 +4380,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"randombytes@npm:^2.1.0":
+  version: 2.1.0
+  resolution: "randombytes@npm:2.1.0"
+  dependencies:
+    safe-buffer: "npm:^5.1.0"
+  checksum: 10c0/50395efda7a8c94f5dffab564f9ff89736064d32addf0cc7e8bf5e4166f09f8ded7a0849ca6c2d2a59478f7d90f78f20d8048bca3cdf8be09d8e8a10790388f3
+  languageName: node
+  linkType: hard
+
 "rc@npm:^1.2.7":
   version: 1.2.8
   resolution: "rc@npm:1.2.8"
@@ -6450,13 +4403,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"react-is@npm:^18.3.1":
-  version: 18.3.1
-  resolution: "react-is@npm:18.3.1"
-  checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072
-  languageName: node
-  linkType: hard
-
 "readable-stream@npm:>=1.0.33-1 <1.1.0-0":
   version: 1.0.34
   resolution: "readable-stream@npm:1.0.34"
@@ -6480,6 +4426,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"readdirp@npm:^4.0.1":
+  version: 4.1.2
+  resolution: "readdirp@npm:4.1.2"
+  checksum: 10c0/60a14f7619dec48c9c850255cd523e2717001b0e179dc7037cfa0895da7b9e9ab07532d324bfb118d73a710887d1e35f79c495fa91582784493e085d18c72c62
+  languageName: node
+  linkType: hard
+
 "reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9":
   version: 1.0.10
   resolution: "reflect.getprototypeof@npm:1.0.10"
@@ -6524,15 +4477,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"resolve-cwd@npm:^3.0.0":
-  version: 3.0.0
-  resolution: "resolve-cwd@npm:3.0.0"
-  dependencies:
-    resolve-from: "npm:^5.0.0"
-  checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4
-  languageName: node
-  linkType: hard
-
 "resolve-from@npm:^4.0.0":
   version: 4.0.0
   resolution: "resolve-from@npm:4.0.0"
@@ -6540,10 +4484,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"resolve-from@npm:^5.0.0":
-  version: 5.0.0
-  resolution: "resolve-from@npm:5.0.0"
-  checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2
+"resolve-pkg-maps@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "resolve-pkg-maps@npm:1.0.0"
+  checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab
   languageName: node
   linkType: hard
 
@@ -6702,7 +4646,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0":
+"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0":
   version: 5.2.1
   resolution: "safe-buffer@npm:5.2.1"
   checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3
@@ -6746,7 +4690,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.2":
+"semver@npm:^7.3.5":
   version: 7.7.2
   resolution: "semver@npm:7.7.2"
   bin:
@@ -6775,6 +4719,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"serialize-javascript@npm:^6.0.2":
+  version: 6.0.2
+  resolution: "serialize-javascript@npm:6.0.2"
+  dependencies:
+    randombytes: "npm:^2.1.0"
+  checksum: 10c0/2dd09ef4b65a1289ba24a788b1423a035581bef60817bea1f01eda8e3bda623f86357665fe7ac1b50f6d4f583f97db9615b3f07b2a2e8cbcb75033965f771dd2
+  languageName: node
+  linkType: hard
+
 "set-function-length@npm:^1.2.2":
   version: 1.2.2
   resolution: "set-function-length@npm:1.2.2"
@@ -6876,13 +4829,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"signal-exit@npm:^3.0.3":
-  version: 3.0.7
-  resolution: "signal-exit@npm:3.0.7"
-  checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912
-  languageName: node
-  linkType: hard
-
 "signal-exit@npm:^4.0.1":
   version: 4.1.0
   resolution: "signal-exit@npm:4.1.0"
@@ -6908,13 +4854,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"slash@npm:^3.0.0":
-  version: 3.0.0
-  resolution: "slash@npm:3.0.0"
-  checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b
-  languageName: node
-  linkType: hard
-
 "smart-buffer@npm:^4.2.0":
   version: 4.2.0
   resolution: "smart-buffer@npm:4.2.0"
@@ -6950,17 +4889,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"source-map-support@npm:0.5.13":
-  version: 0.5.13
-  resolution: "source-map-support@npm:0.5.13"
-  dependencies:
-    buffer-from: "npm:^1.0.0"
-    source-map: "npm:^0.6.0"
-  checksum: 10c0/137539f8c453fa0f496ea42049ab5da4569f96781f6ac8e5bfda26937be9494f4e8891f523c5f98f0e85f71b35d74127a00c46f83f6a4f54672b58d53202565e
-  languageName: node
-  linkType: hard
-
-"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1":
+"source-map@npm:~0.6.1":
   version: 0.6.1
   resolution: "source-map@npm:0.6.1"
   checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011
@@ -6992,15 +4921,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"stack-utils@npm:^2.0.6":
-  version: 2.0.6
-  resolution: "stack-utils@npm:2.0.6"
-  dependencies:
-    escape-string-regexp: "npm:^2.0.0"
-  checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a
-  languageName: node
-  linkType: hard
-
 "stop-iteration-iterator@npm:^1.1.0":
   version: 1.1.0
   resolution: "stop-iteration-iterator@npm:1.1.0"
@@ -7029,16 +4949,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"string-length@npm:^4.0.2":
-  version: 4.0.2
-  resolution: "string-length@npm:4.0.2"
-  dependencies:
-    char-regex: "npm:^1.0.2"
-    strip-ansi: "npm:^6.0.0"
-  checksum: 10c0/1cd77409c3d7db7bc59406f6bcc9ef0783671dcbabb23597a1177c166906ef2ee7c8290f78cae73a8aec858768f189d2cb417797df5e15ec4eb5e16b3346340c
-  languageName: node
-  linkType: hard
-
 "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3":
   version: 4.2.3
   resolution: "string-width@npm:4.2.3"
@@ -7140,20 +5050,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"strip-bom@npm:^4.0.0":
-  version: 4.0.0
-  resolution: "strip-bom@npm:4.0.0"
-  checksum: 10c0/26abad1172d6bc48985ab9a5f96c21e440f6e7e476686de49be813b5a59b3566dccb5c525b831ec54fe348283b47f3ffb8e080bc3f965fde12e84df23f6bb7ef
-  languageName: node
-  linkType: hard
-
-"strip-final-newline@npm:^2.0.0":
-  version: 2.0.0
-  resolution: "strip-final-newline@npm:2.0.0"
-  checksum: 10c0/bddf8ccd47acd85c0e09ad7375409d81653f645fda13227a9d459642277c253d877b68f2e5e4d819fe75733b0e626bac7e954c04f3236f6d196f79c94fa4a96f
-  languageName: node
-  linkType: hard
-
 "strip-json-comments@npm:^3.1.1, strip-json-comments@npm:~3.1.1":
   version: 3.1.1
   resolution: "strip-json-comments@npm:3.1.1"
@@ -7193,15 +5089,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"synckit@npm:^0.11.8":
-  version: 0.11.11
-  resolution: "synckit@npm:0.11.11"
-  dependencies:
-    "@pkgr/core": "npm:^0.2.9"
-  checksum: 10c0/f0761495953d12d94a86edf6326b3a565496c72f9b94c02549b6961fb4d999f4ca316ce6b3eb8ed2e4bfc5056a8de65cda0bd03a233333a35221cd2fdc0e196b
-  languageName: node
-  linkType: hard
-
 "tar-fs@npm:^2.0.0":
   version: 2.1.4
   resolution: "tar-fs@npm:2.1.4"
@@ -7254,17 +5141,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"test-exclude@npm:^6.0.0":
-  version: 6.0.0
-  resolution: "test-exclude@npm:6.0.0"
-  dependencies:
-    "@istanbuljs/schema": "npm:^0.1.2"
-    glob: "npm:^7.1.4"
-    minimatch: "npm:^3.0.4"
-  checksum: 10c0/019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57
-  languageName: node
-  linkType: hard
-
 "text-decoder@npm:^1.1.0":
   version: 1.2.3
   resolution: "text-decoder@npm:1.2.3"
@@ -7294,13 +5170,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"tmpl@npm:1.0.5":
-  version: 1.0.5
-  resolution: "tmpl@npm:1.0.5"
-  checksum: 10c0/f935537799c2d1922cb5d6d3805f594388f75338fe7a4a9dac41504dd539704ca4db45b883b52e7b0aa5b2fd5ddadb1452bf95cd23a69da2f793a843f9451cc9
-  languageName: node
-  linkType: hard
-
 "to-regex-range@npm:^5.0.1":
   version: 5.0.1
   resolution: "to-regex-range@npm:5.0.1"
@@ -7315,18 +5184,17 @@ __metadata:
   resolution: "torch@workspace:."
   dependencies:
     "@eslint/js": "npm:^9.37.0"
-    "@types/jest": "npm:^30.0.0"
+    "@types/mocha": "npm:^10.0.10"
     "@types/node": "npm:^24.6.2"
     "@veehz/gpu.js": "npm:^2.16.0"
+    chai: "npm:^6.2.0"
     eslint: "npm:^9.37.0"
     eslint-plugin-import: "npm:^2.32.0"
-    eslint-plugin-jest: "npm:^29.0.1"
-    jest: "npm:^30.2.0"
-    jest-util: "npm:^30.2.0"
+    mocha: "npm:^11.7.4"
     prettier: "npm:^3.6.2"
     rimraf: "npm:^6.0.1"
-    ts-jest: "npm:^29.4.4"
     ts-node: "npm:^10.9.2"
+    tsx: "npm:^4.20.6"
     typedoc: "npm:^0.28.14"
     typescript: "npm:^5.9.3"
     typescript-eslint: "npm:^8.46.0"
@@ -7344,46 +5212,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ts-jest@npm:^29.4.4":
-  version: 29.4.4
-  resolution: "ts-jest@npm:29.4.4"
-  dependencies:
-    bs-logger: "npm:^0.2.6"
-    fast-json-stable-stringify: "npm:^2.1.0"
-    handlebars: "npm:^4.7.8"
-    json5: "npm:^2.2.3"
-    lodash.memoize: "npm:^4.1.2"
-    make-error: "npm:^1.3.6"
-    semver: "npm:^7.7.2"
-    type-fest: "npm:^4.41.0"
-    yargs-parser: "npm:^21.1.1"
-  peerDependencies:
-    "@babel/core": ">=7.0.0-beta.0 <8"
-    "@jest/transform": ^29.0.0 || ^30.0.0
-    "@jest/types": ^29.0.0 || ^30.0.0
-    babel-jest: ^29.0.0 || ^30.0.0
-    jest: ^29.0.0 || ^30.0.0
-    jest-util: ^29.0.0 || ^30.0.0
-    typescript: ">=4.3 <6"
-  peerDependenciesMeta:
-    "@babel/core":
-      optional: true
-    "@jest/transform":
-      optional: true
-    "@jest/types":
-      optional: true
-    babel-jest:
-      optional: true
-    esbuild:
-      optional: true
-    jest-util:
-      optional: true
-  bin:
-    ts-jest: cli.js
-  checksum: 10c0/f99d612704cda98369f4a54d3db771bad5edd1390fded4f1691f3182f0c8ce8b7f827e5846952bd8bcd26df26c9fb18f11089de760956bdf357875a5f1d49fcc
-  languageName: node
-  linkType: hard
-
 "ts-node@npm:^10.9.2":
   version: 10.9.2
   resolution: "ts-node@npm:10.9.2"
@@ -7434,10 +5262,19 @@ __metadata:
   languageName: node
   linkType: hard
 
-"tslib@npm:^2.4.0":
-  version: 2.8.1
-  resolution: "tslib@npm:2.8.1"
-  checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
+"tsx@npm:^4.20.6":
+  version: 4.20.6
+  resolution: "tsx@npm:4.20.6"
+  dependencies:
+    esbuild: "npm:~0.25.0"
+    fsevents: "npm:~2.3.3"
+    get-tsconfig: "npm:^4.7.5"
+  dependenciesMeta:
+    fsevents:
+      optional: true
+  bin:
+    tsx: dist/cli.mjs
+  checksum: 10c0/07757a9bf62c271e0a00869b2008c5f2d6e648766536e4faf27d9d8027b7cde1ac8e4871f4bb570c99388bcee0018e6869dad98c07df809b8052f9c549cd216f
   languageName: node
   linkType: hard
 
@@ -7459,27 +5296,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"type-detect@npm:4.0.8":
-  version: 4.0.8
-  resolution: "type-detect@npm:4.0.8"
-  checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd
-  languageName: node
-  linkType: hard
-
-"type-fest@npm:^0.21.3":
-  version: 0.21.3
-  resolution: "type-fest@npm:0.21.3"
-  checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8
-  languageName: node
-  linkType: hard
-
-"type-fest@npm:^4.41.0":
-  version: 4.41.0
-  resolution: "type-fest@npm:4.41.0"
-  checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4
-  languageName: node
-  linkType: hard
-
 "typed-array-buffer@npm:^1.0.3":
   version: 1.0.3
   resolution: "typed-array-buffer@npm:1.0.3"
@@ -7619,15 +5435,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"uglify-js@npm:^3.1.4":
-  version: 3.19.3
-  resolution: "uglify-js@npm:3.19.3"
-  bin:
-    uglifyjs: bin/uglifyjs
-  checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479
-  languageName: node
-  linkType: hard
-
 "unbox-primitive@npm:^1.1.0":
   version: 1.1.0
   resolution: "unbox-primitive@npm:1.1.0"
@@ -7690,87 +5497,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"unrs-resolver@npm:^1.7.11":
-  version: 1.11.1
-  resolution: "unrs-resolver@npm:1.11.1"
-  dependencies:
-    "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1"
-    "@unrs/resolver-binding-android-arm64": "npm:1.11.1"
-    "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1"
-    "@unrs/resolver-binding-darwin-x64": "npm:1.11.1"
-    "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1"
-    "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1"
-    "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1"
-    "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1"
-    "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1"
-    "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1"
-    napi-postinstall: "npm:^0.3.0"
-  dependenciesMeta:
-    "@unrs/resolver-binding-android-arm-eabi":
-      optional: true
-    "@unrs/resolver-binding-android-arm64":
-      optional: true
-    "@unrs/resolver-binding-darwin-arm64":
-      optional: true
-    "@unrs/resolver-binding-darwin-x64":
-      optional: true
-    "@unrs/resolver-binding-freebsd-x64":
-      optional: true
-    "@unrs/resolver-binding-linux-arm-gnueabihf":
-      optional: true
-    "@unrs/resolver-binding-linux-arm-musleabihf":
-      optional: true
-    "@unrs/resolver-binding-linux-arm64-gnu":
-      optional: true
-    "@unrs/resolver-binding-linux-arm64-musl":
-      optional: true
-    "@unrs/resolver-binding-linux-ppc64-gnu":
-      optional: true
-    "@unrs/resolver-binding-linux-riscv64-gnu":
-      optional: true
-    "@unrs/resolver-binding-linux-riscv64-musl":
-      optional: true
-    "@unrs/resolver-binding-linux-s390x-gnu":
-      optional: true
-    "@unrs/resolver-binding-linux-x64-gnu":
-      optional: true
-    "@unrs/resolver-binding-linux-x64-musl":
-      optional: true
-    "@unrs/resolver-binding-wasm32-wasi":
-      optional: true
-    "@unrs/resolver-binding-win32-arm64-msvc":
-      optional: true
-    "@unrs/resolver-binding-win32-ia32-msvc":
-      optional: true
-    "@unrs/resolver-binding-win32-x64-msvc":
-      optional: true
-  checksum: 10c0/c91b112c71a33d6b24e5c708dab43ab80911f2df8ee65b87cd7a18fb5af446708e98c4b415ca262026ad8df326debcc7ca6a801b2935504d87fd6f0b9d70dce1
-  languageName: node
-  linkType: hard
-
-"update-browserslist-db@npm:^1.1.3":
-  version: 1.1.3
-  resolution: "update-browserslist-db@npm:1.1.3"
-  dependencies:
-    escalade: "npm:^3.2.0"
-    picocolors: "npm:^1.1.1"
-  peerDependencies:
-    browserslist: ">= 4.21.0"
-  bin:
-    update-browserslist-db: cli.js
-  checksum: 10c0/682e8ecbf9de474a626f6462aa85927936cdd256fe584c6df2508b0df9f7362c44c957e9970df55dfe44d3623807d26316ea2c7d26b80bb76a16c56c37233c32
-  languageName: node
-  linkType: hard
-
 "uri-js@npm:^4.2.2, uri-js@npm:^4.4.1":
   version: 4.4.1
   resolution: "uri-js@npm:4.4.1"
@@ -7794,17 +5520,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"v8-to-istanbul@npm:^9.0.1":
-  version: 9.3.0
-  resolution: "v8-to-istanbul@npm:9.3.0"
-  dependencies:
-    "@jridgewell/trace-mapping": "npm:^0.3.12"
-    "@types/istanbul-lib-coverage": "npm:^2.0.1"
-    convert-source-map: "npm:^2.0.0"
-  checksum: 10c0/968bcf1c7c88c04df1ffb463c179558a2ec17aa49e49376120504958239d9e9dad5281aa05f2a78542b8557f2be0b0b4c325710262f3b838b40d703d5ed30c23
-  languageName: node
-  linkType: hard
-
 "vite-plugin-dts@npm:^4.5.4":
   version: 4.5.4
   resolution: "vite-plugin-dts@npm:4.5.4"
@@ -7890,15 +5605,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"walker@npm:^1.0.8":
-  version: 1.0.8
-  resolution: "walker@npm:1.0.8"
-  dependencies:
-    makeerror: "npm:1.0.12"
-  checksum: 10c0/a17e037bccd3ca8a25a80cb850903facdfed0de4864bd8728f1782370715d679fa72e0a0f5da7c1c1379365159901e5935f35be531229da53bbfc0efdabdb48e
-  languageName: node
-  linkType: hard
-
 "webgpu@npm:0.2.9":
   version: 0.2.9
   resolution: "webgpu@npm:0.2.9"
@@ -8009,10 +5715,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"wordwrap@npm:^1.0.0":
-  version: 1.0.0
-  resolution: "wordwrap@npm:1.0.0"
-  checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92
+"workerpool@npm:^9.2.0":
+  version: 9.3.4
+  resolution: "workerpool@npm:9.3.4"
+  checksum: 10c0/b09d80c81c6e50dab1bc6cc3a4180d4222068f17ada9b04fb7053bf98fdbe3dbd6bdd04ad1420363f5391cbf57d622ecd2680469ad0137aef990f510ab807a09
   languageName: node
   linkType: hard
 
@@ -8045,16 +5751,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"write-file-atomic@npm:^5.0.1":
-  version: 5.0.1
-  resolution: "write-file-atomic@npm:5.0.1"
-  dependencies:
-    imurmurhash: "npm:^0.1.4"
-    signal-exit: "npm:^4.0.1"
-  checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d
-  languageName: node
-  linkType: hard
-
 "xtend@npm:>=4.0.0 <4.1.0-0":
   version: 4.0.2
   resolution: "xtend@npm:4.0.2"
@@ -8069,13 +5765,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"yallist@npm:^3.0.2":
-  version: 3.1.1
-  resolution: "yallist@npm:3.1.1"
-  checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1
-  languageName: node
-  linkType: hard
-
 "yallist@npm:^4.0.0":
   version: 4.0.0
   resolution: "yallist@npm:4.0.0"
@@ -8106,6 +5795,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"yargs-unparser@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "yargs-unparser@npm:2.0.0"
+  dependencies:
+    camelcase: "npm:^6.0.0"
+    decamelize: "npm:^4.0.0"
+    flat: "npm:^5.0.2"
+    is-plain-obj: "npm:^2.1.0"
+  checksum: 10c0/a5a7d6dc157efa95122e16780c019f40ed91d4af6d2bac066db8194ed0ec5c330abb115daa5a79ff07a9b80b8ea80c925baacf354c4c12edd878c0529927ff03
+  languageName: node
+  linkType: hard
+
 "yargs@npm:^17.7.2":
   version: 17.7.2
   resolution: "yargs@npm:17.7.2"

From e42a0ca446934ec6d7002832a92cad0e0b02a9ba Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 19:37:45 +0800
Subject: [PATCH 029/128] add NOTICE and gpu.js license

---
 NOTICE                                | 28 +++++++++++++++++++++++++++
 vendor/gpu-browser.LICENSE.txt        | 21 ++++++++++++++++++++
 {public => vendor}/gpu-browser.min.js |  0
 vite.config.browser.ts                |  2 +-
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 NOTICE
 create mode 100644 vendor/gpu-browser.LICENSE.txt
 rename {public => vendor}/gpu-browser.min.js (100%)

diff --git a/NOTICE b/NOTICE
new file mode 100644
index 00000000..c1a7b88c
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,28 @@
+This project contains documentation strings, comments, and third-party
+libraries that are governed by their own licenses.
+
+================================================================================
+This project includes GPU.js, which is licensed under the MIT License.
+The original license is included below:
+
+The MIT License
+
+Copyright (c) 2019 gpu.js Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/gpu-browser.LICENSE.txt b/vendor/gpu-browser.LICENSE.txt
new file mode 100644
index 00000000..7930df93
--- /dev/null
+++ b/vendor/gpu-browser.LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2019 gpu.js Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/public/gpu-browser.min.js b/vendor/gpu-browser.min.js
similarity index 100%
rename from public/gpu-browser.min.js
rename to vendor/gpu-browser.min.js
diff --git a/vite.config.browser.ts b/vite.config.browser.ts
index 2e5f901f..e85187b5 100644
--- a/vite.config.browser.ts
+++ b/vite.config.browser.ts
@@ -33,7 +33,7 @@ export default defineConfig({
   },
   resolve: {
     alias: {
-      'gpu.js': path.resolve(__dirname, './public/gpu-browser.min.js'),
+      'gpu.js': path.resolve(__dirname, './vendor/gpu-browser.min.js'),
     },
   },
 });

From afe4f3c9f91d9b747884625a9174e0494781736e Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 13 Oct 2025 19:38:05 +0800
Subject: [PATCH 030/128] feat: reshape operation

---
 src/operations/base.ts       |  2 +-
 src/operations/functional.ts |  1 +
 src/operations/ops.gen.ts    | 29 +++++++++++++++++++++++++++++
 src/operations/ops.ts.j2     | 29 +++++++++++++++++++++++++++++
 src/tensor.ts                |  6 +++++-
 test/tensor.test.js          | 11 +++++++++--
 6 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/src/operations/base.ts b/src/operations/base.ts
index c75d40ce..2d249466 100644
--- a/src/operations/base.ts
+++ b/src/operations/base.ts
@@ -1,7 +1,7 @@
 import { Tensor } from '../tensor';
 
 abstract class Operation {
-  abstract forward(...args: (Tensor | number)[]): Tensor;
+  abstract forward(...args: (Tensor | number | number[])[]): Tensor;
   abstract backward(dz: Tensor): void;
 }
 
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 1a5ee8fc..8e071be4 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -52,6 +52,7 @@ export const abs = generate_unary_function('abs');
 export const sign = generate_unary_function('sign');
 export const neg = generate_unary_function('neg');
 export const reciprocal = generate_unary_function('reciprocal');
+export const reshape = generate_function('reshape');
 
 // trigonometric
 
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 5ea1f262..49ebcb51 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -657,6 +657,35 @@ export class Reciprocal extends UnaryOperation {
 }
 registerOperation('reciprocal', Reciprocal);
 
+export class Reshape extends Operation {
+  private cache: [Tensor];
+  public forward(a: Tensor, shape: number[]) {
+    const previous_length = a.dataLength();
+    const target_length = shape.reduce((acc, val) => acc * val, 1);
+
+    if (previous_length !== target_length) {
+      throw new Error('Shape mismatch: ' + a.shape + ' and ' + shape);
+    }
+
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+
+    return new Tensor(
+      a.data,
+      { requires_grad: a.requires_grad },
+      { operation: a.requires_grad ? this : null, shape }
+    );
+  }
+  public backward(dz: Tensor) {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.reshape(a.shape));
+  }
+}
+registerOperation('reshape', Reshape);
+
 // trigonometric
 
 // function generated from unary_op_base("sin", "Math.sin(a[this.thread.x])")
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index 19c486d2..b159b93e 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -98,6 +98,35 @@ registerOperation('powint', PowInt);
 {{ unary_op_base("reciprocal", "1 / a[this.thread.x]") }}
 {{ unary_op_class("Reciprocal", "reciprocal", ["a.backward(dz.mul(a.pow(-2)));"]) }}
 
+export class Reshape extends Operation {
+  private cache: [Tensor];
+  public forward(a: Tensor, shape: number[]) {
+    const previous_length = a.dataLength();
+    const target_length = shape.reduce((acc, val) => acc * val, 1);
+
+    if (previous_length !== target_length) {
+      throw new Error('Shape mismatch: ' + a.shape + ' and ' + shape);
+    }
+
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+
+    return new Tensor(
+      a.data,
+      { requires_grad: a.requires_grad },
+      { operation: a.requires_grad ? this : null, shape }
+    );
+  }
+  public backward(dz: Tensor) {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.reshape(a.shape));
+  }
+}
+registerOperation('reshape', Reshape);
+
 // trigonometric
 
 {{ unary_op_base("sin", "Math.sin(a[this.thread.x])") }}
diff --git a/src/tensor.ts b/src/tensor.ts
index cc4d76a3..c724c984 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -232,7 +232,11 @@ export class Tensor {
   reciprocal(): Tensor {
     return this._executeUnaryOp('reciprocal');
   }
-  
+
+  reshape(shape: number[]): Tensor {
+    return this._executeOpRaw('reshape', shape);
+  }
+ 
   // trigonometric
 
   sin(): Tensor {
diff --git a/test/tensor.test.js b/test/tensor.test.js
index d0ac90cf..d13df820 100644
--- a/test/tensor.test.js
+++ b/test/tensor.test.js
@@ -34,8 +34,6 @@ describe('Tensor', () => {
       const t2 = new Tensor([1]);
       const result = t1.add(t2);
 
-      console.log('shsh', result.shape, result.toArray());
-
       assert.deepStrictEqual(Array.from(result.toArray()), [11, 21, 31]);
       assert.deepStrictEqual(result.shape, [3]);
     });
@@ -102,4 +100,13 @@ describe('Tensor', () => {
       assert.deepStrictEqual(result.shape, [2, 3]);
     });
   });
+
+  describe('Reshape', () => {
+    it('should reshape a tensor', () => {
+      const t = new Tensor([1, 2, 3, 4]);
+      const result = t.reshape([2, 2]);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4]);
+      assert.deepStrictEqual(result.shape, [2, 2]);
+    });
+  });
 });

From ec5b617a50a7f78d641f08252d41397ed584bc7f Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 15 Oct 2025 13:23:45 +0800
Subject: [PATCH 031/128] refactor: creation operations

---
 src/creation/index.ts        | 60 ++----------------------------------
 src/creation/initializers.ts | 16 ++++++++++
 src/creation/rand.ts         | 26 ++++++++++++++++
 src/creation/ranges.ts       | 19 ++++++++++++
 src/creation/utils.ts        |  7 +++++
 5 files changed, 71 insertions(+), 57 deletions(-)
 create mode 100644 src/creation/initializers.ts
 create mode 100644 src/creation/rand.ts
 create mode 100644 src/creation/ranges.ts
 create mode 100644 src/creation/utils.ts

diff --git a/src/creation/index.ts b/src/creation/index.ts
index 64f51490..8eb4eb86 100644
--- a/src/creation/index.ts
+++ b/src/creation/index.ts
@@ -1,57 +1,3 @@
-import { Tensor } from '../tensor';
-
-export function linspace(start: number, end: number, steps: number) {
-  const data = [];
-  const step = (end - start) / (steps - 1);
-  for (let i = 0; i < steps - 1; i++) {
-    data.push(start + i * step);
-  }
-  data.push(end);
-  return new Tensor(data);
-}
-
-function get_shape_from_args(args: number[] | number[][]): number[] {
-  if (Array.isArray(args[0])) {
-    return args[0];
-  }
-
-  return args as number[];
-}
-
-export function ones(...args: number[] | number[][]): Tensor {
-  const shape = get_shape_from_args(args);
-  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(1));
-  tensor.shape = shape;
-  return tensor;
-}
-
-export function zeros(...args: number[] | number[][]): Tensor {
-  const shape = get_shape_from_args(args);
-  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(0));
-  tensor.shape = shape;
-  return tensor;
-}
-
-/* TODO: use the correct distributions */
-
-export function randn(...args: number[] | number[][]): Tensor {
-  const shape = get_shape_from_args(args);
-  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.random()));
-  tensor.shape = shape;
-  return tensor;
-}
-
-export function rand(...args: number[] | number[][]): Tensor {
-  const shape = get_shape_from_args(args);
-  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.random()));
-  tensor.shape = shape;
-  return tensor;
-}
-
-export function randint(low: number, high: number, shape: number[]): Tensor {
-  const tensor = new Tensor(
-    Array(shape.reduce((a, b) => a * b, 1)).fill(Math.floor(Math.random() * (high - low) + low))
-  );
-  tensor.shape = shape;
-  return tensor;
-}
+export * from './rand';
+export * from './initializers';
+export * from './ranges';
diff --git a/src/creation/initializers.ts b/src/creation/initializers.ts
new file mode 100644
index 00000000..8252385f
--- /dev/null
+++ b/src/creation/initializers.ts
@@ -0,0 +1,16 @@
+import { Tensor } from '../tensor';
+import { get_shape_from_args } from './utils';
+
+export function ones(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(1));
+  tensor.shape = shape;
+  return tensor;
+}
+
+export function zeros(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(0));
+  tensor.shape = shape;
+  return tensor;
+}
diff --git a/src/creation/rand.ts b/src/creation/rand.ts
new file mode 100644
index 00000000..6d38d066
--- /dev/null
+++ b/src/creation/rand.ts
@@ -0,0 +1,26 @@
+import { Tensor } from '../tensor';
+import { get_shape_from_args } from './utils';
+
+/* TODO: use the correct distributions */
+
+export function randn(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.random()));
+  tensor.shape = shape;
+  return tensor;
+}
+
+export function rand(...args: number[] | number[][]): Tensor {
+  const shape = get_shape_from_args(args);
+  const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(Math.random()));
+  tensor.shape = shape;
+  return tensor;
+}
+
+export function randint(low: number, high: number, shape: number[]): Tensor {
+  const tensor = new Tensor(
+    Array(shape.reduce((a, b) => a * b, 1)).fill(Math.floor(Math.random() * (high - low) + low))
+  );
+  tensor.shape = shape;
+  return tensor;
+}
diff --git a/src/creation/ranges.ts b/src/creation/ranges.ts
new file mode 100644
index 00000000..7a92a403
--- /dev/null
+++ b/src/creation/ranges.ts
@@ -0,0 +1,19 @@
+import { Tensor } from '../tensor';
+
+export function linspace(start: number, end: number, steps: number) {
+  const data = [];
+  const step = (end - start) / (steps - 1);
+  for (let i = 0; i < steps - 1; i++) {
+    data.push(start + i * step);
+  }
+  data.push(end);
+  return new Tensor(data);
+}
+
+export function arange(start: number, end: number = undefined, step: number = 1) {
+  const data = [];
+  for (let i = start; i < end; i += step) {
+    data.push(i);
+  }
+  return new Tensor(data);
+}
\ No newline at end of file
diff --git a/src/creation/utils.ts b/src/creation/utils.ts
new file mode 100644
index 00000000..3120c4b7
--- /dev/null
+++ b/src/creation/utils.ts
@@ -0,0 +1,7 @@
+export function get_shape_from_args(args: number[] | number[][]): number[] {
+  if (Array.isArray(args[0])) {
+    return args[0];
+  }
+
+  return args as number[];
+}

From 4f64679e36b7191d2d521f2620fc141cc2bc0c66 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 15 Oct 2025 13:31:25 +0800
Subject: [PATCH 032/128] feat: unsqueeze operation

---
 src/operations/functional.ts |  1 +
 src/operations/ops.gen.ts    | 29 +++++++++++++++
 src/operations/ops.ts.j2     | 29 +++++++++++++++
 src/tensor.ts                |  6 +++-
 test/tensor.test.js          | 70 ++++++++++++++++++++++++++++++++++++
 5 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 8e071be4..6fcf47d3 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -53,6 +53,7 @@ export const sign = generate_unary_function('sign');
 export const neg = generate_unary_function('neg');
 export const reciprocal = generate_unary_function('reciprocal');
 export const reshape = generate_function('reshape');
+export const unsqueeze = generate_function('unsqueeze');
 
 // trigonometric
 
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 49ebcb51..744415ed 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -686,6 +686,35 @@ export class Reshape extends Operation {
 }
 registerOperation('reshape', Reshape);
 
+export class Unsqueeze extends Operation {
+  private cache: [Tensor];
+  public forward(a: Tensor, dim: number) {
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+
+    if (dim < 0) {
+      dim += a.shape.length + 1;
+    }
+
+    const shape = [...a.shape];
+    shape.splice(dim, 0, 1);
+
+    return new Tensor(
+      a.data,
+      { requires_grad: a.requires_grad },
+      { operation: a.requires_grad ? this : null, shape }
+    );
+  }
+  public backward(dz: Tensor) {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.reshape(a.shape));
+  }
+}
+registerOperation('unsqueeze', Unsqueeze);
+
 // trigonometric
 
 // function generated from unary_op_base("sin", "Math.sin(a[this.thread.x])")
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index b159b93e..e05a8def 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -127,6 +127,35 @@ export class Reshape extends Operation {
 }
 registerOperation('reshape', Reshape);
 
+export class Unsqueeze extends Operation {
+  private cache: [Tensor];
+  public forward(a: Tensor, dim: number) {
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+
+    if (dim < 0) {
+      dim += a.shape.length + 1;
+    }
+
+    const shape = [...a.shape];
+    shape.splice(dim, 0, 1);
+
+    return new Tensor(
+      a.data,
+      { requires_grad: a.requires_grad },
+      { operation: a.requires_grad ? this : null, shape }
+    );
+  }
+  public backward(dz: Tensor) {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.reshape(a.shape));
+  }
+}
+registerOperation('unsqueeze', Unsqueeze);
+
 // trigonometric
 
 {{ unary_op_base("sin", "Math.sin(a[this.thread.x])") }}
diff --git a/src/tensor.ts b/src/tensor.ts
index c724c984..b0895b6e 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -236,7 +236,11 @@ export class Tensor {
   reshape(shape: number[]): Tensor {
     return this._executeOpRaw('reshape', shape);
   }
- 
+
+  unsqueeze(dim: number): Tensor {
+    return this._executeOpRaw('unsqueeze', dim);
+  }
+
   // trigonometric
 
   sin(): Tensor {
diff --git a/test/tensor.test.js b/test/tensor.test.js
index d13df820..f7ca3174 100644
--- a/test/tensor.test.js
+++ b/test/tensor.test.js
@@ -108,5 +108,75 @@ describe('Tensor', () => {
       assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4]);
       assert.deepStrictEqual(result.shape, [2, 2]);
     });
+
+    it('should not reshape a tensor if the shape is not compatible', () => {
+      const t = new Tensor([1, 2, 3, 4]);
+      assert.throws(() => t.reshape([2, 3]), Error);
+    });
+
+    it('should reshape a tensor with different dimensions', () => {
+      const t = new Tensor([1, 2, 3, 4, 5, 6]);
+      const result = t.reshape([2, 3]);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [2, 3]);
+
+      const result2 = t.reshape([3, 2]);
+      assert.deepStrictEqual(Array.from(result2.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result2.shape, [3, 2]);
+
+      const result3 = t.reshape([6]);
+      assert.deepStrictEqual(Array.from(result3.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result3.shape, [6]);
+
+      const result4 = t.reshape([1, 2, 3]);
+      assert.deepStrictEqual(Array.from(result4.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result4.shape, [1, 2, 3]);
+    });
+  });
+
+  describe('Unsqueeze', () => {
+    it('should unsqueeze a tensor', () => {
+      const t = new Tensor([1, 2, 3]);
+      let result = t.unsqueeze(0);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]);
+      assert.deepStrictEqual(result.shape, [1, 3]);
+
+      let s = new Tensor([1, 2, 3, 4, 5, 6]);
+      s = s.reshape([2, 3]);
+
+      result = s.unsqueeze(0);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [1, 2, 3]);
+
+      result = s.unsqueeze(1);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [2, 1, 3]);
+
+      result = s.unsqueeze(2);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [2, 3, 1]);
+    });
+
+    it('should unsqueeze a tensor with negative dimension', () => {
+      const t = new Tensor([1, 2, 3]);
+      let result = t.unsqueeze(-1);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]);
+      assert.deepStrictEqual(result.shape, [3, 1]);
+
+      let s = new Tensor([1, 2, 3, 4, 5, 6]);
+      s = s.reshape([2, 3]);
+
+      result = s.unsqueeze(-3);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [1, 2, 3]);
+
+      result = s.unsqueeze(-2);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [2, 1, 3]);
+
+      result = s.unsqueeze(-1);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]);
+      assert.deepStrictEqual(result.shape, [2, 3, 1]);
+    });
   });
 });

From 6aab5fc082ae33fd90b8fb724b5b8180f65cf04f Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 15 Oct 2025 13:31:45 +0800
Subject: [PATCH 033/128] feat: test template

---
 test/template.test.js | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 test/template.test.js

diff --git a/test/template.test.js b/test/template.test.js
new file mode 100644
index 00000000..b31b9c0f
--- /dev/null
+++ b/test/template.test.js
@@ -0,0 +1,12 @@
+import { assert } from 'chai';
+import { Tensor } from 'torch';
+
+describe('Tensor', () => {
+  describe('Constructor', () => {
+    it('should create a tensor with correct data and shape', () => {
+      const tensor = new Tensor([10, 20, 30]);
+      assert.deepStrictEqual(tensor.data, [10, 20, 30]);
+      assert.deepStrictEqual(tensor.shape, [3]);
+    });
+  });
+});
\ No newline at end of file

From 83f960ddd7ac461a01deb4173c24b99b5c83ef6f Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 15 Oct 2025 13:33:05 +0800
Subject: [PATCH 034/128] feat: development scripts with watch

---
 package.json | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/package.json b/package.json
index 84207d45..5d7b0583 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,9 @@
   "scripts": {
     "clean": "rimraf build",
     "build:browser": "vite build --config vite.config.browser.ts",
+    "build:browser:watch": "vite build --config vite.config.browser.ts --watch",
     "build:node": "vite build --config vite.config.node.ts",
+    "build:node:watch": "vite build --config vite.config.node.ts --watch",
     "build": "npm run clean && npm run build:node && npm run build:browser",
     "docs": "typedoc --out docs src",
     "generate": "python3 scripts/generate.py",

From 29702f42f077622802ccfc50ac8fdae2988a251b Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 15 Oct 2025 13:42:33 +0800
Subject: [PATCH 035/128] docs: pytorch docs license

---
 NOTICE | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/NOTICE b/NOTICE
index c1a7b88c..201c2bec 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,8 +1,50 @@
-This project contains documentation strings, comments, and third-party
-libraries that are governed by their own licenses.
+This project's licensing is Apache-2.0. It includes components
+governed by other licenses, which are detailed below.
 
 ================================================================================
-This project includes GPU.js, which is licensed under the MIT License.
+1. PyTorch Documentation (BSD-3-Clause license)
+
+https://github.com/pytorch/docs
+
+Portions of this project's documentation are derived from the PyTorch documentation.
+The original PyTorch documentation license is included below:
+
+BSD 3-Clause License
+
+Copyright (c) 2018, Facebook Inc
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+================================================================================
+2. GPU.js (MIT License)
+
+https://github.com/gpujs/gpu.js
+
+This project includes GPU.js to enable GPU acceleration.
 The original license is included below:
 
 The MIT License
@@ -25,4 +67,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
+THE SOFTWARE.

From ea51460f25b5b8a6159aea184f33566053294b01 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 15 Oct 2025 14:15:58 +0800
Subject: [PATCH 036/128] feat: yarn serve and yarn watch

---
 README.md                   |  16 ++-
 examples/browser/index.html |   2 -
 package.json                |   6 +-
 scripts/requirements.txt    |   1 +
 yarn.lock                   | 241 ++++++++++++++++++++++++++++++++++--
 5 files changed, 249 insertions(+), 17 deletions(-)
 create mode 100644 scripts/requirements.txt

diff --git a/README.md b/README.md
index 3e44ba6a..3f1f950f 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ node examples/basic_backpropagation.js
 You can run `http-server` and load `examples/browser/index.html` to see how it works.
 
 ```bash
-npx http-server --cors=* -c-1 .
+yarn serve
 # and navigate to http://localhost:8080/examples/browser/index.html to run torch in js
 # or http://localhost:8080/examples/pyodide/index.html to run in python
 # or http://localhost:8080/test/ to run the tests
@@ -48,4 +48,16 @@ npx http-server --cors=* -c-1 .
 
 Files ending with `.ts.j2` are generated by jinja to `.gen.ts`, using `scripts/generate.py`.
 
-Do not edit `.gen.ts` directly, instead edit the `.ts.j2` files.
\ No newline at end of file
+Thus, Python is required to run `scripts/generate.py`,
+which also requires `Jinja2` (see `scripts/requirements.txt`).
+
+Do not edit `.gen.ts` directly, instead edit the `.ts.j2` files.
+
+### Development Scripts
+
+You can use `yarn watch` to automatically test after each edit.
+
+Note that it does not automatically regenerate `.gen.ts` files when editing `.ts.j2` files.
+You will have to run `yarn generate` or `python3 scripts/generate.py`.
+
+This is to allow for testing in `.gen.ts` files before moving the edits to `.ts.j2`.
\ No newline at end of file
diff --git a/examples/browser/index.html b/examples/browser/index.html
index 920e8bfb..96c9c455 100644
--- a/examples/browser/index.html
+++ b/examples/browser/index.html
@@ -5,8 +5,6 @@
   
   
   torch.js browser backprop example
-  
-  
   
   
 
diff --git a/package.json b/package.json
index 5d7b0583..a20016bd 100644
--- a/package.json
+++ b/package.json
@@ -32,16 +32,20 @@
     "build": "npm run clean && npm run build:node && npm run build:browser",
     "docs": "typedoc --out docs src",
     "generate": "python3 scripts/generate.py",
+    "serve": "http-server -p 8080 -c-1 .",
     "test": "mocha test/**/*.test.ts test/**/*.test.js",
-    "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js"
+    "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js",
+    "watch": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\""
   },
   "devDependencies": {
     "@eslint/js": "^9.37.0",
     "@types/mocha": "^10.0.10",
     "@types/node": "^24.6.2",
     "chai": "^6.2.0",
+    "concurrently": "^9.2.1",
     "eslint": "^9.37.0",
     "eslint-plugin-import": "^2.32.0",
+    "http-server": "^14.1.1",
     "mocha": "^11.7.4",
     "prettier": "^3.6.2",
     "rimraf": "^6.0.1",
diff --git a/scripts/requirements.txt b/scripts/requirements.txt
new file mode 100644
index 00000000..bb0794f9
--- /dev/null
+++ b/scripts/requirements.txt
@@ -0,0 +1 @@
+Jinja2==3.1.2
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index a402cc6c..41d7eb92 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1479,6 +1479,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"async@npm:^3.2.6":
+  version: 3.2.6
+  resolution: "async@npm:3.2.6"
+  checksum: 10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70
+  languageName: node
+  linkType: hard
+
 "available-typed-arrays@npm:^1.0.7":
   version: 1.0.7
   resolution: "available-typed-arrays@npm:1.0.7"
@@ -1521,6 +1528,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"basic-auth@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "basic-auth@npm:2.0.1"
+  dependencies:
+    safe-buffer: "npm:5.1.2"
+  checksum: 10c0/05f56db3a0fc31c89c86b605231e32ee143fb6ae38dc60616bc0970ae6a0f034172def99e69d3aed0e2c9e7cac84e2d63bc51a0b5ff6ab5fc8808cc8b29923c1
+  languageName: node
+  linkType: hard
+
 "bindings@npm:^1.5.0":
   version: 1.5.0
   resolution: "bindings@npm:1.5.0"
@@ -1686,7 +1702,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"chalk@npm:^4.0.0, chalk@npm:^4.1.0":
+"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
   version: 4.1.2
   resolution: "chalk@npm:4.1.2"
   dependencies:
@@ -1774,6 +1790,23 @@ __metadata:
   languageName: node
   linkType: hard
 
+"concurrently@npm:^9.2.1":
+  version: 9.2.1
+  resolution: "concurrently@npm:9.2.1"
+  dependencies:
+    chalk: "npm:4.1.2"
+    rxjs: "npm:7.8.2"
+    shell-quote: "npm:1.8.3"
+    supports-color: "npm:8.1.1"
+    tree-kill: "npm:1.2.2"
+    yargs: "npm:17.7.2"
+  bin:
+    conc: dist/bin/concurrently.js
+    concurrently: dist/bin/concurrently.js
+  checksum: 10c0/da37f239f82eb7ac24f5ddb56259861e5f1d6da2ade7602b6ea7ad3101b13b5ccec02a77b7001402d1028ff2fdc38eed55644b32853ad5abf30e057002a963aa
+  languageName: node
+  linkType: hard
+
 "confbox@npm:^0.1.8":
   version: 0.1.8
   resolution: "confbox@npm:0.1.8"
@@ -1795,6 +1828,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"corser@npm:^2.0.1":
+  version: 2.0.1
+  resolution: "corser@npm:2.0.1"
+  checksum: 10c0/1f319a752a560342dd22d936e5a4c158bfcbc332524ef5b05a7277236dad8b0b2868fd5cf818559f29954ec4d777d82e797fccd76601fcfe431610e4143c8acc
+  languageName: node
+  linkType: hard
+
 "create-require@npm:^1.1.0":
   version: 1.1.1
   resolution: "create-require@npm:1.1.1"
@@ -1853,7 +1893,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"debug@npm:4, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0":
+"debug@npm:4, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:^4.4.0":
   version: 4.4.3
   resolution: "debug@npm:4.4.3"
   dependencies:
@@ -2423,6 +2463,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"eventemitter3@npm:^4.0.0":
+  version: 4.0.7
+  resolution: "eventemitter3@npm:4.0.7"
+  checksum: 10c0/5f6d97cbcbac47be798e6355e3a7639a84ee1f7d9b199a07017f1d2f1e2fe236004d14fa5dfaeba661f94ea57805385e326236a6debbc7145c8877fbc0297c6b
+  languageName: node
+  linkType: hard
+
 "events-universal@npm:^1.0.0":
   version: 1.0.1
   resolution: "events-universal@npm:1.0.1"
@@ -2583,6 +2630,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"follow-redirects@npm:^1.0.0":
+  version: 1.15.11
+  resolution: "follow-redirects@npm:1.15.11"
+  peerDependenciesMeta:
+    debug:
+      optional: true
+  checksum: 10c0/d301f430542520a54058d4aeeb453233c564aaccac835d29d15e050beb33f339ad67d9bddbce01739c5dc46a6716dbe3d9d0d5134b1ca203effa11a7ef092343
+  languageName: node
+  linkType: hard
+
 "for-each@npm:^0.3.3, for-each@npm:^0.3.5":
   version: 0.3.5
   resolution: "for-each@npm:0.3.5"
@@ -2949,6 +3006,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"html-encoding-sniffer@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "html-encoding-sniffer@npm:3.0.0"
+  dependencies:
+    whatwg-encoding: "npm:^2.0.0"
+  checksum: 10c0/b17b3b0fb5d061d8eb15121c3b0b536376c3e295ecaf09ba48dd69c6b6c957839db124fe1e2b3f11329753a4ee01aa7dedf63b7677999e86da17fbbdd82c5386
+  languageName: node
+  linkType: hard
+
 "http-cache-semantics@npm:^4.1.1":
   version: 4.2.0
   resolution: "http-cache-semantics@npm:4.2.0"
@@ -2966,6 +3032,40 @@ __metadata:
   languageName: node
   linkType: hard
 
+"http-proxy@npm:^1.18.1":
+  version: 1.18.1
+  resolution: "http-proxy@npm:1.18.1"
+  dependencies:
+    eventemitter3: "npm:^4.0.0"
+    follow-redirects: "npm:^1.0.0"
+    requires-port: "npm:^1.0.0"
+  checksum: 10c0/148dfa700a03fb421e383aaaf88ac1d94521dfc34072f6c59770528c65250983c2e4ec996f2f03aa9f3fe46cd1270a593126068319311e3e8d9e610a37533e94
+  languageName: node
+  linkType: hard
+
+"http-server@npm:^14.1.1":
+  version: 14.1.1
+  resolution: "http-server@npm:14.1.1"
+  dependencies:
+    basic-auth: "npm:^2.0.1"
+    chalk: "npm:^4.1.2"
+    corser: "npm:^2.0.1"
+    he: "npm:^1.2.0"
+    html-encoding-sniffer: "npm:^3.0.0"
+    http-proxy: "npm:^1.18.1"
+    mime: "npm:^1.6.0"
+    minimist: "npm:^1.2.6"
+    opener: "npm:^1.5.1"
+    portfinder: "npm:^1.0.28"
+    secure-compare: "npm:3.0.1"
+    union: "npm:~0.5.0"
+    url-join: "npm:^4.0.1"
+  bin:
+    http-server: bin/http-server
+  checksum: 10c0/c5770ddd722dd520ce0af25efee6bfb7c6300ff4e934636d4eec83fa995739e64de2e699e89e7a795b3a1894bcc37bec226617c1023600aacd7871fd8d6ffe6d
+  languageName: node
+  linkType: hard
+
 "https-proxy-agent@npm:^7.0.1":
   version: 7.0.6
   resolution: "https-proxy-agent@npm:7.0.6"
@@ -2976,7 +3076,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"iconv-lite@npm:^0.6.2":
+"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2":
   version: 0.6.3
   resolution: "iconv-lite@npm:0.6.3"
   dependencies:
@@ -3668,6 +3768,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"mime@npm:^1.6.0":
+  version: 1.6.0
+  resolution: "mime@npm:1.6.0"
+  bin:
+    mime: cli.js
+  checksum: 10c0/b92cd0adc44888c7135a185bfd0dddc42c32606401c72896a842ae15da71eb88858f17669af41e498b463cd7eb998f7b48939a25b08374c7924a9c8a6f8a81b0
+  languageName: node
+  linkType: hard
+
 "mimic-response@npm:^3.1.0":
   version: 3.1.0
   resolution: "mimic-response@npm:3.1.0"
@@ -4080,6 +4189,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"opener@npm:^1.5.1":
+  version: 1.5.2
+  resolution: "opener@npm:1.5.2"
+  bin:
+    opener: bin/opener-bin.js
+  checksum: 10c0/dd56256ab0cf796585617bc28e06e058adf09211781e70b264c76a1dbe16e90f868c974e5bf5309c93469157c7d14b89c35dc53fe7293b0e40b4d2f92073bc79
+  languageName: node
+  linkType: hard
+
 "optionator@npm:^0.9.3":
   version: 0.9.4
   resolution: "optionator@npm:0.9.4"
@@ -4262,6 +4380,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"portfinder@npm:^1.0.28":
+  version: 1.0.38
+  resolution: "portfinder@npm:1.0.38"
+  dependencies:
+    async: "npm:^3.2.6"
+    debug: "npm:^4.3.6"
+  checksum: 10c0/59b2f2aa0b620c90ce0d477241e62c277f38bfd4fb6074106c23560248dd5e5c2c629dd048ef721f32b19df4213d09b77234880e4f0ab04abf1ab70b6d8048fa
+  languageName: node
+  linkType: hard
+
 "possible-typed-array-names@npm:^1.0.0":
   version: 1.1.0
   resolution: "possible-typed-array-names@npm:1.1.0"
@@ -4366,6 +4494,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"qs@npm:^6.4.0":
+  version: 6.14.0
+  resolution: "qs@npm:6.14.0"
+  dependencies:
+    side-channel: "npm:^1.1.0"
+  checksum: 10c0/8ea5d91bf34f440598ee389d4a7d95820e3b837d3fd9f433871f7924801becaa0cd3b3b4628d49a7784d06a8aea9bc4554d2b6d8d584e2d221dc06238a42909c
+  languageName: node
+  linkType: hard
+
 "quansync@npm:^0.2.11":
   version: 0.2.11
   resolution: "quansync@npm:0.2.11"
@@ -4477,6 +4614,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"requires-port@npm:^1.0.0":
+  version: 1.0.0
+  resolution: "requires-port@npm:1.0.0"
+  checksum: 10c0/b2bfdd09db16c082c4326e573a82c0771daaf7b53b9ce8ad60ea46aa6e30aaf475fe9b164800b89f93b748d2c234d8abff945d2551ba47bf5698e04cd7713267
+  languageName: node
+  linkType: hard
+
 "resolve-from@npm:^4.0.0":
   version: 4.0.0
   resolution: "resolve-from@npm:4.0.0"
@@ -4633,6 +4777,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"rxjs@npm:7.8.2":
+  version: 7.8.2
+  resolution: "rxjs@npm:7.8.2"
+  dependencies:
+    tslib: "npm:^2.1.0"
+  checksum: 10c0/1fcd33d2066ada98ba8f21fcbbcaee9f0b271de1d38dc7f4e256bfbc6ffcdde68c8bfb69093de7eeb46f24b1fb820620bf0223706cff26b4ab99a7ff7b2e2c45
+  languageName: node
+  linkType: hard
+
 "safe-array-concat@npm:^1.1.3":
   version: 1.1.3
   resolution: "safe-array-concat@npm:1.1.3"
@@ -4646,6 +4799,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"safe-buffer@npm:5.1.2":
+  version: 5.1.2
+  resolution: "safe-buffer@npm:5.1.2"
+  checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21
+  languageName: node
+  linkType: hard
+
 "safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0":
   version: 5.2.1
   resolution: "safe-buffer@npm:5.2.1"
@@ -4681,6 +4841,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"secure-compare@npm:3.0.1":
+  version: 3.0.1
+  resolution: "secure-compare@npm:3.0.1"
+  checksum: 10c0/af3102f3f555d917c8ffff7a5f6f00f70195708f4faf82d48794485c9f3cb365cee0dd4da6b4e53e8964f172970bce6069b6101ba3ce8c309bff54f460d1f650
+  languageName: node
+  linkType: hard
+
 "semver@npm:^6.3.1":
   version: 6.3.1
   resolution: "semver@npm:6.3.1"
@@ -4781,6 +4948,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"shell-quote@npm:1.8.3":
+  version: 1.8.3
+  resolution: "shell-quote@npm:1.8.3"
+  checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd
+  languageName: node
+  linkType: hard
+
 "side-channel-list@npm:^1.0.0":
   version: 1.0.0
   resolution: "side-channel-list@npm:1.0.0"
@@ -5064,21 +5238,21 @@ __metadata:
   languageName: node
   linkType: hard
 
-"supports-color@npm:^7.1.0":
-  version: 7.2.0
-  resolution: "supports-color@npm:7.2.0"
+"supports-color@npm:8.1.1, supports-color@npm:^8.1.1, supports-color@npm:~8.1.1":
+  version: 8.1.1
+  resolution: "supports-color@npm:8.1.1"
   dependencies:
     has-flag: "npm:^4.0.0"
-  checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124
+  checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89
   languageName: node
   linkType: hard
 
-"supports-color@npm:^8.1.1, supports-color@npm:~8.1.1":
-  version: 8.1.1
-  resolution: "supports-color@npm:8.1.1"
+"supports-color@npm:^7.1.0":
+  version: 7.2.0
+  resolution: "supports-color@npm:7.2.0"
   dependencies:
     has-flag: "npm:^4.0.0"
-  checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89
+  checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124
   languageName: node
   linkType: hard
 
@@ -5188,8 +5362,10 @@ __metadata:
     "@types/node": "npm:^24.6.2"
     "@veehz/gpu.js": "npm:^2.16.0"
     chai: "npm:^6.2.0"
+    concurrently: "npm:^9.2.1"
     eslint: "npm:^9.37.0"
     eslint-plugin-import: "npm:^2.32.0"
+    http-server: "npm:^14.1.1"
     mocha: "npm:^11.7.4"
     prettier: "npm:^3.6.2"
     rimraf: "npm:^6.0.1"
@@ -5203,6 +5379,15 @@ __metadata:
   languageName: unknown
   linkType: soft
 
+"tree-kill@npm:1.2.2":
+  version: 1.2.2
+  resolution: "tree-kill@npm:1.2.2"
+  bin:
+    tree-kill: cli.js
+  checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2
+  languageName: node
+  linkType: hard
+
 "ts-api-utils@npm:^2.1.0":
   version: 2.1.0
   resolution: "ts-api-utils@npm:2.1.0"
@@ -5262,6 +5447,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"tslib@npm:^2.1.0":
+  version: 2.8.1
+  resolution: "tslib@npm:2.8.1"
+  checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
+  languageName: node
+  linkType: hard
+
 "tsx@npm:^4.20.6":
   version: 4.20.6
   resolution: "tsx@npm:4.20.6"
@@ -5454,6 +5646,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"union@npm:~0.5.0":
+  version: 0.5.0
+  resolution: "union@npm:0.5.0"
+  dependencies:
+    qs: "npm:^6.4.0"
+  checksum: 10c0/9ac158d99991063180e56f408f5991e808fa07594713439c098116da09215c154672ee8c832e16a6b39b037609c08bcaff8ff07c1e3e46c3cc622897972af2aa
+  languageName: node
+  linkType: hard
+
 "unique-filename@npm:^3.0.0":
   version: 3.0.0
   resolution: "unique-filename@npm:3.0.0"
@@ -5506,6 +5707,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"url-join@npm:^4.0.1":
+  version: 4.0.1
+  resolution: "url-join@npm:4.0.1"
+  checksum: 10c0/ac65e2c7c562d7b49b68edddcf55385d3e922bc1dd5d90419ea40b53b6de1607d1e45ceb71efb9d60da02c681d13c6cb3a1aa8b13fc0c989dfc219df97ee992d
+  languageName: node
+  linkType: hard
+
 "util-deprecate@npm:^1.0.1":
   version: 1.0.2
   resolution: "util-deprecate@npm:1.0.2"
@@ -5614,6 +5822,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"whatwg-encoding@npm:^2.0.0":
+  version: 2.0.0
+  resolution: "whatwg-encoding@npm:2.0.0"
+  dependencies:
+    iconv-lite: "npm:0.6.3"
+  checksum: 10c0/91b90a49f312dc751496fd23a7e68981e62f33afe938b97281ad766235c4872fc4e66319f925c5e9001502b3040dd25a33b02a9c693b73a4cbbfdc4ad10c3e3e
+  languageName: node
+  linkType: hard
+
 "which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1":
   version: 1.1.1
   resolution: "which-boxed-primitive@npm:1.1.1"
@@ -5807,7 +6024,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"yargs@npm:^17.7.2":
+"yargs@npm:17.7.2, yargs@npm:^17.7.2":
   version: 17.7.2
   resolution: "yargs@npm:17.7.2"
   dependencies:

From a678bbc3d0a40215af7ed0883fe4c6743f304993 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 19 Nov 2025 00:31:56 +0800
Subject: [PATCH 037/128] docs: copy examples to docs

---
 .github/workflows/push.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 0449bf2e..6dd63688 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -57,6 +57,9 @@ jobs:
         - name: Copy build to docs/build
           run: cp -r build docs/build
 
+        - name: Copy examples to docs/examples
+          run: cp -r examples docs/examples
+
         - name: Deploy docs
           uses: peaceiris/actions-gh-pages@v4
           with:

From 05057f21fc95be313e342c1d682ba76997cc7338 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Thu, 16 Oct 2025 11:04:01 +0800
Subject: [PATCH 038/128] fix: node builds

---
 package.json        | 8 ++++----
 vite.config.node.ts | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/package.json b/package.json
index a20016bd..5c853d2e 100644
--- a/package.json
+++ b/package.json
@@ -9,15 +9,15 @@
   "files": [
     "build"
   ],
-  "main": "./build/node/torch.node.cjs.js",
-  "module": "./build/node/torch.node.es.js",
+  "main": "./build/node/torch.node.cjs",
+  "module": "./build/node/torch.node.es.mjs",
   "types": "./build/types/src/index.d.ts",
   "exports": {
     ".": {
       "types": "./build/types/src/index.d.ts",
       "browser": "./build/browser/torch.browser.es.js",
-      "import": "./build/node/torch.node.es.js",
-      "require": "./build/node/torch.node.cjs.js"
+      "import": "./build/node/torch.node.es.mjs",
+      "require": "./build/node/torch.node.cjs"
     }
   },
   "mocha": {
diff --git a/vite.config.node.ts b/vite.config.node.ts
index fe637bf0..22ed2b7a 100644
--- a/vite.config.node.ts
+++ b/vite.config.node.ts
@@ -5,12 +5,12 @@ export default defineConfig({
   build: {
     lib: {
       entry: path.resolve(__dirname, 'src/index.ts'),
-      fileName: (format) => `torch.node.${format}.js`,
+      fileName: (format) => format === 'es' ? 'torch.node.es.mjs' : 'torch.node.cjs',
       formats: ['es', 'cjs']
     },
     rollupOptions: {
       // Don't bundle 'gpu.js'. The user's Node project will provide it.
-      external: ['gpu.js']
+      external: ['@veehz/gpu.js']
     },
     outDir: 'build/node',
     target: 'node20',

From 1934a2a6c0cd80a5e3bdcbf495184347195e8dcb Mon Sep 17 00:00:00 2001
From: veehz 
Date: Thu, 16 Oct 2025 11:49:56 +0800
Subject: [PATCH 039/128] feat: square operation

---
 src/operations/functional.ts |  1 +
 src/operations/ops.gen.ts    | 42 ++++++++++++++++++++++++++++++++++++
 src/operations/ops.ts.j2     |  3 +++
 src/tensor.ts                |  4 ++++
 4 files changed, 50 insertions(+)

diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 6fcf47d3..0244ce15 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -48,6 +48,7 @@ export const fmod = generate_binary_function('fmod');
 export const log = generate_unary_function('log');
 export const sqrt = generate_unary_function('sqrt');
 export const exp = generate_unary_function('exp');
+export const square = generate_unary_function('square');
 export const abs = generate_unary_function('abs');
 export const sign = generate_unary_function('sign');
 export const neg = generate_unary_function('neg');
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 744415ed..e2e72b2f 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -489,6 +489,48 @@ export class Exp extends UnaryOperation {
 }
 registerOperation('exp', Exp);
 
+// function generated from unary_op_base("square", "a[this.thread.x] * a[this.thread.x]")
+
+const _square_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return a[this.thread.x] * a[this.thread.x];
+  },
+  {
+    dynamicOutput: true,
+    dynamicArguments: true,
+    // pipeline: true,
+    // immutable: true
+  }
+);
+
+function _square_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = _square_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Square", "square", backward_operations)
+export class Square extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+    return _square_tensor(a, a.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a).mul(new Tensor(2)));
+  }
+}
+registerOperation('square', Square);
+
 // function generated from unary_op_base("abs", "Math.abs(a[this.thread.x])")
 
 const _abs_kernel = gpu.createKernel(
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index e05a8def..a340d717 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -86,6 +86,9 @@ registerOperation('powint', PowInt);
 {{ unary_op_base("exp", "Math.exp(a[this.thread.x])") }}
 {{ unary_op_class("Exp", "exp", ["a.backward(dz.mul(a.exp()));"]) }}
 
+{{ unary_op_base("square", "a[this.thread.x] * a[this.thread.x]") }}
+{{ unary_op_class("Square", "square", ["a.backward(dz.mul(a).mul(new Tensor(2)));"]) }}
+
 {{ unary_op_base("abs", "Math.abs(a[this.thread.x])") }}
 {{ unary_op_class("Abs", "abs", ["a.backward(dz.mul(functional.sign(a)));"]) }}
 
diff --git a/src/tensor.ts b/src/tensor.ts
index b0895b6e..3a7546f6 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -217,6 +217,10 @@ export class Tensor {
     return this._executeUnaryOp('exp');
   }
 
+  square(): Tensor {
+    return this._executeUnaryOp('square');
+  }
+
   abs(): Tensor {
     return this._executeUnaryOp('abs');
   }

From 3339ba73c100ab7b1180ab98287c5ce084182294 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Thu, 16 Oct 2025 11:50:15 +0800
Subject: [PATCH 040/128] feat: pyodide bridge

---
 examples/pyodide/bridge.py | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/examples/pyodide/bridge.py b/examples/pyodide/bridge.py
index caeb9cca..5151ded0 100644
--- a/examples/pyodide/bridge.py
+++ b/examples/pyodide/bridge.py
@@ -1,7 +1,21 @@
 # This is a very rough draft.
 
 # assume js_torch is available
-from pyodide.ffi import JsProxy
+from pyodide.ffi import JsProxy, to_js
+
+def _transform(obj):
+    if isinstance(obj, Tensor):
+        return obj.get_tensor()
+    elif isinstance(obj, list) or isinstance(obj, tuple):
+        return torch_utils.to_js_list(obj)
+    else:
+        return obj
+
+def _transform_args(args):
+    return list(map(_transform, args))
+
+def _transform_kwargs(kwargs):
+    return to_js({k: _transform(v) for k, v in kwargs.items()})
 
 class Tensor:
     # dealing with when .grad is None
@@ -96,23 +110,17 @@ def __iter__(self):
 
     def __getattr__(self, name):
         return lambda *args, **kwargs: Tensor(self.get_tensor().__getattribute__(name)(
-            *_transform_args(args),
-            *_transform_args(kwargs)
+            *_transform_args(args), _transform_kwargs(kwargs)
         ))
 
 class _NoGrad:
     def __enter__(self):
-        self.enabled = js_torch.getGradientTrackingEnabled()
-        js_torch.setGradientTrackingEnabled(False)
+        pass
 
     def __exit__(self, type, value, traceback):
-        js_torch.setGradientTrackingEnabled(self.enabled)
+        pass
 
 class _Torch:
-    _operations = [
-        "sin", "mean", "square", "abs", "relu", "ones_like", "linspace", "ones",
-    ]
-
     no_grad = _NoGrad
 
     @property
@@ -121,8 +129,7 @@ def tensor(self):
 
     def __getattr__(self, name):
         return lambda *args, **kwargs: Tensor(js_torch.__getattribute__(name)(
-            *_transform_args(args),
-            *_transform_args(kwargs)
+            *_transform_args(args), _transform_kwargs(kwargs)
         ))
 
     def Size(self, shape):

From 7c87b5e098e2715a6f13612904d03906ba51f55c Mon Sep 17 00:00:00 2001
From: veehz 
Date: Fri, 19 Dec 2025 16:49:39 +0800
Subject: [PATCH 041/128] feat: VS Code PnP SDKs

---
 .yarn/sdks/eslint/bin/eslint.js               | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/api.js                  | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/config-api.js           | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/types/config-api.d.ts   | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/types/index.d.ts        | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/types/rules.d.ts        | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/types/universal.d.ts    | 32 +++++++++++++++++++
 .../lib/types/use-at-your-own-risk.d.ts       | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/universal.js            | 32 +++++++++++++++++++
 .yarn/sdks/eslint/lib/unsupported-api.js      | 32 +++++++++++++++++++
 .yarn/sdks/eslint/package.json                | 31 ++++++++++++++++++
 .yarn/sdks/prettier/bin/prettier.cjs          | 32 +++++++++++++++++++
 .yarn/sdks/prettier/index.cjs                 | 32 +++++++++++++++++++
 .yarn/sdks/prettier/package.json              |  7 ++++
 14 files changed, 422 insertions(+)
 create mode 100755 .yarn/sdks/eslint/bin/eslint.js
 create mode 100644 .yarn/sdks/eslint/lib/api.js
 create mode 100644 .yarn/sdks/eslint/lib/config-api.js
 create mode 100644 .yarn/sdks/eslint/lib/types/config-api.d.ts
 create mode 100644 .yarn/sdks/eslint/lib/types/index.d.ts
 create mode 100644 .yarn/sdks/eslint/lib/types/rules.d.ts
 create mode 100644 .yarn/sdks/eslint/lib/types/universal.d.ts
 create mode 100644 .yarn/sdks/eslint/lib/types/use-at-your-own-risk.d.ts
 create mode 100644 .yarn/sdks/eslint/lib/universal.js
 create mode 100644 .yarn/sdks/eslint/lib/unsupported-api.js
 create mode 100644 .yarn/sdks/eslint/package.json
 create mode 100755 .yarn/sdks/prettier/bin/prettier.cjs
 create mode 100644 .yarn/sdks/prettier/index.cjs
 create mode 100644 .yarn/sdks/prettier/package.json

diff --git a/.yarn/sdks/eslint/bin/eslint.js b/.yarn/sdks/eslint/bin/eslint.js
new file mode 100755
index 00000000..e6604ff5
--- /dev/null
+++ b/.yarn/sdks/eslint/bin/eslint.js
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/bin/eslint.js
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/bin/eslint.js your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/bin/eslint.js`));
diff --git a/.yarn/sdks/eslint/lib/api.js b/.yarn/sdks/eslint/lib/api.js
new file mode 100644
index 00000000..8addf97f
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/api.js
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint`));
diff --git a/.yarn/sdks/eslint/lib/config-api.js b/.yarn/sdks/eslint/lib/config-api.js
new file mode 100644
index 00000000..e84435de
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/config-api.js
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/config
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/config your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/config`));
diff --git a/.yarn/sdks/eslint/lib/types/config-api.d.ts b/.yarn/sdks/eslint/lib/types/config-api.d.ts
new file mode 100644
index 00000000..174070b0
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/types/config-api.d.ts
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/config
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/config your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/config`));
diff --git a/.yarn/sdks/eslint/lib/types/index.d.ts b/.yarn/sdks/eslint/lib/types/index.d.ts
new file mode 100644
index 00000000..19293d02
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/types/index.d.ts
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint`));
diff --git a/.yarn/sdks/eslint/lib/types/rules.d.ts b/.yarn/sdks/eslint/lib/types/rules.d.ts
new file mode 100644
index 00000000..8d79c4cc
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/types/rules.d.ts
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/rules
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/rules your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/rules`));
diff --git a/.yarn/sdks/eslint/lib/types/universal.d.ts b/.yarn/sdks/eslint/lib/types/universal.d.ts
new file mode 100644
index 00000000..662b3f4f
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/types/universal.d.ts
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/universal
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/universal your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/universal`));
diff --git a/.yarn/sdks/eslint/lib/types/use-at-your-own-risk.d.ts b/.yarn/sdks/eslint/lib/types/use-at-your-own-risk.d.ts
new file mode 100644
index 00000000..2e2ccca2
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/types/use-at-your-own-risk.d.ts
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/use-at-your-own-risk
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/use-at-your-own-risk your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/use-at-your-own-risk`));
diff --git a/.yarn/sdks/eslint/lib/universal.js b/.yarn/sdks/eslint/lib/universal.js
new file mode 100644
index 00000000..85a8ccbc
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/universal.js
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/universal
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/universal your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/universal`));
diff --git a/.yarn/sdks/eslint/lib/unsupported-api.js b/.yarn/sdks/eslint/lib/unsupported-api.js
new file mode 100644
index 00000000..c2b464ce
--- /dev/null
+++ b/.yarn/sdks/eslint/lib/unsupported-api.js
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require eslint/use-at-your-own-risk
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real eslint/use-at-your-own-risk your application uses
+module.exports = wrapWithUserWrapper(absRequire(`eslint/use-at-your-own-risk`));
diff --git a/.yarn/sdks/eslint/package.json b/.yarn/sdks/eslint/package.json
new file mode 100644
index 00000000..840be3b6
--- /dev/null
+++ b/.yarn/sdks/eslint/package.json
@@ -0,0 +1,31 @@
+{
+  "name": "eslint",
+  "version": "9.37.0-sdk",
+  "main": "./lib/api.js",
+  "type": "commonjs",
+  "bin": {
+    "eslint": "./bin/eslint.js"
+  },
+  "exports": {
+    ".": {
+      "types": "./lib/types/index.d.ts",
+      "default": "./lib/api.js"
+    },
+    "./config": {
+      "types": "./lib/types/config-api.d.ts",
+      "default": "./lib/config-api.js"
+    },
+    "./package.json": "./package.json",
+    "./use-at-your-own-risk": {
+      "types": "./lib/types/use-at-your-own-risk.d.ts",
+      "default": "./lib/unsupported-api.js"
+    },
+    "./rules": {
+      "types": "./lib/types/rules.d.ts"
+    },
+    "./universal": {
+      "types": "./lib/types/universal.d.ts",
+      "default": "./lib/universal.js"
+    }
+  }
+}
diff --git a/.yarn/sdks/prettier/bin/prettier.cjs b/.yarn/sdks/prettier/bin/prettier.cjs
new file mode 100755
index 00000000..9a4098f7
--- /dev/null
+++ b/.yarn/sdks/prettier/bin/prettier.cjs
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require prettier/bin/prettier.cjs
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real prettier/bin/prettier.cjs your application uses
+module.exports = wrapWithUserWrapper(absRequire(`prettier/bin/prettier.cjs`));
diff --git a/.yarn/sdks/prettier/index.cjs b/.yarn/sdks/prettier/index.cjs
new file mode 100644
index 00000000..57cb2ab1
--- /dev/null
+++ b/.yarn/sdks/prettier/index.cjs
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+
+const {existsSync} = require(`fs`);
+const {createRequire, register} = require(`module`);
+const {resolve} = require(`path`);
+const {pathToFileURL} = require(`url`);
+
+const relPnpApiPath = "../../../.pnp.cjs";
+
+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
+const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
+const absRequire = createRequire(absPnpApiPath);
+
+const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
+const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
+
+if (existsSync(absPnpApiPath)) {
+  if (!process.versions.pnp) {
+    // Setup the environment to be able to require prettier
+    require(absPnpApiPath).setup();
+    if (isPnpLoaderEnabled && register) {
+      register(pathToFileURL(absPnpLoaderPath));
+    }
+  }
+}
+
+const wrapWithUserWrapper = existsSync(absUserWrapperPath)
+  ? exports => absRequire(absUserWrapperPath)(exports)
+  : exports => exports;
+
+// Defer to the real prettier your application uses
+module.exports = wrapWithUserWrapper(absRequire(`prettier`));
diff --git a/.yarn/sdks/prettier/package.json b/.yarn/sdks/prettier/package.json
new file mode 100644
index 00000000..1488e98c
--- /dev/null
+++ b/.yarn/sdks/prettier/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "prettier",
+  "version": "3.6.2-sdk",
+  "main": "./index.cjs",
+  "type": "commonjs",
+  "bin": "./bin/prettier.cjs"
+}

From b96994ffad9c1822813f390fe84d9c840dc82565 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Fri, 19 Dec 2025 16:50:52 +0800
Subject: [PATCH 042/128] fix j2

---
 src/operations/ops.ts.j2 | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index a340d717..705d5166 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -305,6 +305,11 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
   const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
 
   const kernel = _matmul_kernel;
+
+  {#- if(broadcast_shape.length < 2) { // shouldn't happen, but just in case
+    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
+  } #}
+
   kernel.setConstants({
     lp: loop_iterations,
     // assumes that _get_original_index_kernel reads from the front

From 00df4131262690c61c14a9095db0a94b8cd7a4f8 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 5 Jan 2026 14:30:47 +0800
Subject: [PATCH 043/128] docs: add documentation on codebase

---
 CONTRIBUTING.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
 README.md       | 18 ++--------------
 package.json    |  2 +-
 3 files changed, 59 insertions(+), 17 deletions(-)
 create mode 100644 CONTRIBUTING.md

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..0d2c92c8
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,56 @@
+## Codebase Structure
+
+- [`src`](src)
+    - [`index.ts`](src/index.ts) is the entry point of the library.
+    - [`tensor.ts`](src/tensor.ts) is the main tensor class.
+    - [`operations`](operations) contains all operations that tensors can perform.
+    - [`nn`](nn) contains all neural network modules (for everything under `torch.nn`).
+    - [`optim`](optim) contains all optimizers (for everything under `torch.optim`).
+    - [`creation`](creation) contains all tensor creation functions (all functions that create a tensor not from scratch, including `zeros`, `randn`).
+- [`examples`](examples) contains example usages of the library, including on node, on the browser, and using pyodide on the browser.
+- [`test`](test) contains the test cases of the library, including on node and on the browser. See [Testing](#testing).
+
+## Development Notes
+
+Files ending with `.ts.j2` are generated by jinja to `.gen.ts`, using [`scripts/generate.py`](scripts/generate.py).
+
+Thus, Python is required to run [`scripts/generate.py`](scripts/generate.py),
+which also requires `Jinja2` (see [`scripts/requirements.txt`](scripts/requirements.txt)).
+
+Do not edit `.gen.ts` directly, instead edit the `.ts.j2` files.
+
+### Development Scripts
+
+You can use `yarn watch` to automatically test after each edit.
+
+Note that it does not automatically regenerate `.gen.ts` files when editing `.ts.j2` files.
+You will have to run `yarn generate` or `python3 scripts/generate.py`.
+
+This is to allow for testing in `.gen.ts` files before moving the edits to `.ts.j2`.
+
+### Adding a new Operation
+
+To add a new operation, add it to [`src/operations/ops.ts.j2`](src/operations/ops.ts.j2).
+
+You may see the macros at [`scripts/macros.ts.j2`](scripts/macros.ts.j2) and the output at [`src/operations/ops.gen.ts`](src/operations/ops.gen.ts) (you need to run `yarn generate` to regenerate it) to see how it works.
+
+- To allow for `torch.(, )`, add it as well to [`src/operations/functional.ts`](src/operations/functional.ts).
+- To allow for `.()`, add it as well to [`src/tensor.ts`](src/tensor.ts) as a `tensor` method.
+
+## Testing
+
+Tests are run using `mocha`.
+
+- Node: To test on node, run `yarn test`.
+- Browser: To test on browser, run `yarn serve` (after `yarn build` if necessary) and navigate to http://localhost:8080/test/.
+
+To create a new test:
+
+1. Create a new `.test.js`/`.test.ts` file in [`test`](test) or write your new test in one of the existing files.
+2. If you created a new file and would like to test it on the browser, add it to [`test/index.html`](test/index.html).
+
+## Documentation
+
+To see docs, run `yarn docs` to build, and run `yarn serve docs` to serve docs on http://localhost:8080/.
+
+To ensure familiarity with PyTorch, docs should be derived from the PyTorch docs, as mentioned in [`NOTICE`](NOTICE).
\ No newline at end of file
diff --git a/README.md b/README.md
index 3f1f950f..ff61eaa9 100644
--- a/README.md
+++ b/README.md
@@ -44,20 +44,6 @@ yarn serve
 # or http://localhost:8080/test/ to run the tests
 ```
 
-## Development Notes
+## Contributing
 
-Files ending with `.ts.j2` are generated by jinja to `.gen.ts`, using `scripts/generate.py`.
-
-Thus, Python is required to run `scripts/generate.py`,
-which also requires `Jinja2` (see `scripts/requirements.txt`).
-
-Do not edit `.gen.ts` directly, instead edit the `.ts.j2` files.
-
-### Development Scripts
-
-You can use `yarn watch` to automatically test after each edit.
-
-Note that it does not automatically regenerate `.gen.ts` files when editing `.ts.j2` files.
-You will have to run `yarn generate` or `python3 scripts/generate.py`.
-
-This is to allow for testing in `.gen.ts` files before moving the edits to `.ts.j2`.
\ No newline at end of file
+For detailed information on the codebase and tests, see [CONTRIBUTING.md](CONTRIBUTING.md).
diff --git a/package.json b/package.json
index 5c853d2e..fc52bc1d 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
     "build": "npm run clean && npm run build:node && npm run build:browser",
     "docs": "typedoc --out docs src",
     "generate": "python3 scripts/generate.py",
-    "serve": "http-server -p 8080 -c-1 .",
+    "serve": "http-server -p 8080 -c-1",
     "test": "mocha test/**/*.test.ts test/**/*.test.js",
     "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js",
     "watch": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\""

From c5a46cd47ce408b3abf406616421f892ad541433 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 5 Jan 2026 14:39:38 +0800
Subject: [PATCH 044/128] refactor: SGD to be same as pytorch docs

---
 src/optim/optimizers.ts | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/optim/optimizers.ts b/src/optim/optimizers.ts
index cfade5c6..a3f4075a 100644
--- a/src/optim/optimizers.ts
+++ b/src/optim/optimizers.ts
@@ -1,7 +1,6 @@
 import { Optimizer } from "./base";
 import { Parameter } from "../nn/module";
 import { Tensor } from "../tensor";
-import { zeros } from "../creation";
 
 export class SGD extends Optimizer {
   private state: Map = new Map();
@@ -38,20 +37,21 @@ export class SGD extends Optimizer {
       }
 
       if (this.momentum != 0) {
-        let dampening = this.dampening;
-        if(!this.state.has(param)) {
-          this.state.set(param, { velocity: zeros(param.shape) });
-          dampening = 0;
+        if (this.state.has(param)) {
+          let buf = this.state.get(param)!.velocity;
+          buf = buf.mul(this.momentum)
+          buf = buf.add(g.mul(1 - this.dampening));
+          this.state.set(param, { velocity: buf });
+        } else {
+          this.state.set(param, { velocity: g });
         }
 
         let buf = this.state.get(param)!.velocity;
-        buf = buf.mul(this.momentum)
-        buf = buf.add(g.mul(dampening));
 
         if (this.nesterov) {
           g = g.add(buf.mul(this.momentum));
         } else {
-          g = g.add(buf);
+          g = buf;
         }
 
         this.state.set(param, { velocity: buf });
@@ -62,4 +62,4 @@ export class SGD extends Optimizer {
       param.data = newParam.data;
     }
   }
-}
\ No newline at end of file
+}

From c65cfbce18473489705dd803e86f31289e1f1a23 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 5 Jan 2026 15:07:48 +0800
Subject: [PATCH 045/128] feat: ones_like and zeros_like

---
 src/creation/initializers.ts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/creation/initializers.ts b/src/creation/initializers.ts
index 8252385f..4c1cd2ba 100644
--- a/src/creation/initializers.ts
+++ b/src/creation/initializers.ts
@@ -14,3 +14,11 @@ export function zeros(...args: number[] | number[][]): Tensor {
   tensor.shape = shape;
   return tensor;
 }
+
+export function ones_like(tensor: Tensor): Tensor {
+  return ones(tensor.shape);
+}
+
+export function zeros_like(tensor: Tensor): Tensor {
+  return zeros(tensor.shape);
+}

From d949239656bd6b86db0c7deb32d0520897b3bcd0 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 5 Jan 2026 15:11:32 +0800
Subject: [PATCH 046/128] feat: maximum and minimum

---
 src/operations/functional.ts |   2 +
 src/operations/ops.gen.ts    | 103 +++++++++++++++++++++++++++++++++++
 src/operations/ops.ts.j2     |   7 +++
 src/tensor.ts                |   8 +++
 4 files changed, 120 insertions(+)

diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 0244ce15..797a471a 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -42,6 +42,8 @@ export const mul = generate_binary_function('mul');
 export const div = generate_binary_function('div');
 export const pow = generate_binary_function('pow');
 export const fmod = generate_binary_function('fmod');
+export const maximum = generate_binary_function('maximum');
+export const minimum = generate_binary_function('minimum');
 
 // unary pointwise
 
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index e2e72b2f..99f8769e 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -318,6 +318,109 @@ export class Fmod extends BinaryOperation {
 }
 registerOperation('fmod', Fmod);
 
+const _maximum_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return Math.max(a[a_index], b[b_index]);
+  },
+  {
+    dynamicOutput: true,
+    dynamicArguments: true,
+    // pipeline: true,
+    // immutable: true
+  }
+);
+
+function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = _maximum_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Maximum", "maximum", backward_operations)
+export class Maximum extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    if (a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _maximum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.ge(b)));
+    b.backward(dz.mul(b.gt(a)));
+  }
+}
+registerOperation('maximum', Maximum);
+
+const _minimum_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return Math.min(a[a_index], b[b_index]);
+  },
+  {
+    dynamicOutput: true,
+    dynamicArguments: true,
+    // pipeline: true,
+    // immutable: true
+  }
+);
+
+function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = _minimum_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("Minimum", "minimum", backward_operations)
+export class Minimum extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    if (a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _minimum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.le(b)));
+    b.backward(dz.mul(b.lt(a)));
+  }
+}
+registerOperation('minimum', Minimum);
+
+
 function _powint_kernel_function(a: number[], n: number) {
   return Math.pow(a[this.thread.x], n);
 }
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index 705d5166..fd68ca2d 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -34,6 +34,13 @@ import { registerOperation } from './registry';
 {{ binary_op_base("fmod", "a[a_index] % b[b_index]") }}
 {{ binary_op_class("Fmod", "fmod", ["a.backward(dz);"]) }}
 
+{{ binary_op_base("maximum", "Math.max(a[a_index], b[b_index])") }}
+{{ binary_op_class("Maximum", "maximum", ["a.backward(dz.mul(a.ge(b)));", "b.backward(dz.mul(b.gt(a)));"]) }}
+
+{{ binary_op_base("minimum", "Math.min(a[a_index], b[b_index])") }}
+{{ binary_op_class("Minimum", "minimum", ["a.backward(dz.mul(a.le(b)));", "b.backward(dz.mul(b.lt(a)));"]) }}
+
+
 function _powint_kernel_function(a: number[], n: number) {
   return Math.pow(a[this.thread.x], n);
 }
diff --git a/src/tensor.ts b/src/tensor.ts
index 3a7546f6..4e11244c 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -203,6 +203,14 @@ export class Tensor {
     return this._executeBinaryOp('fmod', other);
   }
 
+  maximum(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('maximum', other);
+  }
+
+  minimum(other: Tensor | number): Tensor {
+    return this._executeBinaryOp('minimum', other);
+  }
+
   // unary pointwise
 
   log(): Tensor {

From df60e5991f3d9a1d904a3aad7e24b860eaa9c49c Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 5 Jan 2026 15:29:22 +0800
Subject: [PATCH 047/128] feat: Adam Optimizer

---
 src/optim/optimizers.ts | 85 +++++++++++++++++++++++++++++++++++++++--
 test/optimizers.test.js | 62 ++++++++++++++++++++++++++++--
 2 files changed, 141 insertions(+), 6 deletions(-)

diff --git a/src/optim/optimizers.ts b/src/optim/optimizers.ts
index a3f4075a..3b8fa96f 100644
--- a/src/optim/optimizers.ts
+++ b/src/optim/optimizers.ts
@@ -1,6 +1,7 @@
 import { Optimizer } from "./base";
 import { Parameter } from "../nn/module";
 import { Tensor } from "../tensor";
+import { zeros_like } from "../creation";
 
 export class SGD extends Optimizer {
   private state: Map = new Map();
@@ -10,7 +11,7 @@ export class SGD extends Optimizer {
   private weight_decay: number;
   private nesterov: boolean;
   private maximize: boolean;
-  
+
   constructor(
     params: Parameter[],
     lr: number = 0.001,
@@ -32,11 +33,11 @@ export class SGD extends Optimizer {
   step(): void {
     for (const param of this.params) {
       let g = this.maximize ? param.grad.mul(-1) : param.grad;
-      if (this.weight_decay != 0) {
+      if (this.weight_decay !== 0) {
         g = g.add(param.mul(this.weight_decay));
       }
 
-      if (this.momentum != 0) {
+      if (this.momentum !== 0) {
         if (this.state.has(param)) {
           let buf = this.state.get(param)!.velocity;
           buf = buf.mul(this.momentum)
@@ -63,3 +64,81 @@ export class SGD extends Optimizer {
     }
   }
 }
+
+export class Adam extends Optimizer {
+  private state: Map = new Map();
+
+  private step_count: number = 0;
+  private lr: number;
+  private beta1: number;
+  private beta2: number;
+  private eps: number;
+  private weight_decay: number;
+  private amsgrad: boolean;
+  private maximize: boolean;
+
+  constructor(
+    params: Parameter[],
+    lr: number = 0.001,
+    betas: [number, number] = [0.9, 0.999],
+    eps: number = 1e-8,
+    weight_decay: number = 0.0,
+    amsgrad: boolean = false,
+    maximize: boolean = false,
+  ) {
+    super(params, {});
+    this.lr = lr;
+    this.beta1 = betas[0];
+    this.beta2 = betas[1];
+    this.eps = eps;
+    this.weight_decay = weight_decay;
+    this.amsgrad = amsgrad;
+    this.maximize = maximize;
+  }
+
+  step(): void {
+    this.step_count += 1;
+    for (const param of this.params) {
+      let grad = this.maximize ? param.grad.mul(-1) : param.grad;
+
+      if (this.weight_decay !== 0) {
+        grad = grad.add(param.mul(this.weight_decay));
+      }
+
+      // Initialize
+      if (!this.state.has(param)) {
+        this.state.set(param, {
+          m: zeros_like(param),
+          v: zeros_like(param),
+          vmax: zeros_like(param),
+        });
+      }
+
+      const state = this.state.get(param)!;
+
+      state.m = state.m.mul(this.beta1).add(grad.mul(1 - this.beta1));
+      state.v = state.v.mul(this.beta2).add(grad.mul(grad).mul(1 - this.beta2));
+
+      const biasCorrection1 = 1 - Math.pow(this.beta1, this.step_count);
+      const biasCorrection2 = 1 - Math.pow(this.beta2, this.step_count);
+
+      let vhat: Tensor;
+      const mhat = state.m.div(biasCorrection1);
+      if (this.amsgrad) {
+        state.vmax = state.vmax.maximum(state.v);
+        vhat = state.vmax.div(biasCorrection2);
+      } else {
+        vhat = state.v.div(biasCorrection2);
+      }
+
+      const update = mhat.div(vhat.sqrt().add(this.eps)).mul(this.lr);
+
+      const newParam = param.sub(update);
+      param.data = newParam.data;
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/optimizers.test.js b/test/optimizers.test.js
index 45c10e61..f3df1300 100644
--- a/test/optimizers.test.js
+++ b/test/optimizers.test.js
@@ -1,18 +1,74 @@
 import { assert } from 'chai';
 import * as torch from 'torch';
 
+const EPS = 1e-6;
+
 describe('Optimizers', () => {
   describe('SGD', () => {
     it('should update parameters', () => {
       const x = new torch.Tensor([1.0], { requires_grad: true });
+      const sgd = new torch.optim.SGD([x], 0.01);
+      
       const y = x.mul(new torch.Tensor(2.0));
       y.backward();
-
-      const sgd = new torch.optim.SGD([x], 0.01);
+      
+      /**
+       * x = 1, grad = 2
+       * x_new = x - lr * grad = 1 - 0.01 * 2 = 0.98
+       */
       sgd.step();
       const actual = sgd.params[0].data[0];
       const expected = 0.98;
-      assert.ok(Math.abs(actual - expected) < 1e-6);
+      assert.closeTo(actual, expected, EPS);
+    });
+
+    it('should update parameters correctly over multiple steps (quadratic)', () => {
+      const x = new torch.Tensor([0.5], { requires_grad: true });
+      const sgd = new torch.optim.SGD([x], 0.1);
+
+      let y = x.pow(2);
+
+      /**
+       * x = 0.5, grad = 2x = 1
+       * x_new = x - lr * grad = 0.5 - 0.1 * 1 = 0.4
+       */
+      y.backward();
+      sgd.step();
+      sgd.zero_grad();
+
+      let actual = x.data[0];
+      assert.closeTo(actual, 0.4, EPS);
+
+      /**
+       * x = 0.4, grad = 2x = 0.8
+       * x_new = x - lr * grad = 0.4 - 0.1 * 0.8 = 0.32
+       */
+      y = x.pow(2);
+      y.backward();
+      sgd.step();
+      
+      actual = x.data[0];
+      assert.closeTo(actual, 0.32, EPS);
+    });
+  });
+
+  describe('Adam', () => {
+    it('should handle bias correction with constant gradient', () => {
+      const x = new torch.Tensor([10.0], { requires_grad: true });
+      const adam = new torch.optim.Adam([x], 0.1);
+
+      let y = x.mul(2);
+      y.backward();
+      adam.step();
+      adam.zero_grad();
+
+      assert.closeTo(x.data[0], 9.9, EPS);
+
+      y = x.mul(2);
+      y.backward();
+      adam.step();
+
+      assert.closeTo(x.data[0], 9.8, EPS);
     });
   });
 });

From bda7a43ced3d6dc17a0719a1d0cdd27be3225763 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Mon, 5 Jan 2026 15:36:29 +0800
Subject: [PATCH 048/128] fix: use yarn instead of npm

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index fc52bc1d..cf2643a5 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "build:browser:watch": "vite build --config vite.config.browser.ts --watch",
     "build:node": "vite build --config vite.config.node.ts",
     "build:node:watch": "vite build --config vite.config.node.ts --watch",
-    "build": "npm run clean && npm run build:node && npm run build:browser",
+    "build": "yarn clean && yarn build:node && yarn build:browser",
     "docs": "typedoc --out docs src",
     "generate": "python3 scripts/generate.py",
     "serve": "http-server -p 8080 -c-1",

From b88c9e02a3bc895fea9a545db9307fd35cfbace9 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Sun, 18 Jan 2026 16:25:57 +0800
Subject: [PATCH 049/128] fix: pyodide page point to correct gpu js file

---
 .github/workflows/push.yml  | 5 ++++-
 examples/browser/index.html | 2 ++
 examples/pyodide/index.html | 3 +--
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 6dd63688..1793448e 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -60,8 +60,11 @@ jobs:
         - name: Copy examples to docs/examples
           run: cp -r examples docs/examples
 
+        - name: Copy vendor files to docs/vendor
+          run: cp -r vendor docs/vendor
+
         - name: Deploy docs
           uses: peaceiris/actions-gh-pages@v4
           with:
-            github_token: ${{ secrets.GITHUB_TOKEN }} 
+            github_token: ${{ secrets.GITHUB_TOKEN }}
             publish_dir: ./docs # The folder the action should deploy.
\ No newline at end of file
diff --git a/examples/browser/index.html b/examples/browser/index.html
index 96c9c455..58376831 100644
--- a/examples/browser/index.html
+++ b/examples/browser/index.html
@@ -5,7 +5,9 @@
   
   
   torch.js browser backprop example
+
   
+  
   
 
 
diff --git a/examples/pyodide/index.html b/examples/pyodide/index.html
index 98d58cd4..ec743421 100644
--- a/examples/pyodide/index.html
+++ b/examples/pyodide/index.html
@@ -5,9 +5,8 @@
     
     
     torch+pyodide browser backprop example
-    
-    
     
+    
     
 
 

From e6be197e06949029a56e47a22d3ee6e6b109447b Mon Sep 17 00:00:00 2001
From: Hua Zhi Vee 
Date: Sun, 18 Jan 2026 16:39:45 +0800
Subject: [PATCH 050/128] feat: example shows error if script loading fail

---
 examples/browser/index.html | 4 ++--
 examples/pyodide/index.html | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/examples/browser/index.html b/examples/browser/index.html
index 58376831..471f92ea 100644
--- a/examples/browser/index.html
+++ b/examples/browser/index.html
@@ -7,8 +7,8 @@
   torch.js browser backprop example
 
   
-  
-  
+  
+  
 
 
 
diff --git a/examples/pyodide/index.html b/examples/pyodide/index.html
index ec743421..092fb669 100644
--- a/examples/pyodide/index.html
+++ b/examples/pyodide/index.html
@@ -6,8 +6,8 @@
     
     torch+pyodide browser backprop example
     
-    
-    
+    
+    
 
 
 

From d1bb0cceb3de938dfbe2bf4d5bb0c3ce046e911c Mon Sep 17 00:00:00 2001
From: Hua Zhi Vee 
Date: Sun, 18 Jan 2026 17:23:47 +0800
Subject: [PATCH 051/128] feat: remove debug statements from bridge.py

---
 examples/pyodide/bridge.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/examples/pyodide/bridge.py b/examples/pyodide/bridge.py
index 5151ded0..cadf36bb 100644
--- a/examples/pyodide/bridge.py
+++ b/examples/pyodide/bridge.py
@@ -30,10 +30,9 @@ def __init__(self, data, requires_grad=False):
         if isinstance(data, JsProxy):
             self.data = data
         else:
-            print("creating tensor from data", data)
+            # print("creating tensor from data", data)
             self.data = torch_utils.create_tensor_from_python_data(data, requires_grad)
-            print("created tensor", self.tolist())
-            # print("created tensor", self.data._data)
+            # print("created tensor", self.tolist())
 
     def __repr__(self):
         return f"Tensor(data={self.tolist()}{', requires_grad=True' if self.get_tensor().requires_grad else ''})"

From 6fb6f94b1cb9284f04c09051f456bbdbfe3892bb Mon Sep 17 00:00:00 2001
From: Hua Zhi Vee 
Date: Wed, 21 Jan 2026 15:59:57 +0800
Subject: [PATCH 052/128] feat: build process and publish

---
 .github/workflows/push.yml |  32 +---
 package.json               |   5 +-
 shell.nix                  |  25 +++
 yarn.lock                  | 376 ++++++++++++++++++++++++++++++++++++-
 4 files changed, 406 insertions(+), 32 deletions(-)
 create mode 100644 shell.nix

diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 1793448e..f8d307df 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -3,8 +3,8 @@ name: test-on-push
 on: [push]
 
 jobs:
-  test:
-    name: Verify all tests pass and build success
+  ci:
+    name: Build, test, publish docs, and publish package
     runs-on: ubuntu-latest
     steps:
         - name: Check out source code
@@ -28,29 +28,6 @@ jobs:
         - name: Test
           run: yarn test
 
-  docs:
-    name: Deploy to GitHub Pages
-    runs-on: ubuntu-latest
-    needs: test
-    steps:
-        - name: Check out source code
-          uses: actions/checkout@v4
-
-        - name: Enable Corepack
-          run: corepack enable
-
-        - name: Use Node.js 💻
-          uses: actions/setup-node@v4
-          with:
-            node-version: 20
-            cache: yarn
-
-        - name: Install dependencies
-          run: yarn install --immutable
-
-        - name: Build
-          run: yarn build
-
         - name: Build docs
           run: yarn docs
 
@@ -67,4 +44,7 @@ jobs:
           uses: peaceiris/actions-gh-pages@v4
           with:
             github_token: ${{ secrets.GITHUB_TOKEN }}
-            publish_dir: ./docs # The folder the action should deploy.
\ No newline at end of file
+            publish_dir: ./docs # The folder the action should deploy.
+
+        - name: Publish package
+          run: yarn pkg-pr-new publish
diff --git a/package.json b/package.json
index cf2643a5..c1c33a6c 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,9 @@
   "repository": "git@github.com/source-academy/torch.git",
   "license": "Apache-2.0",
   "files": [
-    "build"
+    "build",
+    "examples",
+    "vendor"
   ],
   "main": "./build/node/torch.node.cjs",
   "module": "./build/node/torch.node.es.mjs",
@@ -47,6 +49,7 @@
     "eslint-plugin-import": "^2.32.0",
     "http-server": "^14.1.1",
     "mocha": "^11.7.4",
+    "pkg-pr-new": "^0.0.62",
     "prettier": "^3.6.2",
     "rimraf": "^6.0.1",
     "ts-node": "^10.9.2",
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 00000000..bce33d68
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,25 @@
+{
+  pkgs ? import  { },
+}:
+
+pkgs.mkShell {
+  buildInputs = with pkgs; [
+    nodejs_22
+    pkg-config
+    libglvnd
+    xorg.libX11
+    xorg.libXi
+    xorg.libXext
+  ];
+
+  shellHook = ''
+    export LD_LIBRARY_PATH="${
+      pkgs.lib.makeLibraryPath [
+        pkgs.libglvnd
+        pkgs.xorg.libX11
+        pkgs.xorg.libXi
+        pkgs.xorg.libXext
+      ]
+    }:$LD_LIBRARY_PATH"
+  '';
+}
diff --git a/yarn.lock b/yarn.lock
index 41d7eb92..c32720ff 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5,6 +5,42 @@ __metadata:
   version: 8
   cacheKey: 10c0
 
+"@actions/core@npm:^1.11.1":
+  version: 1.11.1
+  resolution: "@actions/core@npm:1.11.1"
+  dependencies:
+    "@actions/exec": "npm:^1.1.1"
+    "@actions/http-client": "npm:^2.0.1"
+  checksum: 10c0/9aa30b397d8d0dbc74e69fe46b23fb105cab989beb420c57eacbfc51c6804abe8da0f46973ca9f639d532ea4c096d0f4d37da0223fbe94f304fa3c5f53537c30
+  languageName: node
+  linkType: hard
+
+"@actions/exec@npm:^1.1.1":
+  version: 1.1.1
+  resolution: "@actions/exec@npm:1.1.1"
+  dependencies:
+    "@actions/io": "npm:^1.0.1"
+  checksum: 10c0/4a09f6bdbe50ce68b5cf8a7254d176230d6a74bccf6ecc3857feee209a8c950ba9adec87cc5ecceb04110182d1c17117234e45557d72fde6229b7fd3a395322a
+  languageName: node
+  linkType: hard
+
+"@actions/http-client@npm:^2.0.1":
+  version: 2.2.3
+  resolution: "@actions/http-client@npm:2.2.3"
+  dependencies:
+    tunnel: "npm:^0.0.6"
+    undici: "npm:^5.25.4"
+  checksum: 10c0/13141b66a42aa4afd8c50f7479e13a5cdb5084ccb3c73ec48894b8029743389a3d2bf8cdc18e23fb70cd33995740526dd308815613907571e897c3aa1e5eada6
+  languageName: node
+  linkType: hard
+
+"@actions/io@npm:^1.0.1":
+  version: 1.1.3
+  resolution: "@actions/io@npm:1.1.3"
+  checksum: 10c0/5b8751918e5bf0bebd923ba917fb1c0e294401e7ff0037f32c92a4efa4215550df1f6633c63fd4efb2bdaae8711e69b9e36925857db1f38935ff62a5c92ec29e
+  languageName: node
+  linkType: hard
+
 "@babel/helper-string-parser@npm:^7.27.1":
   version: 7.27.1
   resolution: "@babel/helper-string-parser@npm:7.27.1"
@@ -319,6 +355,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@fastify/busboy@npm:^2.0.0":
+  version: 2.1.1
+  resolution: "@fastify/busboy@npm:2.1.1"
+  checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3
+  languageName: node
+  linkType: hard
+
 "@gerrit0/mini-shiki@npm:^3.12.0":
   version: 3.13.1
   resolution: "@gerrit0/mini-shiki@npm:3.13.1"
@@ -426,6 +469,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@jsdevtools/ez-spawn@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "@jsdevtools/ez-spawn@npm:3.0.4"
+  dependencies:
+    call-me-maybe: "npm:^1.0.1"
+    cross-spawn: "npm:^7.0.3"
+    string-argv: "npm:^0.3.1"
+    type-detect: "npm:^4.0.8"
+  checksum: 10c0/fb56f99c4d09ccaeace4ebaecfa31ab1ff90517d5ca51dbd624f4b9ab489eee469504ab33a12a2bc8b5f0a35ee61e139cc087b242ad7947c61674454cb41c75e
+  languageName: node
+  linkType: hard
+
 "@microsoft/api-extractor-model@npm:7.31.0":
   version: 7.31.0
   resolution: "@microsoft/api-extractor-model@npm:7.31.0"
@@ -550,6 +605,150 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@octokit/action@npm:^6.1.0":
+  version: 6.1.0
+  resolution: "@octokit/action@npm:6.1.0"
+  dependencies:
+    "@octokit/auth-action": "npm:^4.0.0"
+    "@octokit/core": "npm:^5.0.0"
+    "@octokit/plugin-paginate-rest": "npm:^9.0.0"
+    "@octokit/plugin-rest-endpoint-methods": "npm:^10.0.0"
+    "@octokit/types": "npm:^12.0.0"
+    undici: "npm:^6.0.0"
+  checksum: 10c0/c5d692733020a9cd5c85eabe587c7a609a19dc00b4b49294be838cb4f4484b60d69a30c00df00f8fc62d11e9481361eacd4cc829afce58257684bc50520aed08
+  languageName: node
+  linkType: hard
+
+"@octokit/auth-action@npm:^4.0.0":
+  version: 4.1.0
+  resolution: "@octokit/auth-action@npm:4.1.0"
+  dependencies:
+    "@octokit/auth-token": "npm:^4.0.0"
+    "@octokit/types": "npm:^13.0.0"
+  checksum: 10c0/f7f0a222786f348dd0ee6ba72e6c54f1ce36b15c8bb0ed998e8966cea23ee912abeb89b8613c8b354fa6bd1ee7199f74deb609607762d3411c0c8990b2c53fb4
+  languageName: node
+  linkType: hard
+
+"@octokit/auth-token@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "@octokit/auth-token@npm:4.0.0"
+  checksum: 10c0/57acaa6c394c5abab2f74e8e1dcf4e7a16b236f713c77a54b8f08e2d14114de94b37946259e33ec2aab0566b26f724c2b71d2602352b59e541a9854897618f3c
+  languageName: node
+  linkType: hard
+
+"@octokit/core@npm:^5.0.0":
+  version: 5.2.2
+  resolution: "@octokit/core@npm:5.2.2"
+  dependencies:
+    "@octokit/auth-token": "npm:^4.0.0"
+    "@octokit/graphql": "npm:^7.1.0"
+    "@octokit/request": "npm:^8.4.1"
+    "@octokit/request-error": "npm:^5.1.1"
+    "@octokit/types": "npm:^13.0.0"
+    before-after-hook: "npm:^2.2.0"
+    universal-user-agent: "npm:^6.0.0"
+  checksum: 10c0/b4484d85552303b839613e2133dcd064fa06a7c10fe0ebd11ba8f67cb8e3384e48983c589f4d1dc0fa3754857784e3d90ff4eab9782e118baf13ddd1b834957c
+  languageName: node
+  linkType: hard
+
+"@octokit/endpoint@npm:^9.0.6":
+  version: 9.0.6
+  resolution: "@octokit/endpoint@npm:9.0.6"
+  dependencies:
+    "@octokit/types": "npm:^13.1.0"
+    universal-user-agent: "npm:^6.0.0"
+  checksum: 10c0/8e06197b21869aeb498e0315093ca6fbee12bd1bdcfc1667fcd7d79d827d84f2c5a30702ffd28bba7879780e367d14c30df5b20d47fcaed5de5fdc05f5d4e013
+  languageName: node
+  linkType: hard
+
+"@octokit/graphql@npm:^7.1.0":
+  version: 7.1.1
+  resolution: "@octokit/graphql@npm:7.1.1"
+  dependencies:
+    "@octokit/request": "npm:^8.4.1"
+    "@octokit/types": "npm:^13.0.0"
+    universal-user-agent: "npm:^6.0.0"
+  checksum: 10c0/c27216200f3f4ce7ce2a694fb7ea43f8ea4a807fbee3a423c41ed137dd7948dfc0bbf6ea1656f029a7625c84b583acdef740a7032266d0eff55305c91c3a1ed6
+  languageName: node
+  linkType: hard
+
+"@octokit/openapi-types@npm:^20.0.0":
+  version: 20.0.0
+  resolution: "@octokit/openapi-types@npm:20.0.0"
+  checksum: 10c0/5176dcc3b9d182ede3d446750cfa5cf31139624785a73fcf3511e3102a802b4d7cc45e999c27ed91d73fe8b7d718c8c406facb48688926921a71fe603b7db95d
+  languageName: node
+  linkType: hard
+
+"@octokit/openapi-types@npm:^24.2.0":
+  version: 24.2.0
+  resolution: "@octokit/openapi-types@npm:24.2.0"
+  checksum: 10c0/8f47918b35e9b7f6109be6f7c8fc3a64ad13a48233112b29e92559e64a564b810eb3ebf81b4cd0af1bb2989d27b9b95cca96e841ec4e23a3f68703cefe62fd9e
+  languageName: node
+  linkType: hard
+
+"@octokit/plugin-paginate-rest@npm:^9.0.0":
+  version: 9.2.2
+  resolution: "@octokit/plugin-paginate-rest@npm:9.2.2"
+  dependencies:
+    "@octokit/types": "npm:^12.6.0"
+  peerDependencies:
+    "@octokit/core": 5
+  checksum: 10c0/e9c85b17064fe6b62f9af88dba008f3daef456b1195340ea0831990e9c4dbabe89be950b6e5dc924ebcca18ad1aaa0cf6df7d824dc8be26ce9a55f20336ff815
+  languageName: node
+  linkType: hard
+
+"@octokit/plugin-rest-endpoint-methods@npm:^10.0.0":
+  version: 10.4.1
+  resolution: "@octokit/plugin-rest-endpoint-methods@npm:10.4.1"
+  dependencies:
+    "@octokit/types": "npm:^12.6.0"
+  peerDependencies:
+    "@octokit/core": 5
+  checksum: 10c0/4b8f64c0f7fa12464546ad312a5289c2a799967e01e90e2c4923ec6e9604cf212dcb50d9795c9a688867f973c9c529c5950368564c560406c652bcd298f090af
+  languageName: node
+  linkType: hard
+
+"@octokit/request-error@npm:^5.1.1":
+  version: 5.1.1
+  resolution: "@octokit/request-error@npm:5.1.1"
+  dependencies:
+    "@octokit/types": "npm:^13.1.0"
+    deprecation: "npm:^2.0.0"
+    once: "npm:^1.4.0"
+  checksum: 10c0/dc9fc76ea5e4199273e4665ce9ddf345fe8f25578d9999c9a16f276298e61ee6fe0e6f5a6147b91ba3b34fdf5b9e6b7af6ae13d6333175e95b30c574088f7a2d
+  languageName: node
+  linkType: hard
+
+"@octokit/request@npm:^8.4.1":
+  version: 8.4.1
+  resolution: "@octokit/request@npm:8.4.1"
+  dependencies:
+    "@octokit/endpoint": "npm:^9.0.6"
+    "@octokit/request-error": "npm:^5.1.1"
+    "@octokit/types": "npm:^13.1.0"
+    universal-user-agent: "npm:^6.0.0"
+  checksum: 10c0/1a69dcb7336de708a296db9e9a58040e5b284a87495a63112f80eb0007da3fc96a9fadecb9e875fc63cf179c23a0f81031fbef2a6f610a219e45805ead03fcf3
+  languageName: node
+  linkType: hard
+
+"@octokit/types@npm:^12.0.0, @octokit/types@npm:^12.6.0":
+  version: 12.6.0
+  resolution: "@octokit/types@npm:12.6.0"
+  dependencies:
+    "@octokit/openapi-types": "npm:^20.0.0"
+  checksum: 10c0/0bea58bda46c93287f5a80a0e52bc60e7dc7136b8a38c3569d63d073fb9df4a56acdb9d9bdba9978f37c374a4a6e3e52886ef5b08cace048adb0012cacef942c
+  languageName: node
+  linkType: hard
+
+"@octokit/types@npm:^13.0.0, @octokit/types@npm:^13.1.0":
+  version: 13.10.0
+  resolution: "@octokit/types@npm:13.10.0"
+  dependencies:
+    "@octokit/openapi-types": "npm:^24.2.0"
+  checksum: 10c0/f66a401b89d653ec28e5c1529abdb7965752db4d9d40fa54c80e900af4c6bf944af6bd0a83f5b4f1eecb72e3d646899dfb27ffcf272ac243552de7e3b97a038d
+  languageName: node
+  linkType: hard
+
 "@pkgjs/parseargs@npm:^0.11.0":
   version: 0.11.0
   resolution: "@pkgjs/parseargs@npm:0.11.0"
@@ -1537,6 +1736,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"before-after-hook@npm:^2.2.0":
+  version: 2.2.3
+  resolution: "before-after-hook@npm:2.2.3"
+  checksum: 10c0/0488c4ae12df758ca9d49b3bb27b47fd559677965c52cae7b335784724fb8bf96c42b6e5ba7d7afcbc31facb0e294c3ef717cc41c5bc2f7bd9e76f8b90acd31c
+  languageName: node
+  linkType: hard
+
 "bindings@npm:^1.5.0":
   version: 1.5.0
   resolution: "bindings@npm:1.5.0"
@@ -1681,6 +1887,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"call-me-maybe@npm:^1.0.1":
+  version: 1.0.2
+  resolution: "call-me-maybe@npm:1.0.2"
+  checksum: 10c0/8eff5dbb61141ebb236ed71b4e9549e488bcb5451c48c11e5667d5c75b0532303788a1101e6978cafa2d0c8c1a727805599c2741e3e0982855c9f1d78cd06c9f
+  languageName: node
+  linkType: hard
+
 "callsites@npm:^3.0.0":
   version: 3.1.0
   resolution: "callsites@npm:3.1.0"
@@ -1842,7 +2055,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"cross-spawn@npm:^7.0.6":
+"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
   version: 7.0.6
   resolution: "cross-spawn@npm:7.0.6"
   dependencies:
@@ -1921,6 +2134,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"decode-uri-component@npm:^0.4.1":
+  version: 0.4.1
+  resolution: "decode-uri-component@npm:0.4.1"
+  checksum: 10c0/a180bbdb5398ec8270d236a3ac07cb988bbf6097428481780b85840f088951dc0318a8d8f9d56796e1a322b55b29859cea29982f22f9b03af0bc60974c54e591
+  languageName: node
+  linkType: hard
+
 "decompress-response@npm:^6.0.0":
   version: 6.0.0
   resolution: "decompress-response@npm:6.0.0"
@@ -1966,6 +2186,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"deprecation@npm:^2.0.0":
+  version: 2.3.1
+  resolution: "deprecation@npm:2.3.1"
+  checksum: 10c0/23d688ba66b74d09b908c40a76179418acbeeb0bfdf218c8075c58ad8d0c315130cb91aa3dffb623aa3a411a3569ce56c6460de6c8d69071c17fe6dd2442f032
+  languageName: node
+  linkType: hard
+
 "detect-libc@npm:^2.0.0":
   version: 2.1.1
   resolution: "detect-libc@npm:2.1.1"
@@ -2594,6 +2821,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"filter-obj@npm:^5.1.0":
+  version: 5.1.0
+  resolution: "filter-obj@npm:5.1.0"
+  checksum: 10c0/716e8ad2bc352e206556b3e5695b3cdff8aab80c53ea4b00c96315bbf467b987df3640575100aef8b84e812cf5ea4251db4cd672bbe33b1e78afea88400c67dd
+  languageName: node
+  linkType: hard
+
 "find-up@npm:^5.0.0":
   version: 5.0.0
   resolution: "find-up@npm:5.0.0"
@@ -3092,7 +3326,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ignore@npm:^5.2.0":
+"ignore@npm:^5.2.0, ignore@npm:^5.3.1":
   version: 5.3.2
   resolution: "ignore@npm:5.3.2"
   checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337
@@ -3451,6 +3685,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"isbinaryfile@npm:^5.0.2":
+  version: 5.0.7
+  resolution: "isbinaryfile@npm:5.0.7"
+  checksum: 10c0/4cd98a91aaf969d7cae91f74d041dd1df35d9e140c522b7879180035f7eab9ba9c0c3d678e00e72a2777ee7245fd8f20b60c0787132c5fdbf6fc113492325e11
+  languageName: node
+  linkType: hard
+
 "isexe@npm:^2.0.0":
   version: 2.0.0
   resolution: "isexe@npm:2.0.0"
@@ -4358,7 +4599,25 @@ __metadata:
   languageName: node
   linkType: hard
 
-"pkg-types@npm:^1.3.1":
+"pkg-pr-new@npm:^0.0.62":
+  version: 0.0.62
+  resolution: "pkg-pr-new@npm:0.0.62"
+  dependencies:
+    "@actions/core": "npm:^1.11.1"
+    "@jsdevtools/ez-spawn": "npm:^3.0.4"
+    "@octokit/action": "npm:^6.1.0"
+    ignore: "npm:^5.3.1"
+    isbinaryfile: "npm:^5.0.2"
+    pkg-types: "npm:^1.1.1"
+    query-registry: "npm:^3.0.1"
+    tinyglobby: "npm:^0.2.9"
+  bin:
+    pkg-pr-new: bin/cli.js
+  checksum: 10c0/db76e65963800689437ad65d53b8c75b8aaec17c04ca8728af8cc3499a7e690de05e4689c99221bb24b032274bea80b7c1d46c08e5ab308f7dd3b82bdfc644f2
+  languageName: node
+  linkType: hard
+
+"pkg-types@npm:^1.1.1, pkg-types@npm:^1.3.1":
   version: 1.3.1
   resolution: "pkg-types@npm:1.3.1"
   dependencies:
@@ -4510,6 +4769,31 @@ __metadata:
   languageName: node
   linkType: hard
 
+"query-registry@npm:^3.0.1":
+  version: 3.0.1
+  resolution: "query-registry@npm:3.0.1"
+  dependencies:
+    query-string: "npm:^9.0.0"
+    quick-lru: "npm:^7.0.0"
+    url-join: "npm:^5.0.0"
+    validate-npm-package-name: "npm:^5.0.1"
+    zod: "npm:^3.23.8"
+    zod-package-json: "npm:^1.0.3"
+  checksum: 10c0/a4d36d323cb39c02063fc6592ddbef09571ba5016caf9498bb26ecfca35b141177a11217dcfa5e9958e79ec18d3fe57b9ffdef731691a1225d2994cba4afeb82
+  languageName: node
+  linkType: hard
+
+"query-string@npm:^9.0.0":
+  version: 9.3.1
+  resolution: "query-string@npm:9.3.1"
+  dependencies:
+    decode-uri-component: "npm:^0.4.1"
+    filter-obj: "npm:^5.1.0"
+    split-on-first: "npm:^3.0.0"
+  checksum: 10c0/47f62350be7ace6d2e03d12becf5d1985731d97577963a4d8b684e166f6708cb42f63f09aa4c92931f2ee1ff57c0800a25807b95f28fd98f7064b1d06b02b07e
+  languageName: node
+  linkType: hard
+
 "queue-microtask@npm:^1.2.2":
   version: 1.2.3
   resolution: "queue-microtask@npm:1.2.3"
@@ -4517,6 +4801,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"quick-lru@npm:^7.0.0":
+  version: 7.3.0
+  resolution: "quick-lru@npm:7.3.0"
+  checksum: 10c0/28dc8eaadcd489d26917f238ad27a6b09f8fe3a609152b0a4f399d5805094e07b56fe1e8c0d7ade0c11463c31bef329803672effc559601daf160a85f578fd05
+  languageName: node
+  linkType: hard
+
 "randombytes@npm:^2.1.0":
   version: 2.1.0
   resolution: "randombytes@npm:2.1.0"
@@ -5070,6 +5361,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"split-on-first@npm:^3.0.0":
+  version: 3.0.0
+  resolution: "split-on-first@npm:3.0.0"
+  checksum: 10c0/a1262eae12b68de235e1a08e011bf5b42c42621985ddf807e6221fb1e2b3304824913ae7019f18436b96b8fab8aef5f1ad80dedd2385317fdc51b521c3882cd0
+  languageName: node
+  linkType: hard
+
 "sprintf-js@npm:~1.0.2":
   version: 1.0.3
   resolution: "sprintf-js@npm:1.0.3"
@@ -5116,7 +5414,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"string-argv@npm:~0.3.1":
+"string-argv@npm:^0.3.1, string-argv@npm:~0.3.1":
   version: 0.3.2
   resolution: "string-argv@npm:0.3.2"
   checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82
@@ -5334,7 +5632,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15":
+"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15, tinyglobby@npm:^0.2.9":
   version: 0.2.15
   resolution: "tinyglobby@npm:0.2.15"
   dependencies:
@@ -5367,6 +5665,7 @@ __metadata:
     eslint-plugin-import: "npm:^2.32.0"
     http-server: "npm:^14.1.1"
     mocha: "npm:^11.7.4"
+    pkg-pr-new: "npm:^0.0.62"
     prettier: "npm:^3.6.2"
     rimraf: "npm:^6.0.1"
     ts-node: "npm:^10.9.2"
@@ -5479,6 +5778,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"tunnel@npm:^0.0.6":
+  version: 0.0.6
+  resolution: "tunnel@npm:0.0.6"
+  checksum: 10c0/e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75
+  languageName: node
+  linkType: hard
+
 "type-check@npm:^0.4.0, type-check@npm:~0.4.0":
   version: 0.4.0
   resolution: "type-check@npm:0.4.0"
@@ -5488,6 +5794,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"type-detect@npm:^4.0.8":
+  version: 4.1.0
+  resolution: "type-detect@npm:4.1.0"
+  checksum: 10c0/df8157ca3f5d311edc22885abc134e18ff8ffbc93d6a9848af5b682730ca6a5a44499259750197250479c5331a8a75b5537529df5ec410622041650a7f293e2a
+  languageName: node
+  linkType: hard
+
 "typed-array-buffer@npm:^1.0.3":
   version: 1.0.3
   resolution: "typed-array-buffer@npm:1.0.3"
@@ -5646,6 +5959,22 @@ __metadata:
   languageName: node
   linkType: hard
 
+"undici@npm:^5.25.4":
+  version: 5.29.0
+  resolution: "undici@npm:5.29.0"
+  dependencies:
+    "@fastify/busboy": "npm:^2.0.0"
+  checksum: 10c0/e4e4d631ca54ee0ad82d2e90e7798fa00a106e27e6c880687e445cc2f13b4bc87c5eba2a88c266c3eecffb18f26e227b778412da74a23acc374fca7caccec49b
+  languageName: node
+  linkType: hard
+
+"undici@npm:^6.0.0":
+  version: 6.23.0
+  resolution: "undici@npm:6.23.0"
+  checksum: 10c0/d846b3fdfd05aa6081ba1eab5db6bbc21b283042c7a43722b86d1ee2bf749d7c990ceac0c809f9a07ffd88b1b0f4c0f548a8362c035088cb1997d63abdda499c
+  languageName: node
+  linkType: hard
+
 "union@npm:~0.5.0":
   version: 0.5.0
   resolution: "union@npm:0.5.0"
@@ -5691,6 +6020,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"universal-user-agent@npm:^6.0.0":
+  version: 6.0.1
+  resolution: "universal-user-agent@npm:6.0.1"
+  checksum: 10c0/5c9c46ffe19a975e11e6443640ed4c9e0ce48fcc7203325757a8414ac49940ebb0f4667f2b1fa561489d1eb22cb2d05a0f7c82ec20c5cba42e58e188fb19b187
+  languageName: node
+  linkType: hard
+
 "universalify@npm:^2.0.0":
   version: 2.0.1
   resolution: "universalify@npm:2.0.1"
@@ -5714,6 +6050,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"url-join@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "url-join@npm:5.0.0"
+  checksum: 10c0/ed2b166b4b5a98adcf6828a48b6bd6df1dac4c8a464a73cf4d8e2457ed410dd8da6be0d24855b86026cd7f5c5a3657c1b7b2c7a7c5b8870af17635a41387b04c
+  languageName: node
+  linkType: hard
+
 "util-deprecate@npm:^1.0.1":
   version: 1.0.2
   resolution: "util-deprecate@npm:1.0.2"
@@ -5728,6 +6071,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"validate-npm-package-name@npm:^5.0.1":
+  version: 5.0.1
+  resolution: "validate-npm-package-name@npm:5.0.1"
+  checksum: 10c0/903e738f7387404bb72f7ac34e45d7010c877abd2803dc2d614612527927a40a6d024420033132e667b1bade94544b8a1f65c9431a4eb30d0ce0d80093cd1f74
+  languageName: node
+  linkType: hard
+
 "vite-plugin-dts@npm:^4.5.4":
   version: 4.5.4
   resolution: "vite-plugin-dts@npm:4.5.4"
@@ -6052,3 +6402,19 @@ __metadata:
   checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f
   languageName: node
   linkType: hard
+
+"zod-package-json@npm:^1.0.3":
+  version: 1.2.0
+  resolution: "zod-package-json@npm:1.2.0"
+  dependencies:
+    zod: "npm:^3.25.64"
+  checksum: 10c0/78a2104231c8c60b00adc8cf9acfae0c0c5cfc77f0be9225297a41bd73f52b21d17b1208358e0dfe7bd558fb4ba1cc6743c2bdd111280831be00f0c3ecdfc1f4
+  languageName: node
+  linkType: hard
+
+"zod@npm:^3.23.8, zod@npm:^3.25.64":
+  version: 3.25.76
+  resolution: "zod@npm:3.25.76"
+  checksum: 10c0/5718ec35e3c40b600316c5b4c5e4976f7fee68151bc8f8d90ec18a469be9571f072e1bbaace10f1e85cf8892ea12d90821b200e980ab46916a6166a4260a983c
+  languageName: node
+  linkType: hard

From 0f14e5b8ffd43438764b7080e16340b7d4ca3a52 Mon Sep 17 00:00:00 2001
From: veehz 
Date: Wed, 21 Jan 2026 16:09:57 +0800
Subject: [PATCH 053/128] wip sigmoid function

---
 src/nn/functional.ts      |  1 +
 src/nn/index.ts           |  1 +
 src/nn/loss.ts            | 30 +++++++++++++++++++++++---
 src/nn/module.ts          | 10 +++++++++
 src/nn/ops.gen.ts         | 44 ++++++++++++++++++++++++++++++++++++++-
 src/nn/ops.ts.j2          |  5 ++++-
 src/operations/ops.gen.ts |  4 ++--
 src/operations/ops.ts.j2  |  2 +-
 8 files changed, 89 insertions(+), 8 deletions(-)

diff --git a/src/nn/functional.ts b/src/nn/functional.ts
index a561fd08..bd3fadc5 100644
--- a/src/nn/functional.ts
+++ b/src/nn/functional.ts
@@ -35,3 +35,4 @@ function generate_binary_function(opname: string) {
 }
 
 export const relu = generate_unary_function('relu');
+export const sigmoid = generate_unary_function('sigmoid');
diff --git a/src/nn/index.ts b/src/nn/index.ts
index c92f96a3..20331f75 100644
--- a/src/nn/index.ts
+++ b/src/nn/index.ts
@@ -1,4 +1,5 @@
 import './ops.gen';
 
 export * from './module';
+export * from './loss';
 export * as functional from './functional';
\ No newline at end of file
diff --git a/src/nn/loss.ts b/src/nn/loss.ts
index 881d1319..373698ff 100644
--- a/src/nn/loss.ts
+++ b/src/nn/loss.ts
@@ -1,8 +1,8 @@
 import { Tensor } from "../tensor";
 
-class Loss {}
-
-
+abstract class Loss {
+  abstract forward(input: Tensor, target: Tensor): Tensor;
+}
 
 export class MSELoss extends Loss {
   constructor() {
@@ -22,4 +22,28 @@ export class L1Loss extends Loss {
   forward(input: Tensor, target: Tensor) {
     return input.sub(target).abs().mean();
   }
+}
+
+export class BCELoss extends Loss {
+  private weight: Tensor | null;
+
+  constructor(weight: Tensor | null = null) {
+    super();
+    this.weight = weight;
+  }
+
+  forward(input: Tensor, target: Tensor) {
+    const left = target.mul(input.log());
+    console.log("input", input);
+    console.log("input.log()", input.log());
+    console.log("target", target);
+    console.log("LEFT", left);
+    const right = target.neg().add(1).mul(input.neg().add(1).log());
+    console.log("RIGHT", right);
+    const loss = left.add(right).neg().mean();
+    if (this.weight) {
+      return loss.mul(this.weight);
+    }
+    return loss;
+  }
 }
\ No newline at end of file
diff --git a/src/nn/module.ts b/src/nn/module.ts
index 6b9eea64..90cee378 100644
--- a/src/nn/module.ts
+++ b/src/nn/module.ts
@@ -88,3 +88,13 @@ export class ReLU extends Module {
     return functional.relu(input);
   }
 }
+
+export class Sigmoid extends Module {
+  constructor() {
+    super();
+  }
+
+  forward(input: Tensor) {
+    return functional.sigmoid(input);
+  }
+}
diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts
index 6415f710..8b587767 100644
--- a/src/nn/ops.gen.ts
+++ b/src/nn/ops.gen.ts
@@ -50,4 +50,46 @@ export class Relu extends UnaryOperation {
     a.backward(dz.mul(a.gt(0)));
   }
 }
-registerOperation('relu', Relu);
\ No newline at end of file
+registerOperation('relu', Relu);
+
+// function generated from unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[this.thread.x]))")
+
+const _sigmoid_kernel = gpu.createKernel(
+  function (a: number[]) {
+    return 1 / (1 + Math.exp(-a[this.thread.x]));
+  },
+  {
+    dynamicOutput: true,
+    dynamicArguments: true,
+    // pipeline: true,
+    // immutable: true
+  }
+);
+
+function _sigmoid_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = _sigmoid_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+// class generated from unary_op_class("Sigmoid", "sigmoid", backward_operations)
+export class Sigmoid extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+    return _sigmoid_tensor(a, a.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)));
+  }
+}
+registerOperation('sigmoid', Sigmoid);
\ No newline at end of file
diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2
index 3c4fbd02..8eeb1955 100644
--- a/src/nn/ops.ts.j2
+++ b/src/nn/ops.ts.j2
@@ -11,4 +11,7 @@ import { Operation, BinaryOperation, UnaryOperation } from '../operations/base';
 import { registerOperation } from '../operations/registry';
 
 {{ unary_op_base("relu", "Math.max(a[this.thread.x], 0)") }}
-{{ unary_op_class("Relu", "relu", ["a.backward(dz.mul(a.gt(0)));"]) }}
\ No newline at end of file
+{{ unary_op_class("Relu", "relu", ["a.backward(dz.mul(a.gt(0)));"]) }}
+
+{{ unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[this.thread.x]))") }}
+{{ unary_op_class("Sigmoid", "sigmoid", ["a.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)));"]) }}
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 99f8769e..762f5ca5 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -718,11 +718,11 @@ export class Sign extends UnaryOperation {
 }
 registerOperation('sign', Sign);
 
-// function generated from unary_op_base("neg", "Math.sign(a[this.thread.x]) * a[this.thread.x]")
+// function generated from unary_op_base("neg", "-a[this.thread.x]")
 
 const _neg_kernel = gpu.createKernel(
   function (a: number[]) {
-    return Math.sign(a[this.thread.x]) * a[this.thread.x];
+    return -a[this.thread.x];
   },
   {
     dynamicOutput: true,
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index fd68ca2d..369bc0ef 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -102,7 +102,7 @@ registerOperation('powint', PowInt);
 {{ unary_op_base("sign", "Math.sign(a[this.thread.x])") }}
 {{ unary_op_class("Sign", "sign", []) }}
 
-{{ unary_op_base("neg", "Math.sign(a[this.thread.x]) * a[this.thread.x]") }}
+{{ unary_op_base("neg", "-a[this.thread.x]") }}
 {{ unary_op_class("Neg", "neg", ["a.backward(dz.mul(new Tensor(-1)));"]) }}
 
 {{ unary_op_base("reciprocal", "1 / a[this.thread.x]") }}

From 4fd6c0809f9fa059b23c48658ca278607c5b408e Mon Sep 17 00:00:00 2001
From: Hua Zhi Vee 
Date: Fri, 23 Jan 2026 11:19:31 +0800
Subject: [PATCH 054/128] feat: use cpu directly instead of via gpu.js

---
 scripts/.gitignore             |   2 +-
 scripts/macros.ts.j2           | 214 ++++++--
 scripts/macros_gpujs.ts.j2     | 300 +++++++++++
 src/nn/loss.ts                 |   5 -
 src/nn/ops.gen.ts              |  44 +-
 src/nn/ops.ts.j2               |   4 +-
 src/operations/functional.ts   |   5 +
 src/operations/ops.gen.ts      | 887 ++++++++++++++-------------------
 src/operations/ops.ts.j2       | 225 +--------
 src/tensor.ts                  |  15 +-
 test/broadcast.test.js         |  32 ++
 test/custom_operations.test.js |  75 +++
 test/index.html                |  56 ++-
 test/loss.test.js              |  41 ++
 test/tensor.test.js            |  69 ++-
 15 files changed, 1177 insertions(+), 797 deletions(-)
 create mode 100644 scripts/macros_gpujs.ts.j2
 create mode 100644 test/broadcast.test.js
 create mode 100644 test/custom_operations.test.js
 create mode 100644 test/loss.test.js

diff --git a/scripts/.gitignore b/scripts/.gitignore
index a395bf38..21c55e20 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1 +1 @@
-macros.gen.ts
\ No newline at end of file
+*.gen.ts
\ No newline at end of file
diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2
index cba25b95..93ec90ce 100644
--- a/scripts/macros.ts.j2
+++ b/scripts/macros.ts.j2
@@ -1,22 +1,17 @@
 {% macro kernel_options() -%}
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
-  }
+  {}
 {%- endmacro %}
 
 {% macro binary_op_base(name, operation) -%}
-const _{{ name }}_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return {{ operation }};
-  },
-  {{ kernel_options() }}
-);
+const _{{ name }}_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = {{ operation }};
+  }
+  return res;
+};
 
 function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -24,13 +19,10 @@ function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null =
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _{{ name }}_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -40,19 +32,20 @@ function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null =
 {% macro unary_op_base(name, operation) -%}
 // function generated from unary_op_base("{{ name }}", "{{ operation }}")
 
-const _{{ name }}_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return {{ operation }};
-  },
-  {{ kernel_options() }}
-);
+const _{{ name }}_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = {{ operation }};
+  }
+  return res;
+};
 
 function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _{{ name }}_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -97,4 +90,169 @@ export class {{ classname }} extends UnaryOperation {
   }
 }
 registerOperation('{{ opname }}', {{ classname }});
+{%- endmacro %}
+
+{% macro powint_op_base() -%}
+function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor {
+  const data = new Array(a.dataLength());
+  for (let i = 0; i < data.length; i++) {
+    data[i] = Math.pow(a.data[i], n);
+  }
+  return new Tensor(
+    data,
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+{%- endmacro %}
+
+{% macro powint_op_class() -%}
+export class PowInt extends Operation {
+  private cache: [Tensor, number];
+  public forward(a: Tensor, n: number): Tensor {
+    if (a.requires_grad) {
+      this.cache = [a, n];
+    }
+
+    return _powint_tensor(a, n, a.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, n] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(n).mul(a.pow(n - 1)));
+  }
+}
+registerOperation('powint', PowInt);
+{%- endmacro %}
+
+{% macro transpose_op_base() -%}
+function _transpose_tensor(
+  a: Tensor,
+  dim0: number,
+  dim1: number,
+  operation: Operation | null = null
+): Tensor {
+  const output_shape = [...a.shape];
+  [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]];
+  const size = a.dataLength();
+  const data = new Array(size);
+
+  const a_strides = new Array(a.shape.length);
+  const out_strides = new Array(output_shape.length);
+  for (let i = a.shape.length - 1, s = 1; i >= 0; i--) {
+    a_strides[i] = s;
+    s *= a.shape[i];
+  }
+  for (let i = output_shape.length - 1, s = 1; i >= 0; i--) {
+    out_strides[i] = s;
+    s *= output_shape[i];
+  }
+
+  for(let i=0; i acc * val, 1);
+  const data = new Array(output_size).fill(0);
+
+  const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
+
+  const dim_M = broadcast_shape[broadcast_shape.length - 2];
+  const dim_N = broadcast_shape[broadcast_shape.length - 1];
+  const dim_K = a_shape[a_shape.length - 1]; // or b_shape[b_shape.length - 2]
+
+  for (let i = 0; i < output_size; i++) {
+    const mn_idx = i % (dim_M * dim_N);
+    const m = Math.floor(mn_idx / dim_N);
+    const n = mn_idx % dim_N;
+
+    let base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n);
+    let base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N);
+
+    let sum = 0;
+    for(let k=0; k < dim_K; k++) {
+      sum += a.data[base_a + k] * b.data[base_b + k * dim_N];
+    }
+    data[i] = sum;
+  }
+
+  let shape_after_removing_extra_dims = [...broadcast_shape];
+
+  if (a_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims
+      .slice(0, -2)
+      .concat([broadcast_shape[broadcast_shape.length - 1]]);
+  }
+
+  if (b_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
+  }
+
+  return new Tensor(
+    data,
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: shape_after_removing_extra_dims }
+  );
+}
 {%- endmacro %}
\ No newline at end of file
diff --git a/scripts/macros_gpujs.ts.j2 b/scripts/macros_gpujs.ts.j2
new file mode 100644
index 00000000..f3f5cc2b
--- /dev/null
+++ b/scripts/macros_gpujs.ts.j2
@@ -0,0 +1,300 @@
+{% macro kernel_options() -%}
+  {
+    dynamicOutput: true,
+    dynamicArguments: true,
+    // pipeline: true,
+    immutable: true
+  }
+{%- endmacro %}
+
+{% macro binary_op_base(name, operation) -%}
+const _{{ name }}_kernel = gpu.createKernel(
+  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
+    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+    return {{ operation }};
+  },
+  {{ kernel_options() }}
+);
+
+function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = _{{ name }}_kernel;
+  kernel.setConstants({
+    shape_length: broadcast_shape.length
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+{%- endmacro %}
+
+{% macro unary_op_base(name, operation) -%}
+// function generated from unary_op_base("{{ name }}", "{{ operation }}")
+
+const _{{ name }}_kernel = gpu.createKernel(
+  function (a: number[]) {
+    const x = this.thread.x;
+    return {{ operation }};
+  },
+  {{ kernel_options() }}
+);
+
+function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tensor {
+  const kernel = _{{ name }}_kernel;
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+{%- endmacro %}
+
+{% macro binary_op_class(classname, opname, backward_operations) -%}
+// class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations)
+export class {{ classname }} extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    if (a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    {{ backward_operations | join("\n    ") }}
+  }
+}
+registerOperation('{{ opname }}', {{ classname }});
+{%- endmacro %}
+
+{% macro unary_op_class(classname, opname, backward_operations) -%}
+// class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations)
+export class {{ classname }} extends UnaryOperation {
+  private cache: [Tensor];
+  public forward(a: Tensor): Tensor {
+    if (a.requires_grad) {
+      this.cache = [a];
+    }
+    return _{{ opname }}_tensor(a, a.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a] = this.cache;
+
+    // backward_operations:
+    {{ backward_operations | join("\n    ") }}
+  }
+}
+registerOperation('{{ opname }}', {{ classname }});
+{%- endmacro %}
+
+{% macro powint_op_base() -%}
+function _powint_kernel_function(a: number[], n: number) {
+  return Math.pow(a[this.thread.x], n);
+}
+
+const _powint_kernel = gpu.createKernel(
+  _powint_kernel_function,
+  {{ kernel_options() }}
+);
+
+function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor {
+  const kernel = _powint_kernel;
+  /* kernel.setConstants({
+    n: n
+  }); */
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+
+  return new Tensor(
+    kernel(a.data, n) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: a.shape }
+  );
+}
+{%- endmacro %}
+
+{% macro powint_op_class() -%}
+export class PowInt extends Operation {
+  private cache: [Tensor, number];
+  public forward(a: Tensor, n: number): Tensor {
+    if (a.requires_grad) {
+      this.cache = [a, n];
+    }
+
+    return _powint_tensor(a, n, a.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, n] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.mul(n).mul(a.pow(n - 1)));
+  }
+}
+registerOperation('powint', PowInt);
+{%- endmacro %}
+
+{% macro transpose_op_base() -%}
+const _transpose_kernel = gpu.createKernel(
+  function (a: number[], as: number[], dim0: number, dim1: number) {
+    const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
+    return a[a_index];
+  },
+  {{ kernel_options() }}
+);
+
+function _transpose_tensor(
+  a: Tensor,
+  dim0: number,
+  dim1: number,
+  operation: Operation | null = null
+): Tensor {
+  const kernel = _transpose_kernel;
+  kernel.setConstants({
+    shape_length: a.shape.length
+  });
+  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+
+  const swapped_shape = [...a.shape];
+  [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
+
+  return new Tensor(
+    kernel(a.data, a.shape, dim0, dim1) as number[],
+    { requires_grad: a.requires_grad },
+    { operation: operation, shape: swapped_shape }
+  );
+}
+{%- endmacro %}
+
+{% macro transpose_op_class() -%}
+export class Transpose extends Operation {
+  cache: [Tensor, number, number];
+  forward(a: Tensor, dim0: number, dim1: number): Tensor {
+    this.cache = [a, dim0, dim1];
+    return _transpose_tensor(a, dim0, dim1, this);
+  }
+  backward(dz: Tensor): void {
+    const [a, dim0, dim1] = this.cache;
+
+    // backward_operations:
+    a.backward(dz.transpose(dim0, dim1));
+  }
+}
+registerOperation('transpose', Transpose);
+{%- endmacro %}
+
+{% macro matmul_op_base() -%}
+function _matmul_kernel_function(
+  a: number[],
+  as: number[],
+  b: number[],
+  bs: number[],
+  bcs: number[]
+) {
+  let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
+  let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+
+  const l = this.constants.shape_length;
+
+  const tmp1 = bcs[l] * bcs[l + 1];
+  const position = this.thread.x % tmp1;
+
+  a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
+  b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
+
+  const b_stride = bs[l + 1];
+
+  let sum = 0;
+  for (let i = 0; i < this.constants.lp; i++) {
+    sum = sum + a[a_index] * b[b_index];
+    a_index = a_index + 1;
+    b_index = b_index + b_stride;
+  }
+
+  return sum;
+}
+
+const _matmul_kernel = gpu.createKernel(_matmul_kernel_function,
+  {{ kernel_options() }}
+);
+
+function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  if (a.shape.length == 1 && b.shape.length == 1) {
+    return a.mul(b).sum();
+  }
+
+  const a_1d = a.shape.length == 1;
+  const b_1d = b.shape.length == 1;
+
+  const a_shape = a_1d ? [1, a.shape[0]] : a.shape;
+  const b_shape = b_1d ? [b.shape[0], 1] : b.shape;
+
+  if (a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
+    // TODO: check what error pytorch throws
+    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
+  }
+
+  const loop_iterations = a_shape[a_shape.length - 1];
+
+  if (loop_iterations > 1000) {
+    // TODO: can try fixing with maxLoopIterations by gpu.js
+    throw new Error('Loop iterations too large: ' + loop_iterations);
+  }
+
+  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([
+    a_shape[a_shape.length - 2],
+    b_shape[b_shape.length - 1]
+  ]);
+
+  const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
+
+  const kernel = _matmul_kernel;
+
+  {#- if(broadcast_shape.length < 2) { // shouldn't happen, but just in case
+    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
+  } #}
+
+  kernel.setConstants({
+    lp: loop_iterations,
+    // assumes that _get_original_index_kernel reads from the front
+    shape_length: broadcast_shape.length - 2
+  });
+  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+
+  let shape_after_removing_extra_dims = [...broadcast_shape];
+
+  if (a_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims
+      .slice(0, -2)
+      .concat([broadcast_shape[broadcast_shape.length - 1]]);
+  }
+
+  if (b_1d) {
+    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
+  }
+
+  return new Tensor(
+    kernel(
+      a.data,
+      padded_a_shape,
+      b.data,
+      padded_b_shape,
+      broadcast_shape
+    ) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: shape_after_removing_extra_dims }
+  );
+}
+{%- endmacro %}
\ No newline at end of file
diff --git a/src/nn/loss.ts b/src/nn/loss.ts
index 373698ff..3651c720 100644
--- a/src/nn/loss.ts
+++ b/src/nn/loss.ts
@@ -34,12 +34,7 @@ export class BCELoss extends Loss {
 
   forward(input: Tensor, target: Tensor) {
     const left = target.mul(input.log());
-    console.log("input", input);
-    console.log("input.log()", input.log());
-    console.log("target", target);
-    console.log("LEFT", left);
     const right = target.neg().add(1).mul(input.neg().add(1).log());
-    console.log("RIGHT", right);
     const loss = left.add(right).neg().mean();
     if (this.weight) {
       return loss.mul(this.weight);
diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts
index 8b587767..78cf2662 100644
--- a/src/nn/ops.gen.ts
+++ b/src/nn/ops.gen.ts
@@ -10,26 +10,22 @@ import gpu from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from '../operations/base';
 import { registerOperation } from '../operations/registry';
 
-// function generated from unary_op_base("relu", "Math.max(a[this.thread.x], 0)")
+// function generated from unary_op_base("relu", "Math.max(a[x], 0)")
 
-const _relu_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.max(a[this.thread.x], 0);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _relu_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.max(a[x], 0);
   }
-);
+  return res;
+};
 
 function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _relu_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -52,26 +48,22 @@ export class Relu extends UnaryOperation {
 }
 registerOperation('relu', Relu);
 
-// function generated from unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[this.thread.x]))")
+// function generated from unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[x]))")
 
-const _sigmoid_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return 1 / (1 + Math.exp(-a[this.thread.x]));
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _sigmoid_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = 1 / (1 + Math.exp(-a[x]));
   }
-);
+  return res;
+};
 
 function _sigmoid_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _sigmoid_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2
index 8eeb1955..7d91bcf8 100644
--- a/src/nn/ops.ts.j2
+++ b/src/nn/ops.ts.j2
@@ -10,8 +10,8 @@ import gpu from '../gpu';
 import { Operation, BinaryOperation, UnaryOperation } from '../operations/base';
 import { registerOperation } from '../operations/registry';
 
-{{ unary_op_base("relu", "Math.max(a[this.thread.x], 0)") }}
+{{ unary_op_base("relu", "Math.max(a[x], 0)") }}
 {{ unary_op_class("Relu", "relu", ["a.backward(dz.mul(a.gt(0)));"]) }}
 
-{{ unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[this.thread.x]))") }}
+{{ unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[x]))") }}
 {{ unary_op_class("Sigmoid", "sigmoid", ["a.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)));"]) }}
diff --git a/src/operations/functional.ts b/src/operations/functional.ts
index 797a471a..962f9b4d 100644
--- a/src/operations/functional.ts
+++ b/src/operations/functional.ts
@@ -34,6 +34,11 @@ function generate_binary_function(opname: string) {
   };
 }
 
+// debug operations
+
+export const __left_index__ = generate_binary_function('__left_index__');
+export const __right_index__ = generate_binary_function('__right_index__');
+
 // binary pointwise
 
 export const add = generate_binary_function('add');
diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts
index 762f5ca5..657a0df1 100644
--- a/src/operations/ops.gen.ts
+++ b/src/operations/ops.gen.ts
@@ -3,6 +3,7 @@ import { Tensor } from '../tensor';
 import {
   _broadcast_shape,
   _get_original_index_from_transposed_index,
+  _get_original_index,
   _get_original_index_kernel,
   _pad_shape
 } from '../broadcasting';
@@ -11,22 +12,103 @@ import { Operation, BinaryOperation, UnaryOperation } from './base';
 import * as functional from './functional';
 import { registerOperation } from './registry';
 
-// binary pointwise
+// debug operations
+
+const ___left_index___kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = a_index;
+  }
+  return res;
+};
+
+function ___left_index___tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = ___left_index___kernel;
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("__Left_index__", "__left_index__", backward_operations)
+export class __Left_index__ extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    if (a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return ___left_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('__left_index__', __Left_index__);
+
+const ___right_index___kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = b_index;
+  }
+  return res;
+};
+
+function ___right_index___tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
+  const broadcast_shape = _broadcast_shape(a.shape, b.shape);
+  const padded_a_shape = _pad_shape(a.shape, broadcast_shape);
+  const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
+
+  const kernel = ___right_index___kernel;
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
+
+  return new Tensor(
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
+    { requires_grad: a.requires_grad || b.requires_grad },
+    { operation: operation, shape: broadcast_shape }
+  );
+}
+// class generated from binary_op_class("__Right_index__", "__right_index__", backward_operations)
+export class __Right_index__ extends BinaryOperation {
+  private cache: [Tensor, Tensor];
+  public forward(a: Tensor, b: Tensor): Tensor {
+    if (a.requires_grad || b.requires_grad) {
+      this.cache = [a, b];
+    }
+    return ___right_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null);
+  }
+  public backward(dz: Tensor): void {
+    const [a, b] = this.cache;
+
+    // backward_operations:
+    
+  }
+}
+registerOperation('__right_index__', __Right_index__);
 
-const _add_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
+// binary pointwise
 
-    return a[a_index] + b[b_index];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _add_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = a[a_index] + b[b_index];
   }
-);
+  return res;
+};
 
 function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -34,13 +116,10 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _add_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -64,20 +143,15 @@ export class Add extends BinaryOperation {
 }
 registerOperation('add', Add);
 
-const _sub_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return a[a_index] - b[b_index];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _sub_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = a[a_index] - b[b_index];
   }
-);
+  return res;
+};
 
 function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -85,13 +159,10 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _sub_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -115,20 +186,15 @@ export class Sub extends BinaryOperation {
 }
 registerOperation('sub', Sub);
 
-const _mul_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return a[a_index] * b[b_index];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _mul_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = a[a_index] * b[b_index];
   }
-);
+  return res;
+};
 
 function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -136,13 +202,10 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _mul_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -166,20 +229,15 @@ export class Mul extends BinaryOperation {
 }
 registerOperation('mul', Mul);
 
-const _div_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return a[a_index] / b[b_index];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _div_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = a[a_index] / b[b_index];
   }
-);
+  return res;
+};
 
 function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -187,13 +245,10 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _div_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -217,20 +272,15 @@ export class Div extends BinaryOperation {
 }
 registerOperation('div', Div);
 
-const _pow_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return Math.pow(a[a_index], b[b_index]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _pow_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = Math.pow(a[a_index], b[b_index]);
   }
-);
+  return res;
+};
 
 function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -238,13 +288,10 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _pow_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -268,20 +315,15 @@ export class Pow extends BinaryOperation {
 }
 registerOperation('pow', Pow);
 
-const _fmod_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return a[a_index] % b[b_index];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _fmod_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = a[a_index] % b[b_index];
   }
-);
+  return res;
+};
 
 function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -289,13 +331,10 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null):
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _fmod_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -318,20 +357,15 @@ export class Fmod extends BinaryOperation {
 }
 registerOperation('fmod', Fmod);
 
-const _maximum_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return Math.max(a[a_index], b[b_index]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _maximum_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = Math.max(a[a_index], b[b_index]);
   }
-);
+  return res;
+};
 
 function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -339,13 +373,10 @@ function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _maximum_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -369,20 +400,15 @@ export class Maximum extends BinaryOperation {
 }
 registerOperation('maximum', Maximum);
 
-const _minimum_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return Math.min(a[a_index], b[b_index]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _minimum_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = Math.min(a[a_index], b[b_index]);
   }
-);
+  return res;
+};
 
 function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -390,13 +416,10 @@ function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _minimum_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -421,31 +444,17 @@ export class Minimum extends BinaryOperation {
 registerOperation('minimum', Minimum);
 
 
-function _powint_kernel_function(a: number[], n: number) {
-  return Math.pow(a[this.thread.x], n);
-}
-
-const _powint_kernel = gpu.createKernel(
-  _powint_kernel_function,
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
-  }
-);
-
 function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor {
-  const kernel = _powint_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
-
+  const data = new Array(a.dataLength());
+  for (let i = 0; i < data.length; i++) {
+    data[i] = Math.pow(a.data[i], n);
+  }
   return new Tensor(
-    kernel(a.data, n) as number[],
+    data,
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
 }
-
 export class PowInt extends Operation {
   private cache: [Tensor, number];
   public forward(a: Tensor, n: number): Tensor {
@@ -466,26 +475,22 @@ registerOperation('powint', PowInt);
 
 // unary pointwise
 
-// function generated from unary_op_base("log", "Math.log(a[this.thread.x])")
+// function generated from unary_op_base("log", "Math.log(a[x])")
 
-const _log_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.log(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _log_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.log(a[x]);
   }
-);
+  return res;
+};
 
 function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _log_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -508,26 +513,22 @@ export class Log extends UnaryOperation {
 }
 registerOperation('log', Log);
 
-// function generated from unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])")
+// function generated from unary_op_base("sqrt", "Math.sqrt(a[x])")
 
-const _sqrt_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.sqrt(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _sqrt_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.sqrt(a[x]);
   }
-);
+  return res;
+};
 
 function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _sqrt_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -550,26 +551,22 @@ export class Sqrt extends UnaryOperation {
 }
 registerOperation('sqrt', Sqrt);
 
-// function generated from unary_op_base("exp", "Math.exp(a[this.thread.x])")
+// function generated from unary_op_base("exp", "Math.exp(a[x])")
 
-const _exp_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.exp(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _exp_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.exp(a[x]);
   }
-);
+  return res;
+};
 
 function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _exp_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -592,26 +589,22 @@ export class Exp extends UnaryOperation {
 }
 registerOperation('exp', Exp);
 
-// function generated from unary_op_base("square", "a[this.thread.x] * a[this.thread.x]")
+// function generated from unary_op_base("square", "a[x] * a[x]")
 
-const _square_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return a[this.thread.x] * a[this.thread.x];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _square_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = a[x] * a[x];
   }
-);
+  return res;
+};
 
 function _square_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _square_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -634,26 +627,22 @@ export class Square extends UnaryOperation {
 }
 registerOperation('square', Square);
 
-// function generated from unary_op_base("abs", "Math.abs(a[this.thread.x])")
+// function generated from unary_op_base("abs", "Math.abs(a[x])")
 
-const _abs_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.abs(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _abs_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.abs(a[x]);
   }
-);
+  return res;
+};
 
 function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _abs_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -676,26 +665,22 @@ export class Abs extends UnaryOperation {
 }
 registerOperation('abs', Abs);
 
-// function generated from unary_op_base("sign", "Math.sign(a[this.thread.x])")
+// function generated from unary_op_base("sign", "Math.sign(a[x])")
 
-const _sign_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.sign(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _sign_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.sign(a[x]);
   }
-);
+  return res;
+};
 
 function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _sign_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -718,26 +703,22 @@ export class Sign extends UnaryOperation {
 }
 registerOperation('sign', Sign);
 
-// function generated from unary_op_base("neg", "-a[this.thread.x]")
+// function generated from unary_op_base("neg", "-a[x]")
 
-const _neg_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return -a[this.thread.x];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _neg_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = -a[x];
   }
-);
+  return res;
+};
 
 function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _neg_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -760,26 +741,22 @@ export class Neg extends UnaryOperation {
 }
 registerOperation('neg', Neg);
 
-// function generated from unary_op_base("reciprocal", "1 / a[this.thread.x]")
+// function generated from unary_op_base("reciprocal", "1 / a[x]")
 
-const _reciprocal_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return 1 / a[this.thread.x];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _reciprocal_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = 1 / a[x];
   }
-);
+  return res;
+};
 
 function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _reciprocal_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -862,26 +839,22 @@ registerOperation('unsqueeze', Unsqueeze);
 
 // trigonometric
 
-// function generated from unary_op_base("sin", "Math.sin(a[this.thread.x])")
+// function generated from unary_op_base("sin", "Math.sin(a[x])")
 
-const _sin_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.sin(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _sin_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.sin(a[x]);
   }
-);
+  return res;
+};
 
 function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _sin_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -904,26 +877,22 @@ export class Sin extends UnaryOperation {
 }
 registerOperation('sin', Sin);
 
-// function generated from unary_op_base("cos", "Math.cos(a[this.thread.x])")
+// function generated from unary_op_base("cos", "Math.cos(a[x])")
 
-const _cos_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.cos(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _cos_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.cos(a[x]);
   }
-);
+  return res;
+};
 
 function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _cos_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -946,26 +915,22 @@ export class Cos extends UnaryOperation {
 }
 registerOperation('cos', Cos);
 
-// function generated from unary_op_base("tan", "Math.tan(a[this.thread.x])")
+// function generated from unary_op_base("tan", "Math.tan(a[x])")
 
-const _tan_kernel = gpu.createKernel(
-  function (a: number[]) {
-    return Math.tan(a[this.thread.x]);
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _tan_kernel = function (a: number[], output: number) {
+  const res = new Array(output);
+  for(let x = 0; x < output; x++) {
+    res[x] = Math.tan(a[x]);
   }
-);
+  return res;
+};
 
 function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor {
   const kernel = _tan_kernel;
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
+  const output = a.shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data) as number[],
+    kernel(a.data, output) as number[],
     { requires_grad: a.requires_grad },
     { operation: operation, shape: a.shape }
   );
@@ -1046,41 +1011,51 @@ registerOperation('mean', Mean);
 
 // linalg
 
-const _transpose_kernel = gpu.createKernel(
-  function (a: number[], as: number[], dim0: number, dim1: number) {
-    const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
-    return a[a_index];
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
-  }
-);
-
 function _transpose_tensor(
   a: Tensor,
   dim0: number,
   dim1: number,
   operation: Operation | null = null
 ): Tensor {
-  const kernel = _transpose_kernel;
-  kernel.setConstants({
-    shape_length: a.shape.length
-  });
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
-
-  const swapped_shape = [...a.shape];
-  [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
+  const output_shape = [...a.shape];
+  [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]];
+  const size = a.dataLength();
+  const data = new Array(size);
+
+  const a_strides = new Array(a.shape.length);
+  const out_strides = new Array(output_shape.length);
+  for (let i = a.shape.length - 1, s = 1; i >= 0; i--) {
+    a_strides[i] = s;
+    s *= a.shape[i];
+  }
+  for (let i = output_shape.length - 1, s = 1; i >= 0; i--) {
+    out_strides[i] = s;
+    s *= output_shape[i];
+  }
+
+  for(let i=0; i 1000) {
-    // TODO: can try fixing with maxLoopIterations by gpu.js
-    throw new Error('Loop iterations too large: ' + loop_iterations);
-  }
-
   const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([
     a_shape[a_shape.length - 2],
     b_shape[b_shape.length - 1]
   ]);
 
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
+  const data = new Array(output_size).fill(0);
+
   const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
   const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
 
-  const kernel = _matmul_kernel;
-  kernel.setConstants({
-    lp: loop_iterations,
-    // assumes that _get_original_index_kernel reads from the front
-    shape_length: broadcast_shape.length - 2
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const dim_M = broadcast_shape[broadcast_shape.length - 2];
+  const dim_N = broadcast_shape[broadcast_shape.length - 1];
+  const dim_K = a_shape[a_shape.length - 1]; // or b_shape[b_shape.length - 2]
+
+  for (let i = 0; i < output_size; i++) {
+    const mn_idx = i % (dim_M * dim_N);
+    const m = Math.floor(mn_idx / dim_N);
+    const n = mn_idx % dim_N;
+
+    let base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n);
+    let base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N);
+
+    let sum = 0;
+    for(let k=0; k < dim_K; k++) {
+      sum += a.data[base_a + k] * b.data[base_b + k * dim_N];
+    }
+    data[i] = sum;
+  }
 
   let shape_after_removing_extra_dims = [...broadcast_shape];
 
@@ -1187,18 +1129,11 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null
   }
 
   return new Tensor(
-    kernel(
-      a.data,
-      padded_a_shape,
-      b.data,
-      padded_b_shape,
-      broadcast_shape
-    ) as number[],
+    data,
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: shape_after_removing_extra_dims }
   );
 }
-
 // class generated from binary_op_class("Matmul", "matmul", backward_operations)
 export class Matmul extends BinaryOperation {
   private cache: [Tensor, Tensor];
@@ -1219,20 +1154,15 @@ registerOperation('matmul', Matmul);
 
 // comparison
 
-const _lt_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return (a[a_index] < b[b_index]) ? 1 : 0;
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _lt_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = (a[a_index] < b[b_index]) ? 1 : 0;
   }
-);
+  return res;
+};
 
 function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -1240,13 +1170,10 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _lt_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1269,20 +1196,15 @@ export class Lt extends BinaryOperation {
 }
 registerOperation('lt', Lt);
 
-const _gt_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return (a[a_index] > b[b_index]) ? 1 : 0;
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _gt_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = (a[a_index] > b[b_index]) ? 1 : 0;
   }
-);
+  return res;
+};
 
 function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -1290,13 +1212,10 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _gt_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1319,20 +1238,15 @@ export class Gt extends BinaryOperation {
 }
 registerOperation('gt', Gt);
 
-const _le_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return (a[a_index] <= b[b_index]) ? 1 : 0;
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _le_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = (a[a_index] <= b[b_index]) ? 1 : 0;
   }
-);
+  return res;
+};
 
 function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -1340,13 +1254,10 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _le_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1369,20 +1280,15 @@ export class Le extends BinaryOperation {
 }
 registerOperation('le', Le);
 
-const _ge_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return (a[a_index] >= b[b_index]) ? 1 : 0;
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _ge_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = (a[a_index] >= b[b_index]) ? 1 : 0;
   }
-);
+  return res;
+};
 
 function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -1390,13 +1296,10 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _ge_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1419,20 +1322,15 @@ export class Ge extends BinaryOperation {
 }
 registerOperation('ge', Ge);
 
-const _eq_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return (a[a_index] == b[b_index]) ? 1 : 0;
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _eq_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = (a[a_index] == b[b_index]) ? 1 : 0;
   }
-);
+  return res;
+};
 
 function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -1440,13 +1338,10 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _eq_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
@@ -1469,20 +1364,15 @@ export class Eq extends BinaryOperation {
 }
 registerOperation('eq', Eq);
 
-const _ne_kernel = gpu.createKernel(
-  function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) {
-    const a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-    const b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-    return (a[a_index] != b[b_index]) ? 1 : 0;
-  },
-  {
-    dynamicOutput: true,
-    dynamicArguments: true,
-    // pipeline: true,
-    // immutable: true
+const _ne_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) {
+  const res = Array(output_size);
+  for(let x = 0; x < output_size; x++) {
+    const a_index = _get_original_index(as, bcs, x);
+    const b_index = _get_original_index(bs, bcs, x);
+    res[x] = (a[a_index] != b[b_index]) ? 1 : 0;
   }
-);
+  return res;
+};
 
 function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
   const broadcast_shape = _broadcast_shape(a.shape, b.shape);
@@ -1490,13 +1380,10 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T
   const padded_b_shape = _pad_shape(b.shape, broadcast_shape);
 
   const kernel = _ne_kernel;
-  kernel.setConstants({
-    shape_length: broadcast_shape.length
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
+  const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1);
 
   return new Tensor(
-    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[],
+    kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[],
     { requires_grad: a.requires_grad || b.requires_grad },
     { operation: operation, shape: broadcast_shape }
   );
diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2
index 369bc0ef..8b35ff4f 100644
--- a/src/operations/ops.ts.j2
+++ b/src/operations/ops.ts.j2
@@ -1,8 +1,9 @@
-{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class, kernel_options %}
+{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class, kernel_options, powint_op_base, powint_op_class, transpose_op_base, transpose_op_class, matmul_op_base %}
 import { Tensor } from '../tensor';
 import {
   _broadcast_shape,
   _get_original_index_from_transposed_index,
+  _get_original_index,
   _get_original_index_kernel,
   _pad_shape
 } from '../broadcasting';
@@ -11,6 +12,14 @@ import { Operation, BinaryOperation, UnaryOperation } from './base';
 import * as functional from './functional';
 import { registerOperation } from './registry';
 
+// debug operations
+
+{{ binary_op_base("__left_index__", "a_index") }}
+{{ binary_op_class("__Left_index__", "__left_index__", []) }}
+
+{{ binary_op_base("__right_index__", "b_index") }}
+{{ binary_op_class("__Right_index__", "__right_index__", []) }}
+
 // binary pointwise
 
 {{ binary_op_base("add", "a[a_index] + b[b_index]") }}
@@ -41,71 +50,33 @@ import { registerOperation } from './registry';
 {{ binary_op_class("Minimum", "minimum", ["a.backward(dz.mul(a.le(b)));", "b.backward(dz.mul(b.lt(a)));"]) }}
 
 
-function _powint_kernel_function(a: number[], n: number) {
-  return Math.pow(a[this.thread.x], n);
-}
-
-const _powint_kernel = gpu.createKernel(
-  _powint_kernel_function,
-  {{ kernel_options() }}
-);
-
-function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor {
-  const kernel = _powint_kernel;
-  {# kernel.setConstants({
-    n: n
-  }); #}
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
-
-  return new Tensor(
-    kernel(a.data, n) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: a.shape }
-  );
-}
-
-export class PowInt extends Operation {
-  private cache: [Tensor, number];
-  public forward(a: Tensor, n: number): Tensor {
-    if (a.requires_grad) {
-      this.cache = [a, n];
-    }
-
-    return _powint_tensor(a, n, a.requires_grad ? this : null);
-  }
-  public backward(dz: Tensor): void {
-    const [a, n] = this.cache;
-
-    // backward_operations:
-    a.backward(dz.mul(n).mul(a.pow(n - 1)));
-  }
-}
-registerOperation('powint', PowInt);
+{{ powint_op_base() }}
+{{ powint_op_class() }}
 
 // unary pointwise
 
-{{ unary_op_base("log", "Math.log(a[this.thread.x])") }}
+{{ unary_op_base("log", "Math.log(a[x])") }}
 {{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }}
 
-{{ unary_op_base("sqrt", "Math.sqrt(a[this.thread.x])") }}
+{{ unary_op_base("sqrt", "Math.sqrt(a[x])") }}
 {{ unary_op_class("Sqrt", "sqrt", ["a.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }}
 
-{{ unary_op_base("exp", "Math.exp(a[this.thread.x])") }}
+{{ unary_op_base("exp", "Math.exp(a[x])") }}
 {{ unary_op_class("Exp", "exp", ["a.backward(dz.mul(a.exp()));"]) }}
 
-{{ unary_op_base("square", "a[this.thread.x] * a[this.thread.x]") }}
+{{ unary_op_base("square", "a[x] * a[x]") }}
 {{ unary_op_class("Square", "square", ["a.backward(dz.mul(a).mul(new Tensor(2)));"]) }}
 
-{{ unary_op_base("abs", "Math.abs(a[this.thread.x])") }}
+{{ unary_op_base("abs", "Math.abs(a[x])") }}
 {{ unary_op_class("Abs", "abs", ["a.backward(dz.mul(functional.sign(a)));"]) }}
 
-{{ unary_op_base("sign", "Math.sign(a[this.thread.x])") }}
+{{ unary_op_base("sign", "Math.sign(a[x])") }}
 {{ unary_op_class("Sign", "sign", []) }}
 
-{{ unary_op_base("neg", "-a[this.thread.x]") }}
+{{ unary_op_base("neg", "-a[x]") }}
 {{ unary_op_class("Neg", "neg", ["a.backward(dz.mul(new Tensor(-1)));"]) }}
 
-{{ unary_op_base("reciprocal", "1 / a[this.thread.x]") }}
+{{ unary_op_base("reciprocal", "1 / a[x]") }}
 {{ unary_op_class("Reciprocal", "reciprocal", ["a.backward(dz.mul(a.pow(-2)));"]) }}
 
 export class Reshape extends Operation {
@@ -168,13 +139,13 @@ registerOperation('unsqueeze', Unsqueeze);
 
 // trigonometric
 
-{{ unary_op_base("sin", "Math.sin(a[this.thread.x])") }}
+{{ unary_op_base("sin", "Math.sin(a[x])") }}
 {{ unary_op_class("Sin", "sin", ["a.backward(dz.mul(a.cos()));"]) }}
 
-{{ unary_op_base("cos", "Math.cos(a[this.thread.x])") }}
+{{ unary_op_base("cos", "Math.cos(a[x])") }}
 {{ unary_op_class("Cos", "cos", ["a.backward(dz.mul(a.sin().neg()));"]) }}
 
-{{ unary_op_base("tan", "Math.tan(a[this.thread.x])") }}
+{{ unary_op_base("tan", "Math.tan(a[x])") }}
 {{ unary_op_class("Tan", "tan", ["a.backward(dz.mul(a.cos().pow(-2)));"]) }}
 
 // reduction
@@ -201,154 +172,10 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor {
 
 // linalg
 
-const _transpose_kernel = gpu.createKernel(
-  function (a: number[], as: number[], dim0: number, dim1: number) {
-    const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x);
-    return a[a_index];
-  },
-  {{ kernel_options() }}
-);
-
-function _transpose_tensor(
-  a: Tensor,
-  dim0: number,
-  dim1: number,
-  operation: Operation | null = null
-): Tensor {
-  const kernel = _transpose_kernel;
-  kernel.setConstants({
-    shape_length: a.shape.length
-  });
-  kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]);
-
-  const swapped_shape = [...a.shape];
-  [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]];
-
-  return new Tensor(
-    kernel(a.data, a.shape, dim0, dim1) as number[],
-    { requires_grad: a.requires_grad },
-    { operation: operation, shape: swapped_shape }
-  );
-}
-
-export class Transpose extends Operation {
-  cache: [Tensor, number, number];
-  forward(a: Tensor, dim0: number, dim1: number): Tensor {
-    this.cache = [a, dim0, dim1];
-    return _transpose_tensor(a, dim0, dim1, this);
-  }
-  backward(dz: Tensor): void {
-    const [a, dim0, dim1] = this.cache;
-
-    // backward_operations:
-    a.backward(dz.transpose(dim0, dim1));
-  }
-}
-registerOperation('transpose', Transpose);
-
-function _matmul_kernel_function(
-  a: number[],
-  as: number[],
-  b: number[],
-  bs: number[],
-  bcs: number[]
-) {
-  let a_index = _get_original_index_kernel(as, bcs, this.thread.x);
-  let b_index = _get_original_index_kernel(bs, bcs, this.thread.x);
-
-  const l = this.constants.shape_length;
-
-  const tmp1 = bcs[l] * bcs[l + 1];
-  const position = this.thread.x % tmp1;
-
-  a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1];
-  b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]);
-
-  const b_stride = bs[l + 1];
-
-  let sum = 0;
-  for (let i = 0; i < this.constants.lp; i++) {
-    sum = sum + a[a_index] * b[b_index];
-    a_index = a_index + 1;
-    b_index = b_index + b_stride;
-  }
-
-  return sum;
-}
-
-const _matmul_kernel = gpu.createKernel(_matmul_kernel_function,
-  {{ kernel_options() }}
-);
-
-function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor {
-  if (a.shape.length == 1 && b.shape.length == 1) {
-    return a.mul(b).sum();
-  }
-
-  const a_1d = a.shape.length == 1;
-  const b_1d = b.shape.length == 1;
-
-  const a_shape = a_1d ? [1, a.shape[0]] : a.shape;
-  const b_shape = b_1d ? [b.shape[0], 1] : b.shape;
-
-  if (a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) {
-    // TODO: check what error pytorch throws
-    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
-  }
-
-  const loop_iterations = a_shape[a_shape.length - 1];
-
-  if (loop_iterations > 1000) {
-    // TODO: can try fixing with maxLoopIterations by gpu.js
-    throw new Error('Loop iterations too large: ' + loop_iterations);
-  }
-
-  const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([
-    a_shape[a_shape.length - 2],
-    b_shape[b_shape.length - 1]
-  ]);
-
-  const padded_a_shape = _pad_shape(a_shape, broadcast_shape);
-  const padded_b_shape = _pad_shape(b_shape, broadcast_shape);
-
-  const kernel = _matmul_kernel;
-
-  {#- if(broadcast_shape.length < 2) { // shouldn't happen, but just in case
-    throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape);
-  } #}
-
-  kernel.setConstants({
-    lp: loop_iterations,
-    // assumes that _get_original_index_kernel reads from the front
-    shape_length: broadcast_shape.length - 2
-  });
-  kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]);
-
-  let shape_after_removing_extra_dims = [...broadcast_shape];
-
-  if (a_1d) {
-    shape_after_removing_extra_dims = shape_after_removing_extra_dims
-      .slice(0, -2)
-      .concat([broadcast_shape[broadcast_shape.length - 1]]);
-  }
-
-  if (b_1d) {
-    shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1);
-  }
-
-  return new Tensor(
-    kernel(
-      a.data,
-      padded_a_shape,
-      b.data,
-      padded_b_shape,
-      broadcast_shape
-    ) as number[],
-    { requires_grad: a.requires_grad || b.requires_grad },
-    { operation: operation, shape: shape_after_removing_extra_dims }
-  );
-}
+{{ transpose_op_base() }}
+{{ transpose_op_class() }}
 
+{{ matmul_op_base() }}
 {{ binary_op_class("Matmul", "matmul", []) }}
 
 // comparison
diff --git a/src/tensor.ts b/src/tensor.ts
index 4e11244c..5cae8a40 100644
--- a/src/tensor.ts
+++ b/src/tensor.ts
@@ -45,7 +45,7 @@ function _flatten(data: NestedNumberArray): number[] {
 }
 
 export class Tensor {
-  data: number[] | Texture;
+  data: number[];
   _shape: number[];
   operation: Operation | null = null;
   public grad: Tensor | null = null;
@@ -53,14 +53,14 @@ export class Tensor {
   requires_grad: boolean;
 
   constructor(
-    data: NestedNumberArray | Texture,
+    data: NestedNumberArray,
     options: { requires_grad?: boolean } = {},
     internal_options: { operation?: Operation; shape?: number[] } = {}
   ) {
-    this.data = data instanceof Texture ? data : _flatten(data);
+    this.data = _flatten(data);
     this.requires_grad = options.requires_grad ?? false;
 
-    this._shape = internal_options.shape ?? _get_shape(data instanceof Texture ? data.toArray() : data);
+    this._shape = internal_options.shape ?? _get_shape(data);
     this.operation = internal_options.operation ?? null;
   }
 
@@ -74,15 +74,10 @@ export class Tensor {
   }
 
   toArray_(): void {
-    if (this.data instanceof Texture) {
-      this.data = this.data.toArray() as number[];
-    }
+    return;
   }
 
   toArray(): number[] {
-    if (this.data instanceof Texture) {
-      return this.data.toArray() as number[];
-    }
     return this.data;
   }
 
diff --git a/test/broadcast.test.js b/test/broadcast.test.js
new file mode 100644
index 00000000..0d8033ab
--- /dev/null
+++ b/test/broadcast.test.js
@@ -0,0 +1,32 @@
+import { assert } from 'chai';
+import { Tensor, add, __left_index__, __right_index__ } from 'torch';
+
+describe('Broadcast Index', () => {
+    it('Broadcast indices should be correct in 2d array', () => {
+        const arr = new Tensor([
+            [0, 0],
+            [0, 0],
+            [0, 0]
+        ]);
+
+        assert.deepStrictEqual(__left_index__(arr, arr).toArray(), [0, 1, 2, 3, 4, 5]);
+        assert.deepStrictEqual(__right_index__(arr, arr).toArray(), [0, 1, 2, 3, 4, 5]);
+    });
+
+    it('Should get correct value of left and right index', () => {
+        const arr = new Tensor([
+            [1, 2],
+            [3, 4],
+            [5, 6]
+        ]);
+
+        const zeros = new Tensor([
+            [0, 0],
+            [0, 0],
+            [0, 0]
+        ])
+
+        assert.deepStrictEqual(add(arr, zeros).toArray(), [1, 2, 3, 4, 5, 6]);
+        assert.deepStrictEqual(add(zeros, arr).toArray(), [1, 2, 3, 4, 5, 6]);
+    });
+});
\ No newline at end of file
diff --git a/test/custom_operations.test.js b/test/custom_operations.test.js
new file mode 100644
index 00000000..2b954286
--- /dev/null
+++ b/test/custom_operations.test.js
@@ -0,0 +1,75 @@
+import { assert } from 'chai';
+import { Tensor } from 'torch';
+
+describe('Custom Operations', () => {
+
+  describe('Matmul', () => {
+    it('should perform matrix multiplication on 2D tensors', () => {
+      const t1 = new Tensor([
+        [1, 2, 3],
+        [4, 5, 6]
+      ]);
+      const t2 = new Tensor([
+        [7, 8],
+        [9, 1],
+        [2, 3]
+      ]);
+
+      const result = t1.matmul(t2);
+      assert.deepStrictEqual(result.shape, [2, 2]);
+      assert.deepStrictEqual(Array.from(result.toArray()), [31, 19, 85, 55]);
+    });
+
+    it('should perform dot product on 1D tensors', () => {
+      const t1 = new Tensor([1, 2, 3]);
+      const t2 = new Tensor([4, 5, 6]);
+
+      const result = t1.matmul(t2);
+      assert.deepStrictEqual(result.shape, [1]);
+      assert.deepStrictEqual(Array.from(result.toArray()), [32]);
+    });
+
+    it('should handle batch matrix multiplication', () => {
+      const t1 = new Tensor([
+        [[62, 50], [7, 53]],
+        [[5, 48], [63, 94]]
+      ]);
+      const t2 = new Tensor([
+        [[98, 3], [59, 81]],
+        [[79, 74], [41, 98]]
+      ]);
+
+      const result = t1.matmul(t2);
+      assert.deepStrictEqual(result.shape, [2, 2, 2]);
+
+      const data = Array.from(result.toArray());
+      assert.deepStrictEqual(data, [9026, 4236, 3813, 4314, 2363, 5074, 8831, 13874]);
+    });
+  });
+
+  describe('Transpose', () => {
+    it('should transpose a 2D tensor', () => {
+      const t = new Tensor([
+        [1, 2, 3],
+        [4, 5, 6]
+      ]);
+
+      const result = t.transpose(0, 1);
+      assert.deepStrictEqual(result.shape, [3, 2]);
+      assert.deepStrictEqual(Array.from(result.toArray()), [1, 4, 2, 5, 3, 6]);
+    });
+
+    it('should transpose dimensions in a 3D tensor', () => {
+      const t = new Tensor([
+        [[1, 2], [3, 4]],
+        [[5, 6], [7, 8]]
+      ]);
+
+      const result = t.transpose(1, 2);
+      assert.deepStrictEqual(result.shape, [2, 2, 2]);
+      const data = Array.from(result.toArray());
+      assert.deepStrictEqual(data, [1, 3, 2, 4, 5, 7, 6, 8]);
+    });
+  });
+
+});
diff --git a/test/index.html b/test/index.html
index 01db6bed..06bbb5f9 100644
--- a/test/index.html
+++ b/test/index.html
@@ -1,22 +1,24 @@
 
 
-  
-    
-    Mocha Tests
-    
-    
-  
-  
-    
- - + + + Mocha Tests + + + - - + + + + - - + + + \ No newline at end of file diff --git a/test/loss.test.js b/test/loss.test.js new file mode 100644 index 00000000..2664f922 --- /dev/null +++ b/test/loss.test.js @@ -0,0 +1,41 @@ + +import * as torch from 'torch'; +import { Tensor } from 'torch'; +import { assert } from 'chai'; + +describe('BCELoss', () => { + it('scalar', () => { + const input = new Tensor(0.123, { requires_grad: true }); + const target = new Tensor(0.9876); + + const loss = new torch.nn.BCELoss(); + const result = loss.forward(input, target); + + console.log("BCELoss result:", result.item()); + + assert.closeTo(result.item(), 2.0712, 0.001); + }) + + it('should calculate binary cross entropy loss correctly', () => { + /* Python: + import torch + x, y + */ + const m = new torch.nn.Sigmoid() + const input = new Tensor([[0.5424, 1.3919], + [-1.0297, -0.6352], + [0.5700, -1.0037]], + { requires_grad: true }); + const target = new Tensor([[0.8340, 0.4923], + [0.7729, 0.7560], + [0.5616, 0.0999]]); + + const loss = new torch.nn.BCELoss(); + const result = loss.forward(m.forward(input), target); + + console.log(m.forward(input)) + console.log("BCELoss result:", result.item()); + + assert.closeTo(result.item(), 0.7657, 0.001); + }); +}); diff --git a/test/tensor.test.js b/test/tensor.test.js index f7ca3174..d482fd05 100644 --- a/test/tensor.test.js +++ b/test/tensor.test.js @@ -49,7 +49,7 @@ describe('Tensor', () => { }); describe('Multiplication', () => { - it('should multiply two tensors with same shape', () => { + it('should multiply two tensors with same shape, scalar', () => { const t1 = new Tensor([10]); const t2 = new Tensor([20]); const result = t1.mul(t2); @@ -57,6 +57,51 @@ describe('Tensor', () => { assert.deepStrictEqual(Array.from(result.toArray()), [200]); assert.deepStrictEqual(result.shape, [1]); }); + + it('should multiply two tensors with same shape, scalar 2', () => { + const t1 = new Tensor([-1.0604]); + const t2 = new Tensor([0.7560]); + const result = t1.mul(t2); + + assert.closeTo(Array.from(result.toArray())[0], -0.8016, 0.001); + assert.deepStrictEqual(result.shape, [1]); + }); + + it('should multiply two tensors with the same shape, integers', () => { + const i1 = [[2, 3], [5, 7], [11, 13]] + const t1 = new Tensor(i1); + + const i2 = [[1, 2], [3, 4], [5, 6]] + const t2 = new Tensor(i2); + + const result = t1.mul(t2); + const expected = [[2, 6], [15, 28], [55, 78]] + + for(let i=0;i { + const i1 = [[-0.4583, -0.2220], [-1.3351, -1.0604], [-0.4482, -1.3160]] + const t1 = new Tensor(i1); + + const i2 = [[0.8340, 0.4923], [0.7729, 0.7560], [0.5616, 0.0999]]; + const t2 = new Tensor(i2); + + const result = t1.mul(t2); + const expected = [[-0.3822, -0.1093], [-1.0319, -0.8016], [-0.2517, -0.1315]] + + for(let i=0;i { @@ -179,4 +224,26 @@ describe('Tensor', () => { assert.deepStrictEqual(result.shape, [2, 3, 1]); }); }); + + describe('Unary Operations', () => { + describe('Neg', () => { + it('should negate a tensor', () => { + const t = new Tensor([1, 2, 3, -4]); + const result = t.neg(); + assert.deepStrictEqual(Array.from(result.toArray()), [-1, -2, -3, 4]); + assert.deepStrictEqual(result.shape, [4]); + }); + }); + + describe('Exp', () => { + const input = [1, 2, 3, -4, 2.5, -6.7]; + const t = new Tensor(input); + const result = t.exp(); + const expected = input.map((x) => Math.exp(x)); + for (let i = 0; i < expected.length; i++) { + assert.closeTo(result.data[i], expected[i], 0.0001); + } + assert.deepStrictEqual(result.shape, [6]); + }) + }); }); From d3002574022c7ca221cd9b7efa74858f00160a19 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 6 Feb 2026 14:17:16 +0800 Subject: [PATCH 055/128] refactor: complete removal of gpu.js dependency --- NOTICE | 30 -- package.json | 3 - scripts/macros_gpujs.ts.j2 | 300 ------------- src/gpu.ts | 48 --- src/index.ts | 5 +- src/nn/ops.gen.ts | 1 - src/nn/ops.ts.j2 | 1 - src/operations/ops.gen.ts | 2 +- src/operations/ops.ts.j2 | 1 - src/tensor.ts | 18 +- vendor/gpu-browser.LICENSE.txt | 21 - vendor/gpu-browser.min.js | 28 -- yarn.lock | 766 +-------------------------------- 13 files changed, 11 insertions(+), 1213 deletions(-) delete mode 100644 scripts/macros_gpujs.ts.j2 delete mode 100644 src/gpu.ts delete mode 100644 vendor/gpu-browser.LICENSE.txt delete mode 100644 vendor/gpu-browser.min.js diff --git a/NOTICE b/NOTICE index 201c2bec..5949bbc6 100644 --- a/NOTICE +++ b/NOTICE @@ -38,33 +38,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -================================================================================ -2. GPU.js (MIT License) - -https://github.com/gpujs/gpu.js - -This project includes GPU.js to enable GPU acceleration. -The original license is included below: - -The MIT License - -Copyright (c) 2019 gpu.js Team - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/package.json b/package.json index c1c33a6c..66ca86c4 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,5 @@ "typescript-eslint": "^8.46.0", "vite": "^7.1.9", "vite-plugin-dts": "^4.5.4" - }, - "dependencies": { - "@veehz/gpu.js": "^2.16.0" } } diff --git a/scripts/macros_gpujs.ts.j2 b/scripts/macros_gpujs.ts.j2 deleted file mode 100644 index f3f5cc2b..00000000 --- a/scripts/macros_gpujs.ts.j2 +++ /dev/null @@ -1,300 +0,0 @@ -{% macro kernel_options() -%} - { - dynamicOutput: true, - dynamicArguments: true, - // pipeline: true, - immutable: true - } -{%- endmacro %} - -{% macro binary_op_base(name, operation) -%} -const _{{ name }}_kernel = gpu.createKernel( - function (a: number[], as: number[], b: number[], bs: number[], bcs: number[]) { - const a_index = _get_original_index_kernel(as, bcs, this.thread.x); - const b_index = _get_original_index_kernel(bs, bcs, this.thread.x); - - return {{ operation }}; - }, - {{ kernel_options() }} -); - -function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _{{ name }}_kernel; - kernel.setConstants({ - shape_length: broadcast_shape.length - }); - kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -{%- endmacro %} - -{% macro unary_op_base(name, operation) -%} -// function generated from unary_op_base("{{ name }}", "{{ operation }}") - -const _{{ name }}_kernel = gpu.createKernel( - function (a: number[]) { - const x = this.thread.x; - return {{ operation }}; - }, - {{ kernel_options() }} -); - -function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tensor { - const kernel = _{{ name }}_kernel; - kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]); - - return new Tensor( - kernel(a.data) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -{%- endmacro %} - -{% macro binary_op_class(classname, opname, backward_operations) -%} -// class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations) -export class {{ classname }} extends BinaryOperation { - private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; - } - return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - public backward(dz: Tensor): void { - const [a, b] = this.cache; - - // backward_operations: - {{ backward_operations | join("\n ") }} - } -} -registerOperation('{{ opname }}', {{ classname }}); -{%- endmacro %} - -{% macro unary_op_class(classname, opname, backward_operations) -%} -// class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations) -export class {{ classname }} extends UnaryOperation { - private cache: [Tensor]; - public forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.cache = [a]; - } - return _{{ opname }}_tensor(a, a.requires_grad ? this : null); - } - public backward(dz: Tensor): void { - const [a] = this.cache; - - // backward_operations: - {{ backward_operations | join("\n ") }} - } -} -registerOperation('{{ opname }}', {{ classname }}); -{%- endmacro %} - -{% macro powint_op_base() -%} -function _powint_kernel_function(a: number[], n: number) { - return Math.pow(a[this.thread.x], n); -} - -const _powint_kernel = gpu.createKernel( - _powint_kernel_function, - {{ kernel_options() }} -); - -function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor { - const kernel = _powint_kernel; - /* kernel.setConstants({ - n: n - }); */ - kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]); - - return new Tensor( - kernel(a.data, n) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -{%- endmacro %} - -{% macro powint_op_class() -%} -export class PowInt extends Operation { - private cache: [Tensor, number]; - public forward(a: Tensor, n: number): Tensor { - if (a.requires_grad) { - this.cache = [a, n]; - } - - return _powint_tensor(a, n, a.requires_grad ? this : null); - } - public backward(dz: Tensor): void { - const [a, n] = this.cache; - - // backward_operations: - a.backward(dz.mul(n).mul(a.pow(n - 1))); - } -} -registerOperation('powint', PowInt); -{%- endmacro %} - -{% macro transpose_op_base() -%} -const _transpose_kernel = gpu.createKernel( - function (a: number[], as: number[], dim0: number, dim1: number) { - const a_index = _get_original_index_from_transposed_index(as, dim0, dim1, this.thread.x); - return a[a_index]; - }, - {{ kernel_options() }} -); - -function _transpose_tensor( - a: Tensor, - dim0: number, - dim1: number, - operation: Operation | null = null -): Tensor { - const kernel = _transpose_kernel; - kernel.setConstants({ - shape_length: a.shape.length - }); - kernel.setOutput([a.shape.reduce((acc, val) => acc * val, 1)]); - - const swapped_shape = [...a.shape]; - [swapped_shape[dim0], swapped_shape[dim1]] = [swapped_shape[dim1], swapped_shape[dim0]]; - - return new Tensor( - kernel(a.data, a.shape, dim0, dim1) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: swapped_shape } - ); -} -{%- endmacro %} - -{% macro transpose_op_class() -%} -export class Transpose extends Operation { - cache: [Tensor, number, number]; - forward(a: Tensor, dim0: number, dim1: number): Tensor { - this.cache = [a, dim0, dim1]; - return _transpose_tensor(a, dim0, dim1, this); - } - backward(dz: Tensor): void { - const [a, dim0, dim1] = this.cache; - - // backward_operations: - a.backward(dz.transpose(dim0, dim1)); - } -} -registerOperation('transpose', Transpose); -{%- endmacro %} - -{% macro matmul_op_base() -%} -function _matmul_kernel_function( - a: number[], - as: number[], - b: number[], - bs: number[], - bcs: number[] -) { - let a_index = _get_original_index_kernel(as, bcs, this.thread.x); - let b_index = _get_original_index_kernel(bs, bcs, this.thread.x); - - const l = this.constants.shape_length; - - const tmp1 = bcs[l] * bcs[l + 1]; - const position = this.thread.x % tmp1; - - a_index = a_index * as[l] * as[l + 1] + Math.floor(position / bcs[l + 1]) * as[l + 1]; - b_index = b_index * bs[l] * bs[l + 1] + (position % bcs[l + 1]); - - const b_stride = bs[l + 1]; - - let sum = 0; - for (let i = 0; i < this.constants.lp; i++) { - sum = sum + a[a_index] * b[b_index]; - a_index = a_index + 1; - b_index = b_index + b_stride; - } - - return sum; -} - -const _matmul_kernel = gpu.createKernel(_matmul_kernel_function, - {{ kernel_options() }} -); - -function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { - if (a.shape.length == 1 && b.shape.length == 1) { - return a.mul(b).sum(); - } - - const a_1d = a.shape.length == 1; - const b_1d = b.shape.length == 1; - - const a_shape = a_1d ? [1, a.shape[0]] : a.shape; - const b_shape = b_1d ? [b.shape[0], 1] : b.shape; - - if (a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) { - // TODO: check what error pytorch throws - throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape); - } - - const loop_iterations = a_shape[a_shape.length - 1]; - - if (loop_iterations > 1000) { - // TODO: can try fixing with maxLoopIterations by gpu.js - throw new Error('Loop iterations too large: ' + loop_iterations); - } - - const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([ - a_shape[a_shape.length - 2], - b_shape[b_shape.length - 1] - ]); - - const padded_a_shape = _pad_shape(a_shape, broadcast_shape); - const padded_b_shape = _pad_shape(b_shape, broadcast_shape); - - const kernel = _matmul_kernel; - - {#- if(broadcast_shape.length < 2) { // shouldn't happen, but just in case - throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape); - } #} - - kernel.setConstants({ - lp: loop_iterations, - // assumes that _get_original_index_kernel reads from the front - shape_length: broadcast_shape.length - 2 - }); - kernel.setOutput([broadcast_shape.reduce((acc, val) => acc * val, 1)]); - - let shape_after_removing_extra_dims = [...broadcast_shape]; - - if (a_1d) { - shape_after_removing_extra_dims = shape_after_removing_extra_dims - .slice(0, -2) - .concat([broadcast_shape[broadcast_shape.length - 1]]); - } - - if (b_1d) { - shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1); - } - - return new Tensor( - kernel( - a.data, - padded_a_shape, - b.data, - padded_b_shape, - broadcast_shape - ) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: shape_after_removing_extra_dims } - ); -} -{%- endmacro %} \ No newline at end of file diff --git a/src/gpu.ts b/src/gpu.ts deleted file mode 100644 index f50e202b..00000000 --- a/src/gpu.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * TODO: - * - Probably use Source Academy gpu.js - */ - -import { GPU, Texture } from '@veehz/gpu.js'; -import { - _get_original_index_from_transposed_index, - _get_original_index_kernel -} from './broadcasting'; - -export { Texture }; - -/** - * Problems with gpu: - * - source array too large when all the options dynamicoutput dynamicarguments pipeline immutable are true - * - if pipeline is not used, then the memory transfer is too slow - * - if dynamicarguments is not used, then the source array is too large error will appear (https://github.com/gpujs/gpu.js/issues/495) - * - if dynamicoutputs is not used, then loops and broadcasting cannot be used - * - * CPU is currently fast enough as well. - */ -const gpu = new GPU({ mode: 'cpu' }); - -// gpu.addFunction(_get_original_index_kernel); -gpu.addFunction(_get_original_index_kernel, { - returnType: 'Integer', - argumentTypes: { - original_shape: 'Array', - new_shape: 'Array', - index: 'Integer' - } -}); - -gpu.addFunction(_get_original_index_from_transposed_index, { - returnType: 'Integer', - argumentTypes: { - original_shape: 'Array', - dim0: 'Integer', - dim1: 'Integer', - transposed_index: 'Integer' - } -}); - -export default gpu; - -// for debugging purposes -export { GPU }; diff --git a/src/index.ts b/src/index.ts index 703a65ab..25eb2aad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,9 @@ -import gpu, { GPU } from './gpu'; import { Tensor } from './tensor'; export * from './operations/ops.gen'; +export { Operation } from './operations/base'; export * from './operations/functional'; export * from './creation/index'; export * as nn from './nn/index'; export * as optim from './optim/index'; export { Tensor }; - -// For debugging purposes -export { gpu, GPU }; diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts index 78cf2662..5d90e5fa 100644 --- a/src/nn/ops.gen.ts +++ b/src/nn/ops.gen.ts @@ -6,7 +6,6 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import gpu from '../gpu'; import { Operation, BinaryOperation, UnaryOperation } from '../operations/base'; import { registerOperation } from '../operations/registry'; diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2 index 7d91bcf8..7823bfb8 100644 --- a/src/nn/ops.ts.j2 +++ b/src/nn/ops.ts.j2 @@ -6,7 +6,6 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import gpu from '../gpu'; import { Operation, BinaryOperation, UnaryOperation } from '../operations/base'; import { registerOperation } from '../operations/registry'; diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts index 657a0df1..3e0ad894 100644 --- a/src/operations/ops.gen.ts +++ b/src/operations/ops.gen.ts @@ -7,7 +7,7 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import gpu, { Texture } from '../gpu'; +// import gpu, { Texture } from '../gpu'; import { Operation, BinaryOperation, UnaryOperation } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2 index 8b35ff4f..589962d9 100644 --- a/src/operations/ops.ts.j2 +++ b/src/operations/ops.ts.j2 @@ -7,7 +7,6 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import gpu, { Texture } from '../gpu'; import { Operation, BinaryOperation, UnaryOperation } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; diff --git a/src/tensor.ts b/src/tensor.ts index 5cae8a40..e6e8c7af 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,7 +1,6 @@ import { _get_original_index } from './broadcasting'; import { Operation } from './operations/base'; import { getOperation, getOperationCache } from './operations/registry'; -import { Texture } from './gpu'; /* * TODO: @@ -82,9 +81,6 @@ export class Tensor { } dataLength(): number { - if (this.data instanceof Texture) { - return this.shape.reduce((acc, val) => acc * val, 1); - } return this.data.length; } @@ -153,17 +149,13 @@ export class Tensor { this.grad.toArray_(); - // Add grad to this.grad + // this.grad += grad for (let i = 0; i < grad.dataLength(); i++) { this.grad.data[_get_original_index(this.shape, grad.shape, i)] += grad.data[i]; } if (this.operation) { - // Propagate only the incoming local gradient, not the accumulated one, - // to avoid double-counting when a tensor receives gradients from - // multiple downstream paths. - // this.operation.backward(grad); - this.operation.backward(this.grad); + this.operation.backward(grad); } } @@ -253,11 +245,11 @@ export class Tensor { sin(): Tensor { return this._executeUnaryOp('sin'); } - + cos(): Tensor { return this._executeUnaryOp('cos'); } - + tan(): Tensor { return this._executeUnaryOp('tan'); } @@ -299,7 +291,7 @@ export class Tensor { ge(other: Tensor | number): Tensor { return this._executeBinaryOp('ge', other); } - + eq(other: Tensor | number): Tensor { return this._executeBinaryOp('eq', other); } diff --git a/vendor/gpu-browser.LICENSE.txt b/vendor/gpu-browser.LICENSE.txt deleted file mode 100644 index 7930df93..00000000 --- a/vendor/gpu-browser.LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2019 gpu.js Team - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/vendor/gpu-browser.min.js b/vendor/gpu-browser.min.js deleted file mode 100644 index e41461ba..00000000 --- a/vendor/gpu-browser.min.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * gpu.js - * http://gpu.rocks/ - * - * GPU Accelerated JavaScript - * - * @version 2.16.0 - * @date Wed Nov 16 2022 15:48:40 GMT-0500 (Eastern Standard Time) - * - * @license MIT - * The MIT License - * - * Copyright (c) 2022 gpu.js Team - *//** - * gpu.js - * http://gpu.rocks/ - * - * GPU Accelerated JavaScript - * - * @version 2.16.0 - * @date Wed Nov 16 2022 15:48:37 GMT-0500 (Eastern Standard Time) - * - * @license MIT - * The MIT License - * - * Copyright (c) 2022 gpu.js Team - */ - !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).GPU=e()}}((function(){return function e(t,n,r){function i(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var h=n[a]={exports:{}};t[a][0].call(h.exports,(function(e){return i(t[a][1][e]||e)}),h,h.exports,e,t,n,r)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;ae)return!1;if((n+=t[r+1])>=e)return!0}}function p(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&o.test(String.fromCharCode(e)):!1!==t&&c(e,l)))}function d(e,t){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&u.test(String.fromCharCode(e)):!1!==t&&(c(e,l)||c(e,h)))))}var m=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function f(e,t){return new m(e,{beforeExpr:!0,binop:t})}var g={beforeExpr:!0},x={startsExpr:!0},y={};function b(e,t){return void 0===t&&(t={}),t.keyword=e,y[e]=new m(e,t)}var T={num:new m("num",x),regexp:new m("regexp",x),string:new m("string",x),name:new m("name",x),eof:new m("eof"),bracketL:new m("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new m("]"),braceL:new m("{",{beforeExpr:!0,startsExpr:!0}),braceR:new m("}"),parenL:new m("(",{beforeExpr:!0,startsExpr:!0}),parenR:new m(")"),comma:new m(",",g),semi:new m(";",g),colon:new m(":",g),dot:new m("."),question:new m("?",g),arrow:new m("=>",g),template:new m("template"),invalidTemplate:new m("invalidTemplate"),ellipsis:new m("...",g),backQuote:new m("`",x),dollarBraceL:new m("${",{beforeExpr:!0,startsExpr:!0}),eq:new m("=",{beforeExpr:!0,isAssign:!0}),assign:new m("_=",{beforeExpr:!0,isAssign:!0}),incDec:new m("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new m("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:f("||",1),logicalAND:f("&&",2),bitwiseOR:f("|",3),bitwiseXOR:f("^",4),bitwiseAND:f("&",5),equality:f("==/!=/===/!==",6),relational:f("/<=/>=",7),bitShift:f("<>/>>>",8),plusMin:new m("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:f("%",10),star:f("*",10),slash:f("/",10),starstar:new m("**",{beforeExpr:!0}),_break:b("break"),_case:b("case",g),_catch:b("catch"),_continue:b("continue"),_debugger:b("debugger"),_default:b("default",g),_do:b("do",{isLoop:!0,beforeExpr:!0}),_else:b("else",g),_finally:b("finally"),_for:b("for",{isLoop:!0}),_function:b("function",x),_if:b("if"),_return:b("return",g),_switch:b("switch"),_throw:b("throw",g),_try:b("try"),_var:b("var"),_const:b("const"),_while:b("while",{isLoop:!0}),_with:b("with"),_new:b("new",{beforeExpr:!0,startsExpr:!0}),_this:b("this",x),_super:b("super",x),_class:b("class",x),_extends:b("extends",g),_export:b("export"),_import:b("import",x),_null:b("null",x),_true:b("true",x),_false:b("false",x),_in:b("in",{beforeExpr:!0,binop:7}),_instanceof:b("instanceof",{beforeExpr:!0,binop:7}),_typeof:b("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:b("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:b("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},v=/\r\n?|\n|\u2028|\u2029/,S=new RegExp(v.source,"g");function A(e,t){return 10===e||13===e||!t&&(8232===e||8233===e)}var _=/[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/,E=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,w=Object.prototype,k=w.hasOwnProperty,I=w.toString;function D(e,t){return k.call(e,t)}var C=Array.isArray||function(e){return"[object Array]"===I.call(e)};function $(e){return new RegExp("^(?:"+e.replace(/ /g,"|")+")$")}var L=function(e,t){this.line=e,this.column=t};L.prototype.offset=function(e){return new L(this.line,this.column+e)};var R=function(e,t,n){this.start=t,this.end=n,null!==e.sourceFile&&(this.source=e.sourceFile)};function F(e,t){for(var n=1,r=0;;){S.lastIndex=r;var i=S.exec(e);if(!(i&&i.index=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),C(t.onToken)){var r=t.onToken;t.onToken=function(e){return r.push(e)}}return C(t.onComment)&&(t.onComment=function(e,t){return function(n,r,i,s,a,o){var u={type:n?"Block":"Line",value:r,start:i,end:s};e.locations&&(u.loc=new R(this,a,o)),e.ranges&&(u.range=[i,s]),t.push(u)}}(t,t.onComment)),t}function M(e,t){return 2|(e?4:0)|(t?8:0)}var O=function(e,n,i){this.options=e=V(e),this.sourceFile=e.sourceFile,this.keywords=$(r[e.ecmaVersion>=6?6:"module"===e.sourceType?"5module":5]);var s="";if(!0!==e.allowReserved){for(var a=e.ecmaVersion;!(s=t[a]);a--);"module"===e.sourceType&&(s+=" await")}this.reservedWords=$(s);var o=(s?s+" ":"")+t.strict;this.reservedWordsStrict=$(o),this.reservedWordsStrictBind=$(o+" "+t.strictBind),this.input=String(n),this.containsEsc=!1,i?(this.pos=i,this.lineStart=this.input.lastIndexOf("\n",i-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(v).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=T.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports={},0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(1),this.regexpState=null},z={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0}};O.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)},z.inFunction.get=function(){return(2&this.currentVarScope().flags)>0},z.inGenerator.get=function(){return(8&this.currentVarScope().flags)>0},z.inAsync.get=function(){return(4&this.currentVarScope().flags)>0},z.allowSuper.get=function(){return(64&this.currentThisScope().flags)>0},z.allowDirectSuper.get=function(){return(128&this.currentThisScope().flags)>0},z.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())},O.prototype.inNonArrowFunction=function(){return(2&this.currentThisScope().flags)>0},O.extend=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var n=this,r=0;r-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var n=t?e.parenthesizedAssign:e.parenthesizedBind;n>-1&&this.raiseRecoverable(n,"Parenthesized pattern")}},P.checkExpressionErrors=function(e,t){if(!e)return!1;var n=e.shorthandAssign,r=e.doubleProto;if(!t)return n>=0||r>=0;n>=0&&this.raise(n,"Shorthand property assignments are valid only in destructuring patterns"),r>=0&&this.raiseRecoverable(r,"Redefinition of __proto__ property")},P.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos=6&&this.unexpected(),this.parseFunctionStatement(s,!1,!e);case T._class:return e&&this.unexpected(),this.parseClass(s,!0);case T._if:return this.parseIfStatement(s);case T._return:return this.parseReturnStatement(s);case T._switch:return this.parseSwitchStatement(s);case T._throw:return this.parseThrowStatement(s);case T._try:return this.parseTryStatement(s);case T._const:case T._var:return r=r||this.value,e&&"var"!==r&&this.unexpected(),this.parseVarStatement(s,r);case T._while:return this.parseWhileStatement(s);case T._with:return this.parseWithStatement(s);case T.braceL:return this.parseBlock(!0,s);case T.semi:return this.parseEmptyStatement(s);case T._export:case T._import:if(this.options.ecmaVersion>10&&i===T._import){E.lastIndex=this.pos;var a=E.exec(this.input),o=this.pos+a[0].length;if(40===this.input.charCodeAt(o))return this.parseExpressionStatement(s,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),i===T._import?this.parseImport(s):this.parseExport(s,n);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(s,!0,!e);var u=this.value,l=this.parseExpression();return i===T.name&&"Identifier"===l.type&&this.eat(T.colon)?this.parseLabeledStatement(s,u,l,e):this.parseExpressionStatement(s,l)}},U.parseBreakContinueStatement=function(e,t){var n="break"===t;this.next(),this.eat(T.semi)||this.insertSemicolon()?e.label=null:this.type!==T.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var r=0;r=6?this.eat(T.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},U.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&(this.inAsync||!this.inFunction&&this.options.allowAwaitOutsideFunction)&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(B),this.enterScope(0),this.expect(T.parenL),this.type===T.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var n=this.isLet();if(this.type===T._var||this.type===T._const||n){var r=this.startNode(),i=n?"let":this.value;return this.next(),this.parseVar(r,!0,i),this.finishNode(r,"VariableDeclaration"),(this.type===T._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&1===r.declarations.length?(this.options.ecmaVersion>=9&&(this.type===T._in?t>-1&&this.unexpected(t):e.await=t>-1),this.parseForIn(e,r)):(t>-1&&this.unexpected(t),this.parseFor(e,r))}var s=new G,a=this.parseExpression(!0,s);return this.type===T._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.options.ecmaVersion>=9&&(this.type===T._in?t>-1&&this.unexpected(t):e.await=t>-1),this.toAssignable(a,!1,s),this.checkLVal(a),this.parseForIn(e,a)):(this.checkExpressionErrors(s,!0),t>-1&&this.unexpected(t),this.parseFor(e,a))},U.parseFunctionStatement=function(e,t,n){return this.next(),this.parseFunction(e,H|(n?0:X),!1,t)},U.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(T._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")},U.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(T.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},U.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(T.braceL),this.labels.push(W),this.enterScope(0);for(var n=!1;this.type!==T.braceR;)if(this.type===T._case||this.type===T._default){var r=this.type===T._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),r?t.test=this.parseExpression():(n&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),n=!0,t.test=null),this.expect(T.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},U.parseThrowStatement=function(e){return this.next(),v.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var j=[];U.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===T._catch){var t=this.startNode();if(this.next(),this.eat(T.parenL)){t.param=this.parseBindingAtom();var n="Identifier"===t.param.type;this.enterScope(n?32:0),this.checkLVal(t.param,n?4:2),this.expect(T.parenR)}else this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0);t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(T._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},U.parseVarStatement=function(e,t){return this.next(),this.parseVar(e,!1,t),this.semicolon(),this.finishNode(e,"VariableDeclaration")},U.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(B),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")},U.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")},U.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},U.parseLabeledStatement=function(e,t,n,r){for(var i=0,s=this.labels;i=0;o--){var u=this.labels[o];if(u.statementStart!==e.start)break;u.statementStart=this.start,u.kind=a}return this.labels.push({name:t,kind:a,statementStart:this.start}),e.body=this.parseStatement(r?-1===r.indexOf("label")?r+"label":r:"label"),this.labels.pop(),e.label=n,this.finishNode(e,"LabeledStatement")},U.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},U.parseBlock=function(e,t){for(void 0===e&&(e=!0),void 0===t&&(t=this.startNode()),t.body=[],this.expect(T.braceL),e&&this.enterScope(0);!this.eat(T.braceR);){var n=this.parseStatement(null);t.body.push(n)}return e&&this.exitScope(),this.finishNode(t,"BlockStatement")},U.parseFor=function(e,t){return e.init=t,this.expect(T.semi),e.test=this.type===T.semi?null:this.parseExpression(),this.expect(T.semi),e.update=this.type===T.parenR?null:this.parseExpression(),this.expect(T.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")},U.parseForIn=function(e,t){var n=this.type===T._in;return this.next(),"VariableDeclaration"===t.type&&null!=t.declarations[0].init&&(!n||this.options.ecmaVersion<8||this.strict||"var"!==t.kind||"Identifier"!==t.declarations[0].id.type)?this.raise(t.start,(n?"for-in":"for-of")+" loop variable declaration may not have an initializer"):"AssignmentPattern"===t.type&&this.raise(t.start,"Invalid left-hand side in for-loop"),e.left=t,e.right=n?this.parseExpression():this.parseMaybeAssign(),this.expect(T.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,n?"ForInStatement":"ForOfStatement")},U.parseVar=function(e,t,n){for(e.declarations=[],e.kind=n;;){var r=this.startNode();if(this.parseVarId(r,n),this.eat(T.eq)?r.init=this.parseMaybeAssign(t):"const"!==n||this.type===T._in||this.options.ecmaVersion>=6&&this.isContextual("of")?"Identifier"===r.id.type||t&&(this.type===T._in||this.isContextual("of"))?r.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),e.declarations.push(this.finishNode(r,"VariableDeclarator")),!this.eat(T.comma))break}return e},U.parseVarId=function(e,t){e.id=this.parseBindingAtom(),this.checkLVal(e.id,"var"===t?1:2,!1)};var H=1,X=2;U.parseFunction=function(e,t,n,r){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!r)&&(this.type===T.star&&t&X&&this.unexpected(),e.generator=this.eat(T.star)),this.options.ecmaVersion>=8&&(e.async=!!r),t&H&&(e.id=4&t&&this.type!==T.name?null:this.parseIdent(),!e.id||t&X||this.checkLVal(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?1:2:3));var i=this.yieldPos,s=this.awaitPos,a=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(M(e.async,e.generator)),t&H||(e.id=this.type===T.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,n,!1),this.yieldPos=i,this.awaitPos=s,this.awaitIdentPos=a,this.finishNode(e,t&H?"FunctionDeclaration":"FunctionExpression")},U.parseFunctionParams=function(e){this.expect(T.parenL),e.params=this.parseBindingList(T.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},U.parseClass=function(e,t){this.next();var n=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var r=this.startNode(),i=!1;for(r.body=[],this.expect(T.braceL);!this.eat(T.braceR);){var s=this.parseClassElement(null!==e.superClass);s&&(r.body.push(s),"MethodDefinition"===s.type&&"constructor"===s.kind&&(i&&this.raise(s.start,"Duplicate constructor in the same class"),i=!0))}return e.body=this.finishNode(r,"ClassBody"),this.strict=n,this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},U.parseClassElement=function(e){var t=this;if(this.eat(T.semi))return null;var n=this.startNode(),r=function(e,r){void 0===r&&(r=!1);var i=t.start,s=t.startLoc;return!!t.eatContextual(e)&&(!(t.type===T.parenL||r&&t.canInsertSemicolon())||(n.key&&t.unexpected(),n.computed=!1,n.key=t.startNodeAt(i,s),n.key.name=e,t.finishNode(n.key,"Identifier"),!1))};n.kind="method",n.static=r("static");var i=this.eat(T.star),s=!1;i||(this.options.ecmaVersion>=8&&r("async",!0)?(s=!0,i=this.options.ecmaVersion>=9&&this.eat(T.star)):r("get")?n.kind="get":r("set")&&(n.kind="set")),n.key||this.parsePropertyName(n);var a=n.key,o=!1;return n.computed||n.static||!("Identifier"===a.type&&"constructor"===a.name||"Literal"===a.type&&"constructor"===a.value)?n.static&&"Identifier"===a.type&&"prototype"===a.name&&this.raise(a.start,"Classes may not have a static property named prototype"):("method"!==n.kind&&this.raise(a.start,"Constructor can't have get/set modifier"),i&&this.raise(a.start,"Constructor can't be a generator"),s&&this.raise(a.start,"Constructor can't be an async method"),n.kind="constructor",o=e),this.parseClassMethod(n,i,s,o),"get"===n.kind&&0!==n.value.params.length&&this.raiseRecoverable(n.value.start,"getter should have no params"),"set"===n.kind&&1!==n.value.params.length&&this.raiseRecoverable(n.value.start,"setter should have exactly one param"),"set"===n.kind&&"RestElement"===n.value.params[0].type&&this.raiseRecoverable(n.value.params[0].start,"Setter cannot use rest params"),n},U.parseClassMethod=function(e,t,n,r){return e.value=this.parseMethod(t,n,r),this.finishNode(e,"MethodDefinition")},U.parseClassId=function(e,t){this.type===T.name?(e.id=this.parseIdent(),t&&this.checkLVal(e.id,2,!1)):(!0===t&&this.unexpected(),e.id=null)},U.parseClassSuper=function(e){e.superClass=this.eat(T._extends)?this.parseExprSubscripts():null},U.parseExport=function(e,t){if(this.next(),this.eat(T.star))return this.expectContextual("from"),this.type!==T.string&&this.unexpected(),e.source=this.parseExprAtom(),this.semicolon(),this.finishNode(e,"ExportAllDeclaration");if(this.eat(T._default)){var n;if(this.checkExport(t,"default",this.lastTokStart),this.type===T._function||(n=this.isAsyncFunction())){var r=this.startNode();this.next(),n&&this.next(),e.declaration=this.parseFunction(r,4|H,!1,n)}else if(this.type===T._class){var i=this.startNode();e.declaration=this.parseClass(i,"nullableID")}else e.declaration=this.parseMaybeAssign(),this.semicolon();return this.finishNode(e,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement())e.declaration=this.parseStatement(null),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id.name,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==T.string&&this.unexpected(),e.source=this.parseExprAtom();else{for(var s=0,a=e.specifiers;s=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",n&&this.checkPatternErrors(n,!0);for(var r=0,i=e.properties;r=8&&!s&&"async"===a.name&&!this.canInsertSemicolon()&&this.eat(T._function))return this.parseFunction(this.startNodeAt(r,i),0,!1,!0);if(n&&!this.canInsertSemicolon()){if(this.eat(T.arrow))return this.parseArrowExpression(this.startNodeAt(r,i),[a],!1);if(this.options.ecmaVersion>=8&&"async"===a.name&&this.type===T.name&&!s)return a=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(T.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(r,i),[a],!0)}return a;case T.regexp:var o=this.value;return(t=this.parseLiteral(o.value)).regex={pattern:o.pattern,flags:o.flags},t;case T.num:case T.string:return this.parseLiteral(this.value);case T._null:case T._true:case T._false:return(t=this.startNode()).value=this.type===T._null?null:this.type===T._true,t.raw=this.type.keyword,this.next(),this.finishNode(t,"Literal");case T.parenL:var u=this.start,l=this.parseParenAndDistinguishExpression(n);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(l)&&(e.parenthesizedAssign=u),e.parenthesizedBind<0&&(e.parenthesizedBind=u)),l;case T.bracketL:return t=this.startNode(),this.next(),t.elements=this.parseExprList(T.bracketR,!0,!0,e),this.finishNode(t,"ArrayExpression");case T.braceL:return this.parseObj(!1,e);case T._function:return t=this.startNode(),this.next(),this.parseFunction(t,0);case T._class:return this.parseClass(this.startNode(),!1);case T._new:return this.parseNew();case T.backQuote:return this.parseTemplate();case T._import:return this.options.ecmaVersion>=11?this.parseExprImport():this.unexpected();default:this.unexpected()}},Y.parseExprImport=function(){var e=this.startNode();if(this.next(),this.type===T.parenL)return this.parseDynamicImport(e);this.unexpected()},Y.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),!this.eat(T.parenR)){var t=this.start;this.eat(T.comma)&&this.eat(T.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")},Y.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),110===t.raw.charCodeAt(t.raw.length-1)&&(t.bigint=t.raw.slice(0,-1)),this.next(),this.finishNode(t,"Literal")},Y.parseParenExpression=function(){this.expect(T.parenL);var e=this.parseExpression();return this.expect(T.parenR),e},Y.parseParenAndDistinguishExpression=function(e){var t,n=this.start,r=this.startLoc,i=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var s,a=this.start,o=this.startLoc,u=[],l=!0,h=!1,c=new G,p=this.yieldPos,d=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==T.parenR;){if(l?l=!1:this.expect(T.comma),i&&this.afterTrailingComma(T.parenR,!0)){h=!0;break}if(this.type===T.ellipsis){s=this.start,u.push(this.parseParenItem(this.parseRestBinding())),this.type===T.comma&&this.raise(this.start,"Comma is not permitted after the rest element");break}u.push(this.parseMaybeAssign(!1,c,this.parseParenItem))}var m=this.start,f=this.startLoc;if(this.expect(T.parenR),e&&!this.canInsertSemicolon()&&this.eat(T.arrow))return this.checkPatternErrors(c,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=p,this.awaitPos=d,this.parseParenArrowList(n,r,u);u.length&&!h||this.unexpected(this.lastTokStart),s&&this.unexpected(s),this.checkExpressionErrors(c,!0),this.yieldPos=p||this.yieldPos,this.awaitPos=d||this.awaitPos,u.length>1?((t=this.startNodeAt(a,o)).expressions=u,this.finishNodeAt(t,"SequenceExpression",m,f)):t=u[0]}else t=this.parseParenExpression();if(this.options.preserveParens){var g=this.startNodeAt(n,r);return g.expression=t,this.finishNode(g,"ParenthesizedExpression")}return t},Y.parseParenItem=function(e){return e},Y.parseParenArrowList=function(e,t,n){return this.parseArrowExpression(this.startNodeAt(e,t),n)};var Z=[];Y.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode(),t=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(T.dot)){e.meta=t;var n=this.containsEsc;return e.property=this.parseIdent(!0),("target"!==e.property.name||n)&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is new.target"),this.inNonArrowFunction()||this.raiseRecoverable(e.start,"new.target can only be used in functions"),this.finishNode(e,"MetaProperty")}var r=this.start,i=this.startLoc,s=this.type===T._import;return e.callee=this.parseSubscripts(this.parseExprAtom(),r,i,!0),s&&"ImportExpression"===e.callee.type&&this.raise(r,"Cannot use new with import()"),this.eat(T.parenL)?e.arguments=this.parseExprList(T.parenR,this.options.ecmaVersion>=8,!1):e.arguments=Z,this.finishNode(e,"NewExpression")},Y.parseTemplateElement=function(e){var t=e.isTagged,n=this.startNode();return this.type===T.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),n.value={raw:this.value,cooked:null}):n.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),n.tail=this.type===T.backQuote,this.finishNode(n,"TemplateElement")},Y.parseTemplate=function(e){void 0===e&&(e={});var t=e.isTagged;void 0===t&&(t=!1);var n=this.startNode();this.next(),n.expressions=[];var r=this.parseTemplateElement({isTagged:t});for(n.quasis=[r];!r.tail;)this.type===T.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(T.dollarBraceL),n.expressions.push(this.parseExpression()),this.expect(T.braceR),n.quasis.push(r=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(n,"TemplateLiteral")},Y.isAsyncProp=function(e){return!e.computed&&"Identifier"===e.key.type&&"async"===e.key.name&&(this.type===T.name||this.type===T.num||this.type===T.string||this.type===T.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===T.star)&&!v.test(this.input.slice(this.lastTokEnd,this.start))},Y.parseObj=function(e,t){var n=this.startNode(),r=!0,i={};for(n.properties=[],this.next();!this.eat(T.braceR);){if(r)r=!1;else if(this.expect(T.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(T.braceR))break;var s=this.parseProperty(e,t);e||this.checkPropClash(s,i,t),n.properties.push(s)}return this.finishNode(n,e?"ObjectPattern":"ObjectExpression")},Y.parseProperty=function(e,t){var n,r,i,s,a=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(T.ellipsis))return e?(a.argument=this.parseIdent(!1),this.type===T.comma&&this.raise(this.start,"Comma is not permitted after the rest element"),this.finishNode(a,"RestElement")):(this.type===T.parenL&&t&&(t.parenthesizedAssign<0&&(t.parenthesizedAssign=this.start),t.parenthesizedBind<0&&(t.parenthesizedBind=this.start)),a.argument=this.parseMaybeAssign(!1,t),this.type===T.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(a,"SpreadElement"));this.options.ecmaVersion>=6&&(a.method=!1,a.shorthand=!1,(e||t)&&(i=this.start,s=this.startLoc),e||(n=this.eat(T.star)));var o=this.containsEsc;return this.parsePropertyName(a),!e&&!o&&this.options.ecmaVersion>=8&&!n&&this.isAsyncProp(a)?(r=!0,n=this.options.ecmaVersion>=9&&this.eat(T.star),this.parsePropertyName(a,t)):r=!1,this.parsePropertyValue(a,e,n,r,i,s,t,o),this.finishNode(a,"Property")},Y.parsePropertyValue=function(e,t,n,r,i,s,a,o){if((n||r)&&this.type===T.colon&&this.unexpected(),this.eat(T.colon))e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,a),e.kind="init";else if(this.options.ecmaVersion>=6&&this.type===T.parenL)t&&this.unexpected(),e.kind="init",e.method=!0,e.value=this.parseMethod(n,r);else if(t||o||!(this.options.ecmaVersion>=5)||e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||this.type===T.comma||this.type===T.braceR)this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((n||r)&&this.unexpected(),this.checkUnreserved(e.key),"await"!==e.key.name||this.awaitIdentPos||(this.awaitIdentPos=i),e.kind="init",t?e.value=this.parseMaybeDefault(i,s,e.key):this.type===T.eq&&a?(a.shorthandAssign<0&&(a.shorthandAssign=this.start),e.value=this.parseMaybeDefault(i,s,e.key)):e.value=e.key,e.shorthand=!0):this.unexpected();else{(n||r)&&this.unexpected(),e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);var u="get"===e.kind?0:1;if(e.value.params.length!==u){var l=e.value.start;"get"===e.kind?this.raiseRecoverable(l,"getter should have no params"):this.raiseRecoverable(l,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")}},Y.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(T.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(T.bracketR),e.key;e.computed=!1}return e.key=this.type===T.num||this.type===T.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved)},Y.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},Y.parseMethod=function(e,t,n){var r=this.startNode(),i=this.yieldPos,s=this.awaitPos,a=this.awaitIdentPos;return this.initFunction(r),this.options.ecmaVersion>=6&&(r.generator=e),this.options.ecmaVersion>=8&&(r.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(64|M(t,r.generator)|(n?128:0)),this.expect(T.parenL),r.params=this.parseBindingList(T.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(r,!1,!0),this.yieldPos=i,this.awaitPos=s,this.awaitIdentPos=a,this.finishNode(r,"FunctionExpression")},Y.parseArrowExpression=function(e,t,n){var r=this.yieldPos,i=this.awaitPos,s=this.awaitIdentPos;return this.enterScope(16|M(n,!1)),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!n),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1),this.yieldPos=r,this.awaitPos=i,this.awaitIdentPos=s,this.finishNode(e,"ArrowFunctionExpression")},Y.parseFunctionBody=function(e,t,n){var r=t&&this.type!==T.braceL,i=this.strict,s=!1;if(r)e.body=this.parseMaybeAssign(),e.expression=!0,this.checkParams(e,!1);else{var a=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);i&&!a||(s=this.strictDirective(this.end))&&a&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var o=this.labels;this.labels=[],s&&(this.strict=!0),this.checkParams(e,!i&&!s&&!t&&!n&&this.isSimpleParamList(e.params)),e.body=this.parseBlock(!1),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=o}this.exitScope(),this.strict&&e.id&&this.checkLVal(e.id,5),this.strict=i},Y.isSimpleParamList=function(e){for(var t=0,n=e;t-1||i.functions.indexOf(e)>-1||i.var.indexOf(e)>-1,i.lexical.push(e),this.inModule&&1&i.flags&&delete this.undefinedExports[e]}else if(4===t){this.currentScope().lexical.push(e)}else if(3===t){var s=this.currentScope();r=this.treatFunctionsAsVar?s.lexical.indexOf(e)>-1:s.lexical.indexOf(e)>-1||s.var.indexOf(e)>-1,s.functions.push(e)}else for(var a=this.scopeStack.length-1;a>=0;--a){var o=this.scopeStack[a];if(o.lexical.indexOf(e)>-1&&!(32&o.flags&&o.lexical[0]===e)||!this.treatFunctionsAsVarInScope(o)&&o.functions.indexOf(e)>-1){r=!0;break}if(o.var.push(e),this.inModule&&1&o.flags&&delete this.undefinedExports[e],3&o.flags)break}r&&this.raiseRecoverable(n,"Identifier '"+e+"' has already been declared")},Q.checkLocalExport=function(e){-1===this.scopeStack[0].lexical.indexOf(e.name)&&-1===this.scopeStack[0].var.indexOf(e.name)&&(this.undefinedExports[e.name]=e)},Q.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]},Q.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(3&t.flags)return t}},Q.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(3&t.flags&&!(16&t.flags))return t}};var te=function(e,t,n){this.type="",this.start=t,this.end=0,e.options.locations&&(this.loc=new R(e,n)),e.options.directSourceFile&&(this.sourceFile=e.options.directSourceFile),e.options.ranges&&(this.range=[t,0])},ne=O.prototype;function re(e,t,n,r){return e.type=t,e.end=n,this.options.locations&&(e.loc.end=r),this.options.ranges&&(e.range[1]=n),e}ne.startNode=function(){return new te(this,this.start,this.startLoc)},ne.startNodeAt=function(e,t){return new te(this,e,t)},ne.finishNode=function(e,t){return re.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)},ne.finishNodeAt=function(e,t,n,r){return re.call(this,e,t,n,r)};var ie=function(e,t,n,r,i){this.token=e,this.isExpr=!!t,this.preserveSpace=!!n,this.override=r,this.generator=!!i},se={b_stat:new ie("{",!1),b_expr:new ie("{",!0),b_tmpl:new ie("${",!1),p_stat:new ie("(",!1),p_expr:new ie("(",!0),q_tmpl:new ie("`",!0,!0,(function(e){return e.tryReadTemplateToken()})),f_stat:new ie("function",!1),f_expr:new ie("function",!0),f_expr_gen:new ie("function",!0,!1,null,!0),f_gen:new ie("function",!1,!1,null,!0)},ae=O.prototype;ae.initialContext=function(){return[se.b_stat]},ae.braceIsBlock=function(e){var t=this.curContext();return t===se.f_expr||t===se.f_stat||(e!==T.colon||t!==se.b_stat&&t!==se.b_expr?e===T._return||e===T.name&&this.exprAllowed?v.test(this.input.slice(this.lastTokEnd,this.start)):e===T._else||e===T.semi||e===T.eof||e===T.parenR||e===T.arrow||(e===T.braceL?t===se.b_stat:e!==T._var&&e!==T._const&&e!==T.name&&!this.exprAllowed):!t.isExpr)},ae.inGeneratorContext=function(){for(var e=this.context.length-1;e>=1;e--){var t=this.context[e];if("function"===t.token)return t.generator}return!1},ae.updateContext=function(e){var t,n=this.type;n.keyword&&e===T.dot?this.exprAllowed=!1:(t=n.updateContext)?t.call(this,e):this.exprAllowed=n.beforeExpr},T.parenR.updateContext=T.braceR.updateContext=function(){if(1!==this.context.length){var e=this.context.pop();e===se.b_stat&&"function"===this.curContext().token&&(e=this.context.pop()),this.exprAllowed=!e.isExpr}else this.exprAllowed=!0},T.braceL.updateContext=function(e){this.context.push(this.braceIsBlock(e)?se.b_stat:se.b_expr),this.exprAllowed=!0},T.dollarBraceL.updateContext=function(){this.context.push(se.b_tmpl),this.exprAllowed=!0},T.parenL.updateContext=function(e){var t=e===T._if||e===T._for||e===T._with||e===T._while;this.context.push(t?se.p_stat:se.p_expr),this.exprAllowed=!0},T.incDec.updateContext=function(){},T._function.updateContext=T._class.updateContext=function(e){!e.beforeExpr||e===T.semi||e===T._else||e===T._return&&v.test(this.input.slice(this.lastTokEnd,this.start))||(e===T.colon||e===T.braceL)&&this.curContext()===se.b_stat?this.context.push(se.f_stat):this.context.push(se.f_expr),this.exprAllowed=!1},T.backQuote.updateContext=function(){this.curContext()===se.q_tmpl?this.context.pop():this.context.push(se.q_tmpl),this.exprAllowed=!1},T.star.updateContext=function(e){if(e===T._function){var t=this.context.length-1;this.context[t]===se.f_expr?this.context[t]=se.f_expr_gen:this.context[t]=se.f_gen}this.exprAllowed=!0},T.name.updateContext=function(e){var t=!1;this.options.ecmaVersion>=6&&e!==T.dot&&("of"===this.value&&!this.exprAllowed||"yield"===this.value&&this.inGeneratorContext())&&(t=!0),this.exprAllowed=t};var oe="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",ue=oe+" Extended_Pictographic",le={9:oe,10:ue,11:"ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS Extended_Pictographic"},he="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",ce="Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",pe=ce+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",de={9:ce,10:pe,11:"Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"},me={};function fe(e){var t=me[e]={binary:$(le[e]+" "+he),nonBinary:{General_Category:$(he),Script:$(de[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}fe(9),fe(10),fe(11);var ge=O.prototype,xe=function(e){this.parser=e,this.validFlags="gim"+(e.options.ecmaVersion>=6?"uy":"")+(e.options.ecmaVersion>=9?"s":""),this.unicodeProperties=me[e.options.ecmaVersion>=11?11:e.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=[],this.backReferenceNames=[]};function ye(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode(55296+(e>>10),56320+(1023&e)))}function be(e){return 36===e||e>=40&&e<=43||46===e||63===e||e>=91&&e<=94||e>=123&&e<=125}function Te(e){return e>=65&&e<=90||e>=97&&e<=122}function ve(e){return Te(e)||95===e}function Se(e){return ve(e)||Ae(e)}function Ae(e){return e>=48&&e<=57}function _e(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function Ee(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e-48}function we(e){return e>=48&&e<=55}xe.prototype.reset=function(e,t,n){var r=-1!==n.indexOf("u");this.start=0|e,this.source=t+"",this.flags=n,this.switchU=r&&this.parser.options.ecmaVersion>=6,this.switchN=r&&this.parser.options.ecmaVersion>=9},xe.prototype.raise=function(e){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+e)},xe.prototype.at=function(e){var t=this.source,n=t.length;if(e>=n)return-1;var r=t.charCodeAt(e);if(!this.switchU||r<=55295||r>=57344||e+1>=n)return r;var i=t.charCodeAt(e+1);return i>=56320&&i<=57343?(r<<10)+i-56613888:r},xe.prototype.nextIndex=function(e){var t=this.source,n=t.length;if(e>=n)return n;var r,i=t.charCodeAt(e);return!this.switchU||i<=55295||i>=57344||e+1>=n||(r=t.charCodeAt(e+1))<56320||r>57343?e+1:e+2},xe.prototype.current=function(){return this.at(this.pos)},xe.prototype.lookahead=function(){return this.at(this.nextIndex(this.pos))},xe.prototype.advance=function(){this.pos=this.nextIndex(this.pos)},xe.prototype.eat=function(e){return this.current()===e&&(this.advance(),!0)},ge.validateRegExpFlags=function(e){for(var t=e.validFlags,n=e.flags,r=0;r-1&&this.raise(e.start,"Duplicate regular expression flag")}},ge.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&e.groupNames.length>0&&(e.switchN=!0,this.regexp_pattern(e))},ge.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames.length=0,e.backReferenceNames.length=0,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,n=e.backReferenceNames;t=9&&(n=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!n,!0}return e.pos=t,!1},ge.regexp_eatQuantifier=function(e,t){return void 0===t&&(t=!1),!!this.regexp_eatQuantifierPrefix(e,t)&&(e.eat(63),!0)},ge.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)},ge.regexp_eatBracedQuantifier=function(e,t){var n=e.pos;if(e.eat(123)){var r=0,i=-1;if(this.regexp_eatDecimalDigits(e)&&(r=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(i=e.lastIntValue),e.eat(125)))return-1!==i&&i=9?this.regexp_groupSpecifier(e):63===e.current()&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1},ge.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)},ge.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1},ge.regexp_eatSyntaxCharacter=function(e){var t=e.current();return!!be(t)&&(e.lastIntValue=t,e.advance(),!0)},ge.regexp_eatPatternCharacters=function(e){for(var t=e.pos,n=0;-1!==(n=e.current())&&!be(n);)e.advance();return e.pos!==t},ge.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return!(-1===t||36===t||t>=40&&t<=43||46===t||63===t||91===t||94===t||124===t)&&(e.advance(),!0)},ge.regexp_groupSpecifier=function(e){if(e.eat(63)){if(this.regexp_eatGroupName(e))return-1!==e.groupNames.indexOf(e.lastStringValue)&&e.raise("Duplicate capture group name"),void e.groupNames.push(e.lastStringValue);e.raise("Invalid group")}},ge.regexp_eatGroupName=function(e){if(e.lastStringValue="",e.eat(60)){if(this.regexp_eatRegExpIdentifierName(e)&&e.eat(62))return!0;e.raise("Invalid capture group name")}return!1},ge.regexp_eatRegExpIdentifierName=function(e){if(e.lastStringValue="",this.regexp_eatRegExpIdentifierStart(e)){for(e.lastStringValue+=ye(e.lastIntValue);this.regexp_eatRegExpIdentifierPart(e);)e.lastStringValue+=ye(e.lastIntValue);return!0}return!1},ge.regexp_eatRegExpIdentifierStart=function(e){var t=e.pos,n=e.current();return e.advance(),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e)&&(n=e.lastIntValue),function(e){return p(e,!0)||36===e||95===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},ge.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,n=e.current();return e.advance(),92===n&&this.regexp_eatRegExpUnicodeEscapeSequence(e)&&(n=e.lastIntValue),function(e){return d(e,!0)||36===e||95===e||8204===e||8205===e}(n)?(e.lastIntValue=n,!0):(e.pos=t,!1)},ge.regexp_eatAtomEscape=function(e){return!!(this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e))||(e.switchU&&(99===e.current()&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)},ge.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var n=e.lastIntValue;if(e.switchU)return n>e.maxBackReference&&(e.maxBackReference=n),!0;if(n<=e.numCapturingParens)return!0;e.pos=t}return!1},ge.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1},ge.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)},ge.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1},ge.regexp_eatZero=function(e){return 48===e.current()&&!Ae(e.lookahead())&&(e.lastIntValue=0,e.advance(),!0)},ge.regexp_eatControlEscape=function(e){var t=e.current();return 116===t?(e.lastIntValue=9,e.advance(),!0):110===t?(e.lastIntValue=10,e.advance(),!0):118===t?(e.lastIntValue=11,e.advance(),!0):102===t?(e.lastIntValue=12,e.advance(),!0):114===t&&(e.lastIntValue=13,e.advance(),!0)},ge.regexp_eatControlLetter=function(e){var t=e.current();return!!Te(t)&&(e.lastIntValue=t%32,e.advance(),!0)},ge.regexp_eatRegExpUnicodeEscapeSequence=function(e){var t,n=e.pos;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var r=e.lastIntValue;if(e.switchU&&r>=55296&&r<=56319){var i=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var s=e.lastIntValue;if(s>=56320&&s<=57343)return e.lastIntValue=1024*(r-55296)+(s-56320)+65536,!0}e.pos=i,e.lastIntValue=r}return!0}if(e.switchU&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&((t=e.lastIntValue)>=0&&t<=1114111))return!0;e.switchU&&e.raise("Invalid unicode escape"),e.pos=n}return!1},ge.regexp_eatIdentityEscape=function(e){if(e.switchU)return!!this.regexp_eatSyntaxCharacter(e)||!!e.eat(47)&&(e.lastIntValue=47,!0);var t=e.current();return!(99===t||e.switchN&&107===t)&&(e.lastIntValue=t,e.advance(),!0)},ge.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do{e.lastIntValue=10*e.lastIntValue+(t-48),e.advance()}while((t=e.current())>=48&&t<=57);return!0}return!1},ge.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(function(e){return 100===e||68===e||115===e||83===e||119===e||87===e}(t))return e.lastIntValue=-1,e.advance(),!0;if(e.switchU&&this.options.ecmaVersion>=9&&(80===t||112===t)){if(e.lastIntValue=-1,e.advance(),e.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(e)&&e.eat(125))return!0;e.raise("Invalid property name")}return!1},ge.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var n=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var r=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,n,r),!0}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var i=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,i),!0}return!1},ge.regexp_validateUnicodePropertyNameAndValue=function(e,t,n){D(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(n)||e.raise("Invalid property value")},ge.regexp_validateUnicodePropertyNameOrValue=function(e,t){e.unicodeProperties.binary.test(t)||e.raise("Invalid property name")},ge.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";ve(t=e.current());)e.lastStringValue+=ye(t),e.advance();return""!==e.lastStringValue},ge.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";Se(t=e.current());)e.lastStringValue+=ye(t),e.advance();return""!==e.lastStringValue},ge.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)},ge.regexp_eatCharacterClass=function(e){if(e.eat(91)){if(e.eat(94),this.regexp_classRanges(e),e.eat(93))return!0;e.raise("Unterminated character class")}return!1},ge.regexp_classRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var n=e.lastIntValue;!e.switchU||-1!==t&&-1!==n||e.raise("Invalid character class"),-1!==t&&-1!==n&&t>n&&e.raise("Range out of order in character class")}}},ge.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var n=e.current();(99===n||we(n))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var r=e.current();return 93!==r&&(e.lastIntValue=r,e.advance(),!0)},ge.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)},ge.regexp_eatClassControlLetter=function(e){var t=e.current();return!(!Ae(t)&&95!==t)&&(e.lastIntValue=t%32,e.advance(),!0)},ge.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1},ge.regexp_eatDecimalDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;Ae(n=e.current());)e.lastIntValue=10*e.lastIntValue+(n-48),e.advance();return e.pos!==t},ge.regexp_eatHexDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;_e(n=e.current());)e.lastIntValue=16*e.lastIntValue+Ee(n),e.advance();return e.pos!==t},ge.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var n=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=64*t+8*n+e.lastIntValue:e.lastIntValue=8*t+n}else e.lastIntValue=t;return!0}return!1},ge.regexp_eatOctalDigit=function(e){var t=e.current();return we(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)},ge.regexp_eatFixedHexDigits=function(e,t){var n=e.pos;e.lastIntValue=0;for(var r=0;r>10),56320+(1023&e)))}Ie.next=function(e){!e&&this.type.keyword&&this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword "+this.type.keyword),this.options.onToken&&this.options.onToken(new ke(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},Ie.getToken=function(){return this.next(),new ke(this)},"undefined"!=typeof Symbol&&(Ie[Symbol.iterator]=function(){var e=this;return{next:function(){var t=e.getToken();return{done:t.type===T.eof,value:t}}}}),Ie.curContext=function(){return this.context[this.context.length-1]},Ie.nextToken=function(){var e=this.curContext();return e&&e.preserveSpace||this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length?this.finishToken(T.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},Ie.readToken=function(e){return p(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},Ie.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);return e<=55295||e>=57344?e:(e<<10)+this.input.charCodeAt(this.pos+1)-56613888},Ie.skipBlockComment=function(){var e,t=this.options.onComment&&this.curPosition(),n=this.pos,r=this.input.indexOf("*/",this.pos+=2);if(-1===r&&this.raise(this.pos-2,"Unterminated comment"),this.pos=r+2,this.options.locations)for(S.lastIndex=n;(e=S.exec(this.input))&&e.index8&&e<14||e>=5760&&_.test(String.fromCharCode(e))))break e;++this.pos}}},Ie.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var n=this.type;this.type=e,this.value=t,this.updateContext(n)},Ie.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(T.ellipsis)):(++this.pos,this.finishToken(T.dot))},Ie.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(T.assign,2):this.finishOp(T.slash,1)},Ie.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),n=1,r=42===e?T.star:T.modulo;return this.options.ecmaVersion>=7&&42===e&&42===t&&(++n,r=T.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(T.assign,n+1):this.finishOp(r,n)},Ie.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?this.finishOp(124===e?T.logicalOR:T.logicalAND,2):61===t?this.finishOp(T.assign,2):this.finishOp(124===e?T.bitwiseOR:T.bitwiseAND,1)},Ie.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(T.assign,2):this.finishOp(T.bitwiseXOR,1)},Ie.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45!==t||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!v.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(T.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===t?this.finishOp(T.assign,2):this.finishOp(T.plusMin,1)},Ie.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),n=1;return t===e?(n=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+n)?this.finishOp(T.assign,n+1):this.finishOp(T.bitShift,n)):33!==t||60!==e||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===t&&(n=2),this.finishOp(T.relational,n)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},Ie.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(T.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(T.arrow)):this.finishOp(61===e?T.eq:T.prefix,1)},Ie.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(T.parenL);case 41:return++this.pos,this.finishToken(T.parenR);case 59:return++this.pos,this.finishToken(T.semi);case 44:return++this.pos,this.finishToken(T.comma);case 91:return++this.pos,this.finishToken(T.bracketL);case 93:return++this.pos,this.finishToken(T.bracketR);case 123:return++this.pos,this.finishToken(T.braceL);case 125:return++this.pos,this.finishToken(T.braceR);case 58:return++this.pos,this.finishToken(T.colon);case 63:return++this.pos,this.finishToken(T.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(T.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 126:return this.finishOp(T.prefix,1)}this.raise(this.pos,"Unexpected character '"+De(e)+"'")},Ie.finishOp=function(e,t){var n=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,n)},Ie.readRegexp=function(){for(var e,t,n=this.pos;;){this.pos>=this.input.length&&this.raise(n,"Unterminated regular expression");var r=this.input.charAt(this.pos);if(v.test(r)&&this.raise(n,"Unterminated regular expression"),e)e=!1;else{if("["===r)t=!0;else if("]"===r&&t)t=!1;else if("/"===r&&!t)break;e="\\"===r}++this.pos}var i=this.input.slice(n,this.pos);++this.pos;var s=this.pos,a=this.readWord1();this.containsEsc&&this.unexpected(s);var o=this.regexpState||(this.regexpState=new xe(this));o.reset(n,i,a),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var u=null;try{u=new RegExp(i,a)}catch(e){}return this.finishToken(T.regexp,{pattern:i,flags:a,value:u})},Ie.readInt=function(e,t){for(var n=this.pos,r=0,i=0,s=null==t?1/0:t;i=97?a-97+10:a>=65?a-65+10:a>=48&&a<=57?a-48:1/0)>=e)break;++this.pos,r=r*e+o}return this.pos===n||null!=t&&this.pos-n!==t?null:r},Ie.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var n=this.readInt(e);return null==n&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&110===this.input.charCodeAt(this.pos)?(n="undefined"!=typeof BigInt?BigInt(this.input.slice(t,this.pos)):null,++this.pos):p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(T.num,n)},Ie.readNumber=function(e){var t=this.pos;e||null!==this.readInt(10)||this.raise(t,"Invalid number");var n=this.pos-t>=2&&48===this.input.charCodeAt(t);n&&this.strict&&this.raise(t,"Invalid number");var r=this.input.charCodeAt(this.pos);if(!n&&!e&&this.options.ecmaVersion>=11&&110===r){var i=this.input.slice(t,this.pos),s="undefined"!=typeof BigInt?BigInt(i):null;return++this.pos,p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(T.num,s)}n&&/[89]/.test(this.input.slice(t,this.pos))&&(n=!1),46!==r||n||(++this.pos,this.readInt(10),r=this.input.charCodeAt(this.pos)),69!==r&&101!==r||n||(43!==(r=this.input.charCodeAt(++this.pos))&&45!==r||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number")),p(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var a=this.input.slice(t,this.pos),o=n?parseInt(a,8):parseFloat(a);return this.finishToken(T.num,o)},Ie.readCodePoint=function(){var e;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var t=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.invalidStringToken(t,"Code point out of bounds")}else e=this.readHexChar(4);return e},Ie.readString=function(e){for(var t="",n=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var r=this.input.charCodeAt(this.pos);if(r===e)break;92===r?(t+=this.input.slice(n,this.pos),t+=this.readEscapedChar(!1),n=this.pos):(A(r,this.options.ecmaVersion>=10)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(n,this.pos++),this.finishToken(T.string,t)};var Ce={};Ie.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e!==Ce)throw e;this.readInvalidTemplateToken()}this.inTemplateElement=!1},Ie.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw Ce;this.raise(e,t)},Ie.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var n=this.input.charCodeAt(this.pos);if(96===n||36===n&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==T.template&&this.type!==T.invalidTemplate?(e+=this.input.slice(t,this.pos),this.finishToken(T.template,e)):36===n?(this.pos+=2,this.finishToken(T.dollarBraceL)):(++this.pos,this.finishToken(T.backQuote));if(92===n)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(A(n)){switch(e+=this.input.slice(t,this.pos),++this.pos,n){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(n)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},Ie.readInvalidTemplateToken=function(){for(;this.pos=48&&t<=55){var r=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],i=parseInt(r,8);return i>255&&(r=r.slice(0,-1),i=parseInt(r,8)),this.pos+=r.length-1,t=this.input.charCodeAt(this.pos),"0"===r&&56!==t&&57!==t||!this.strict&&!e||this.invalidStringToken(this.pos-1-r.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(i)}return A(t)?"":String.fromCharCode(t)}},Ie.readHexChar=function(e){var t=this.pos,n=this.readInt(16,e);return null===n&&this.invalidStringToken(t,"Bad character escape sequence"),n},Ie.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,n=this.pos,r=this.options.ecmaVersion>=6;this.pos0;)l.pop()}function v(e,t){h[e]=t}function S(e){const t=f[e];return t?n+"."+t:e}function A(e){y=" ".repeat(e)}function _(e,t){const r=`${n}Variable${m.length}`;return l.push(`${y}const ${r} = ${t};`),m.push(e),r}function E(e,t){const r=`${n}Variable${m.length}`,i=`imageDatum${x}`;l.push(`${y}let ${i} = ["P3\\n# ${u}.ppm\\n", ${e}, ' ', ${t}, "\\n255\\n"].join("");`),l.push(`${y}for (let i = 0; i < ${i}.length; i += 4) {`),l.push(`${y} ${i} += ${r}[i] + ' ' + ${r}[i + 1] + ' ' + ${r}[i + 2] + ' ';`),l.push(`${y}}`),l.push(`${y}if (typeof require !== "undefined") {`),l.push(`${y} require('fs').writeFileSync('./${u}.ppm', ${i});`),l.push(`${y}}`),x++}function w(e){l.push(`${y}// ${e}`)}function k(){l.push(`${y}(() => {\n${y}const error = ${n}.getError();\n${y}if (error !== ${n}.NONE) {\n${y} const names = Object.getOwnPropertyNames(gl);\n${y} for (let i = 0; i < names.length; i++) {\n${y} const name = names[i];\n${y} if (${n}[name] === error) {\n${y} throw new Error('${n} threw ' + name);\n${y} }\n${y} }\n${y}}\n${y}})();`)}function I(e,t){return`${n}.${e}(${s(t,{contextName:n,contextVariables:m,getEntity:S,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})})`}function D(e){if(h)for(const t in h)if(h[t]===e)return t;return null}function C(e){const t=m.indexOf(e);return-1!==t?`${n}Variable${t}`:null}}function i(e,t){const n=new Proxy(e,{get:function(t,n){if("function"==typeof t[n])return function(){if("drawBuffersWEBGL"===n)return h.push(`${p}${i}.drawBuffersWEBGL([${s(arguments[0],{contextName:i,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0]);let t=e[n].apply(e,arguments);switch(typeof t){case"undefined":return void h.push(`${p}${f(n,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(a(t))?(h.push(`${p}const ${i}Variable${o.length} = ${f(n,arguments)};`),o.push(t=a(t))):(h.push(`${p}const ${i}Variable${o.length} = ${f(n,arguments)};`),o.push(t));break;default:null===t?h.push(`${f(n,arguments)};`):h.push(`${p}const ${i}Variable${o.length} = ${f(n,arguments)};`),o.push(t)}return t};return r[e[n]]=n,e[n]}}),r={},{contextName:i,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return n;function m(e){return r.hasOwnProperty(e)?`${i}.${r[e]}`:u(e)}function f(e,t){return`${i}.${e}(${s(t,{contextName:i,contextVariables:o,getEntity:m,addVariable:g,variables:c,onUnrecognizedArgumentLookup:d})})`}function g(e,t){const n=`${i}Variable${o.length}`;return o.push(e),h.push(`${p}const ${n} = ${t};`),n}}function s(e,t){const{variables:n,onUnrecognizedArgumentLookup:r}=t;return Array.from(e).map((e=>{const i=function(e){if(n)for(const t in n)if(n.hasOwnProperty(t)&&n[t]===e)return t;if(r)return r(e);return null}(e);return i||function(e,t){const{contextName:n,contextVariables:r,getEntity:i,addVariable:s,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=r.indexOf(e);if(o>-1)return`${n}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),n=/'/.test(e),r=/"/.test(e);return t?"`"+e+"`":n&&!r?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return i(e);case"Array":return s(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return s(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)})).join(", ")}function a(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:i}),"undefined"!=typeof window&&(r.glExtensionWiretap=i,window.glWiretap=r)},{}],4:[function(e,t,n){function r(e){const t=new Array(e.length);for(let n=0;n{e.output=h(t),e.graphical&&l(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&l(e),e.exec=function(){return new Promise(((t,n)=>{try{t(e.apply(e,arguments))}catch(e){n(e)}}))},e.getPixels=t=>{const{x:n,y:r}=e.output;return t?function(e,t,n){const r=n/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,n=["setWarnVarUsage","setArgumentTypes","setTactic","setOptimizeFloatMemory","setDebug","setLoopMaxIterations","setConstantTypes","setFunctions","setNativeFunctions","setInjectedNative","setPipeline","setPrecision","setOutputToTexture","setImmutable","setStrictIntegers","setDynamicOutput","setHardcodeConstants","setDynamicArguments","setUseLegacyEncoder","setWarnVarUsage","addSubKernel"];for(let r=0;r0&&t.push(", "),t.push("user_"),t.push(n)}t.push(") {\n")}for(let n=0;n0&&t.push(n.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const n=this.getDeclaration(e.left);if(n&&!n.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);return this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let n=0;n0&&t.push(",");const r=n[e],i=this.getDeclaration(r.id);i.valueType||(i.valueType=this.getType(r.init)),this.astGeneric(r,t)}return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:n,cases:r}=e;t.push("switch ("),this.astGeneric(n,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(r[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(r[e].consequent,t),r[e].consequent&&r[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:n,type:r,property:i,xProperty:s,yProperty:a,zProperty:o,name:u,origin:l}=this.getMemberExpressionDetails(e);switch(n){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":default:throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===l)return t.push(Math[u]),t;switch(i){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;case"fn()[][]":return this.astGeneric(e.object.object,t),t.push("["),this.astGeneric(e.object.property,t),t.push("]"),t.push("["),this.astGeneric(e.property,t),t.push("]"),t}if(!e.computed)switch(r){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const h=`${l}_${u}`;{let e,n;if("constants"===l){const t=this.constants[u];n="Input"===this.constantTypes[u],e=n?t.size:null}else n=this.isInput(u),e=n?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${h}`),o&&a?n?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):a?n?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):void 0!==s&&(t.push("["),this.astGeneric(s,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let n=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n);this.isAstMathFunction(e);this.onFunctionCall&&this.onFunctionCall(this.name,n,e.arguments),t.push(n),t.push("(");const r=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", "),this.astGeneric(s,t)}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length,i=[];for(let t=0;t{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});i.push(" _imageData,"," _colorData,",` color: ${t},`),s.push(` kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[n].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});s.push(t),i.push(" _mediaTo2DArray,"),i.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=r.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});s.push(t),i.push(" _mediaTo2DArray,")}return`function(settings) {\n${n.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n case 'Matrix(2)':\n case 'Matrix(3)':\n case 'Matrix(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${i.join("\n")} });\n ${s.join("\n")}\n return kernel;\n}`}}},{"../../utils":114}],8:[function(e,t,n){const{Kernel:r}=e("../kernel"),{FunctionBuilder:i}=e("../function-builder"),{CPUFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),{cpuKernelString:o}=e("./kernel-string");t.exports={CPUKernel:class extends r{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){throw new Error(`Looking up native function return type not supported on ${this.name}`)}static combineKernels(e){return e}static getSignature(e,t){return"cpu"+(t.length>0?":"+t.join(","):"")}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this._prependedString=[],this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d"):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=a.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${n}[x] = subKernelResult_${n};\n`:`result_${n}[x] = subKernelResult_${n};\n`)}this.followingReturnStatement=e.join("")}const e=i.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.built)return;if(this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const n=t[0],r=t[1]||1;e.width=n,e.height=r,this._imageData=this.context.createImageData(n,r),this._colorData=new Uint8ClampedArray(n*r*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}this.buildSignature(arguments),this.built=!0}color(e,t,n,r){void 0===r&&(r=1),e=Math.floor(255*e),t=Math.floor(255*t),n=Math.floor(255*n),r=Math.floor(255*r);const i=this.output[0],s=this.output[1],a=this.thread.x+(s-this.thread.y-1)*i;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=n,this._colorData[4*a+3]=r}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter((t=>/^function/.test(t)?t:(e=t,!1))):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._resultKernelHeader()}\n ${this._processConstants()}\n return (${this.argumentNames.map((e=>"user_"+e)).join(", ")}) => {\n ${this._prependedString.join("")}\n ${this._earlyThrows()}\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return o(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants){switch(this.constantTypes[t]){case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}}return e.join("")}_earlyThrows(){if(this.graphical)return"";if(this.immutable)return"";if(!this.pipeline)return"";const e=[];for(let t=0;t`user_${r} === result_${e.name}`)).join(" || ");t.push(`user_${r} === result${i?` || ${i}`:""}`)}return`if (${t.join(" || ")}) throw new Error('Source and destination arrays are the same. Use immutable = true');`}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,r=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(n);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`)).join(" ")}\n ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_mutableKernel1DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const result = new ${e}(outputX);\n ${this._mapSubKernels((t=>`const result_${t.name} = new ${e}(outputX);\n`)).join(" ")}\n ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join(" ")}`}_resultMutableKernel1DLoop(e){return` const outputX = _this.output[0];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultImmutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputY);\n`)).join(" ")}\n ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${t}(outputX);\n ${this._mapSubKernels((e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`)).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_mutableKernel2DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputY);\n`)).join(" ")}\n ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = result[y] = new ${e}(outputX);\n ${this._mapSubKernels((t=>`const resultX_${t.name} = result_${t.name}[y] = new ${e}(outputX);\n`)).join("")}\n }`}_resultMutableKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y];\n ${this._mapSubKernels((e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`)).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultImmutableKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputZ);\n`)).join(" ")}\n ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels((e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`)).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${t}(outputX);\n ${this._mapSubKernels((e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`)).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_mutableKernel3DResults(){const e=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels((e=>`const result_${e.name} = new Array(outputZ);\n`)).join(" ")}\n ${this._mapSubKernels((e=>`let subKernelResult_${e.name};\n`)).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels((e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`)).join(" ")}\n for (let y = 0; y < outputY; y++) {\n const resultX = resultY[y] = new ${e}(outputX);\n ${this._mapSubKernels((t=>`const resultX_${t.name} = resultY_${t.name}[y] = new ${e}(outputX);\n`)).join(" ")}\n }\n }`}_resultMutableKernel3DLoop(e){return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z];\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y];\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map((e=>`${e.property}: result_${e.name}`)).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=i.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,n]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,n),this._colorData=new Uint8ClampedArray(t*n*4))}prependString(e){if(this._kernelString)throw new Error("Kernel already built");this._prependedString.push(e)}hasPrependString(e){return this._prependedString.indexOf(e)>-1}}}},{"../../utils":114,"../function-builder":9,"../kernel":36,"./function-node":6,"./kernel-string":7}],9:[function(e,t,n){class r{static fromKernel(e,t,n){const{kernelArguments:i,kernelConstants:s,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:h,debug:c,loopMaxIterations:p,nativeFunctions:d,output:m,optimizeFloatMemory:f,precision:g,plugins:x,source:y,subKernels:b,functions:T,leadingReturnStatement:v,followingReturnStatement:S,dynamicArguments:A,dynamicOutput:_}=e,E=new Array(i.length),w={};for(let e=0;eG.needsArgumentType(e,t),I=(e,t,n)=>{G.assignArgumentType(e,t,n)},D=(e,t,n)=>G.lookupReturnType(e,t,n),C=e=>G.lookupFunctionArgumentTypes(e),$=(e,t)=>G.lookupFunctionArgumentName(e,t),L=(e,t)=>G.lookupFunctionArgumentBitRatio(e,t),R=(e,t,n,r)=>{G.assignArgumentType(e,t,n,r)},F=(e,t,n,r)=>{G.assignArgumentBitRatio(e,t,n,r)},N=(e,t,n)=>{G.trackFunctionCall(e,t,n)},V=(e,n)=>{const r=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:m,plugins:x,constants:l,constantTypes:w,constantBitRatios:h,optimizeFloatMemory:f,precision:g,lookupReturnType:D,lookupFunctionArgumentTypes:C,lookupFunctionArgumentName:$,lookupFunctionArgumentBitRatio:L,needsArgumentType:k,assignArgumentType:I,triggerImplyArgumentType:R,triggerImplyArgumentBitRatio:F,onFunctionCall:N,onNestedFunction:V}))));let K=null;b&&(K=b.map((e=>{const{name:n,source:r}=e;return new t(r,Object.assign({},M,{name:n,isSubKernel:!0,isRootKernel:!1}))})));const G=new r({kernel:e,rootNode:z,functionNodes:P,nativeFunctions:d,subKernelNodes:K});return G}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1){const n=t.indexOf(e);if(-1===n)t.push(e);else{const e=t.splice(n,1)[0];t.push(e)}return t}const n=this.functionMap[e];if(n){const r=t.indexOf(e);if(-1===r){t.push(e),n.toString();for(let e=0;e-1){t.push(this.nativeFunctions[i].source);continue}const s=this.functionMap[r];s&&t.push(s.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map((e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)}))}fromJSON(e,t){this.functionMap={};for(let n=0;n0){const i=t.arguments;for(let t=0;t0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"Math"!==e.object.name?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||r))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0})),n=t.body[0].declarations[0].init;if(this.traceFunctionAST(n),!t)throw new Error("Failed to parse JS code");return this.ast=n}traceFunctionAST(e){const{contexts:t,declarations:n,functions:r,identifiers:i,functionCalls:a}=new s(e);this.contexts=t,this.identifiers=i,this.functionCalls=a,this.functions=r;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const n=this.getType(e.left);if(this.isState("skip-literal-correction"))return n;if("LiteralInteger"===n){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return a[n]||n;case"UpdateExpression":case"ReturnStatement":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let n;for(let e=0;e-1}isAstMathFunction(e){return"CallExpression"===e.type&&e.callee&&"MemberExpression"===e.callee.type&&e.callee.object&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&e.callee.property&&"Identifier"===e.callee.property.type&&["abs","acos","acosh","asin","asinh","atan","atan2","atanh","cbrt","ceil","clz32","cos","cosh","expm1","exp","floor","fround","imul","log","log2","log10","log1p","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc"].indexOf(e.callee.property.name)>-1}isAstVariable(e){return"Identifier"===e.type||"MemberExpression"===e.type}isSafe(e){return this.isSafeDependencies(this.getDependencies(e))}isSafeDependencies(e){return!e||!e.every||e.every((e=>e.isSafe))}getDependencies(e,t,n){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let r=0;r-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,n);case"Identifier":const r=this.getDeclaration(e);if(r)t.push({name:e.name,origin:"declaration",isSafe:!n&&this.isSafeDependencies(r.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,n);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":case"LogicalExpression":return n="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,n),this.getDependencies(e.right,t,n),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,n);case"VariableDeclaration":return this.getDependencies(e.declarations,t,n);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const i=this.getMemberExpressionDetails(e);switch(i.signature){case"value[]":this.getDependencies(e.object,t,n);break;case"value[][]":this.getDependencies(e.object.object,t,n);break;case"value[][][]":this.getDependencies(e.object.object.object,t,n);break;case"this.output.value":this.dynamicOutput&&t.push({name:i.name,origin:"output",isSafe:!1})}if(i)return i.property&&this.getDependencies(i.property,t,n),i.xProperty&&this.getDependencies(i.xProperty,t,n),i.yProperty&&this.getDependencies(i.yProperty,t,n),i.zProperty&&this.getDependencies(i.zProperty,t,n),t;case"SequenceExpression":return this.getDependencies(e.expressions,t,n);default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e,t){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const n=[];for(;e;)e.computed?n.push("[]"):"ThisExpression"===e.type?n.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?n.unshift(t?"."+e.property.name:".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?n.unshift("."+e.property.name):n.unshift(t?"."+e.property.name:".value"):e.name?n.unshift(t?e.name:"value"):e.callee&&e.callee.name?n.unshift(t?e.callee.name+"()":"fn()"):e.elements?n.unshift("[]"):n.unshift("unknown"),e=e.object;const r=n.join("");if(t)return r;return["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"].indexOf(r)>-1?r:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let n=0;n0?r[r.length-1]:0;return new Error(`${e} on line ${r.length}, position ${s.length}:\n ${n}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t1?t.push("(",r.join(","),")"):t.push(r[0]),t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)||(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator))),t}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,n=null;const r=this.getVariableSignature(e);switch(r){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:r,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return t=e.object.object.object.object.name,{name:t,origin:"user",signature:r,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return t=e.property.name,{name:t,origin:"Math",type:"Number",signature:r};switch(e.property.name){case"r":case"g":case"b":case"a":return t=e.object.name,{name:t,property:e.property.name,origin:"user",signature:r,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,n=this.getConstantType(t),!n)throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"fn()[][]":case"[][]":return{signature:r,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const n=t[0];if("VariableDeclarator"===n.type&&n.id&&n.id.name&&n.id.name===e.name)return n;if(t.shift(),n.argument)t.push(n.argument);else if(n.body)t.push(n.body);else if(n.declarations)t.push(n.declarations);else if(Array.isArray(n))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let n=0;n0?e[e.length-1]:null}const s="trackIdentifiers",a="memberExpression",o="inForLoopInit";t.exports={FunctionTracer:class{constructor(e){this.runningContexts=[],this.functionContexts=[],this.contexts=[],this.functionCalls=[],this.declarations=[],this.identifiers=[],this.functions=[],this.returnStatements=[],this.trackedIdentifiers=null,this.states=[],this.newFunctionContext(),this.scan(e)}isState(e){return this.states[this.states.length-1]===e}hasState(e){return this.states.indexOf(e)>-1}pushState(e){this.states.push(e)}popState(e){if(!this.isState(e))throw new Error(`Cannot pop the non-active state "${e}"`);this.states.pop()}get currentFunctionContext(){return i(this.functionContexts)}get currentContext(){return i(this.runningContexts)}newFunctionContext(){const e={"@contextType":"function"};this.contexts.push(e),this.functionContexts.push(e)}newContext(e){const t=Object.assign({"@contextType":"const/let"},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e();const{currentFunctionContext:n}=this;for(const e in n)n.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=n[e]);return this.runningContexts.pop(),t}useFunctionContext(e){const t=i(this.functionContexts);this.runningContexts.push(t),e(),this.runningContexts.pop()}getIdentifiers(e){const t=this.trackedIdentifiers=[];return this.pushState(s),e(),this.trackedIdentifiers=null,this.popState(s),t}getDeclaration(e){const{currentContext:t,currentFunctionContext:n,runningContexts:r}=this,i=t[e]||n[e]||null;if(!i&&t===n&&r.length>0){const t=r[r.length-2];if(t[e])return t[e]}return i}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)}));break;case"BlockStatement":this.newContext((()=>{this.scan(e.body)}));break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":if("++"===e.operator){const t=this.getDeclaration(e.argument.name);t&&(t.suggestedType="Integer")}this.scan(e.argument);break;case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":"var"===e.kind?this.useFunctionContext((()=>{e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations)})):(e.declarations=r.normalizeDeclarations(e),this.scan(e.declarations));break;case"VariableDeclarator":{const{currentContext:t}=this,n=this.hasState(o),r={ast:e,context:t,name:e.id.name,origin:"declaration",inForLoopInit:n,inForLoopTest:null,assignable:t===this.currentFunctionContext||!n&&!t.hasOwnProperty(e.id.name),suggestedType:null,valueType:null,dependencies:null,isSafe:null};t[e.id.name]||(t[e.id.name]=r),this.declarations.push(r),this.scan(e.id),this.scan(e.init);break}case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":{let t;const n=this.newContext((()=>{this.pushState(o),this.scan(e.init),this.popState(o),t=this.getIdentifiers((()=>{this.scan(e.test)})),this.scan(e.update),this.newContext((()=>{this.scan(e.body)}))}));if(t)for(const e in n)"@contextType"!==e&&t.indexOf(e)>-1&&(n[e].inForLoopTest=!0);break}case"DoWhileStatement":case"WhileStatement":this.newContext((()=>{this.scan(e.body),this.scan(e.test)}));break;case"Identifier":this.isState(s)&&this.trackedIdentifiers.push(e.name),this.identifiers.push({context:this.currentContext,declaration:this.getDeclaration(e.name),ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.pushState(a),this.scan(e.object),this.scan(e.property),this.popState(a);break;case"ExpressionStatement":this.scan(e.expression);break;case"SequenceExpression":this.scan(e.expressions);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}},{"../utils":114}],12:[function(e,t,n){const{glWiretap:r}=e("gl-wiretap"),{utils:i}=e("../../utils");function s(e){return e.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const n="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${n}, ${t.output[0]})`}function o(e,t,n){const r=e.toArray.toString(),s=!/^function/.test(r);return`() => {\n function framebuffer() { return ${n}; };\n ${i.flattenFunctionToString(`${s?"function ":""}${r}`,{findDependency:(t,n)=>{if("utils"===t)return`const ${n} = ${i[n].toString()};`;if("this"===t)return"framebuffer"===n?"":`${s?"function ":""}${e[n].toString()}`;throw new Error("unhandled fromObject")},thisLookup:(n,r)=>{if("texture"===n)return t;if("context"===n)return r?null:"gl";if(e.hasOwnProperty(n))return JSON.stringify(e[n]);throw new Error(`unhandled thisLookup ${n}`)}})}\n return toArray();\n }`}function u(e,t,n,r,i){if(null===e)return null;if(null===t)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement)for(let i=0;i{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}})):null;const c=[],p=[],d=r(n.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(N.subKernels){if(m){const t=N.subKernels[f++].property;p.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,N)};`)}else p.push(` const result = { result: ${a(e,N)} };`),m=!0;f===N.subKernels.length&&p.push(" return result;")}else e?p.push(` return ${a(e,N)};`):p.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,N.kernelArguments,[],d,c);if(t)return t;const n=u(e,N.kernelConstants,S?Object.keys(S).map((e=>S[e])):[],d,c);return n||null}});let m=!1,f=0;const{source:g,canvas:x,output:y,pipeline:b,graphical:T,loopMaxIterations:v,constants:S,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:k,subKernels:I,immutable:D,argumentTypes:C,constantTypes:$,kernelArguments:L,kernelConstants:R,tactic:F}=n,N=new e(g,{canvas:x,context:d,checkContext:!1,output:y,pipeline:b,graphical:T,loopMaxIterations:v,constants:S,optimizeFloatMemory:A,precision:_,fixIntegerDivisionAccuracy:E,functions:w,nativeFunctions:k,subKernels:I,immutable:D,argumentTypes:C,constantTypes:$,tactic:F});let V=[];if(d.setIndent(2),N.build.apply(N,t),V.push(d.toString()),d.reset(),N.kernelArguments.forEach(((e,n)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLCanvas":case"HTMLImage":case"HTMLVideo":case"Input":d.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let r=0;re.varName)).join(", ")}) {`),d.setIndent(4),N.run.apply(N,t),N.renderKernels?N.renderKernels():N.renderOutput&&N.renderOutput(),V.push(" /** start setup uploads for kernel values **/"),N.kernelArguments.forEach((e=>{V.push(" "+e.getStringValueHandler().split("\n").join("\n "))})),V.push(" /** end setup uploads for kernel values **/"),V.push(d.toString()),N.renderOutput===N.renderTexture){d.reset();const e=d.getContextVariableName(N.framebuffer);if(N.renderKernels){const t=N.renderKernels(),n=d.getContextVariableName(N.texture.texture);V.push(` return {\n result: {\n texture: ${n},\n type: '${t.result.type}',\n toArray: ${o(t.result,n,e)}\n },`);const{subKernels:r,mappedTextures:i}=N;for(let n=0;n"utils"===e?`const ${t} = ${i[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(N)),V.push(" innerKernel.getPixels = getPixels;")),V.push(" return innerKernel;");let M=[];return R.forEach((e=>{M.push(`${e.getStringValueHandler()}`)})),`function kernel(settings) {\n const { context, constants } = settings;\n ${M.join("")}\n ${l||""}\n${V.join("\n")}\n}`}}},{"../../utils":114,"gl-wiretap":3}],13:[function(e,t,n){const{Kernel:r}=e("../kernel"),{utils:i}=e("../../utils"),{GLTextureArray2Float:s}=e("./texture/array-2-float"),{GLTextureArray2Float2D:a}=e("./texture/array-2-float-2d"),{GLTextureArray2Float3D:o}=e("./texture/array-2-float-3d"),{GLTextureArray3Float:u}=e("./texture/array-3-float"),{GLTextureArray3Float2D:l}=e("./texture/array-3-float-2d"),{GLTextureArray3Float3D:h}=e("./texture/array-3-float-3d"),{GLTextureArray4Float:c}=e("./texture/array-4-float"),{GLTextureArray4Float2D:p}=e("./texture/array-4-float-2d"),{GLTextureArray4Float3D:d}=e("./texture/array-4-float-3d"),{GLTextureFloat:m}=e("./texture/float"),{GLTextureFloat2D:f}=e("./texture/float-2d"),{GLTextureFloat3D:g}=e("./texture/float-3d"),{GLTextureMemoryOptimized:x}=e("./texture/memory-optimized"),{GLTextureMemoryOptimized2D:y}=e("./texture/memory-optimized-2d"),{GLTextureMemoryOptimized3D:b}=e("./texture/memory-optimized-3d"),{GLTextureUnsigned:T}=e("./texture/unsigned"),{GLTextureUnsigned2D:v}=e("./texture/unsigned-2d"),{GLTextureUnsigned3D:S}=e("./texture/unsigned-3d"),{GLTextureGraphical:A}=e("./texture/graphical");const _={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends r{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),2===n[0]&&1511===n[1]}static getIsSpeedTacticSupported(){const e=new this(function(e){return e[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[4],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[0,1,2,3]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),0===Math.round(n[0])&&1===Math.round(n[1])&&2===Math.round(n[2])&&3===Math.round(n[3])}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static getFeatures(){const e=this.testContext,t=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isSpeedTacticSupported:this.getIsSpeedTacticSupported(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:t,kernelMap:t,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize(),lowIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_INT),lowFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.LOW_FLOAT),mediumIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_INT),mediumFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT),highIntPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_INT),highFloatPrecision:e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT)})}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}static getSignature(e,t){return e.getVariablePrecisionString()+(t.length>0?":"+t.join(","):"")}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return i.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],n=[],r=[],i=/^[a-zA-Z_]/,s=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?r[r.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"*"!==h)if("MULTI_LINE_COMMENT"!==c||"*"!==l||"/"!==h)if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"/"!==h)if("COMMENT"!==c||"\n"!==l)if(null!==c||"("!==l){if("FUNCTION_ARGUMENTS"===c){if(")"===l){r.pop();break}if("f"===l&&"l"===h&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){r.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===l&&"n"===h&&"t"===e[a+2]&&" "===e[a+3]){r.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===l){a++;continue}if(!i.test(l))throw new Error("variable name is not expected string")}o+=l,s.test(h)||(r.pop(),n.push(o),t.push(_[u]))}a++}else r.push("FUNCTION_ARGUMENTS"),a++;else r.pop(),a++;else r.push("COMMENT"),a+=2;else r.pop(),a+=2;else r.push("MULTI_LINE_COMMENT"),a+=2}if(r.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:n,argumentTypes:t}}static nativeFunctionReturnType(e){return _[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:n,context:r,threadDim:s}=t.texSize;let a;if("single"===t.precision){const e=n[0],t=Math.ceil(n[1]/4);a=new Float32Array(e*t*4*4),r.readPixels(0,0,e,4*t,r.RGBA,r.FLOAT,a)}else{const e=new Uint8Array(n[0]*n[1]*4);r.readPixels(0,0,n[0],n[1],r.RGBA,r.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}if(a=a.subarray(0,s[0]*s[1]*s[2]),1===t.output.length)return a;if(2===t.output.length)return i.splitArray(a,t.output[0]);if(3===t.output.length){return i.splitArray(a,t.output[0]*t.output[1]).map((function(e){return i.splitArray(e,t.output[0])}))}}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.switchingKernels=null,this._textureSwitched=null,this._mappedTextureSwitched=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=A,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=S,null):this.output[1]>0?(this.TextureConstructor=v,null):(this.TextureConstructor=T,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=S,this.formatValues=i.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=v,this.formatValues=i.erect2DPackedFloat,null):(this.TextureConstructor=T,this.formatValues=i.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=b,null):this.output[1]>0?(this.TextureConstructor=y,null):(this.TextureConstructor=x,null):this.output[2]>0?(this.TextureConstructor=g,null):this.output[1]>0?(this.TextureConstructor=f,null):(this.TextureConstructor=m,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,null):this.output[1]>0?(this.TextureConstructor=a,null):(this.TextureConstructor=s,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,null):this.output[1]>0?(this.TextureConstructor=l,null):(this.TextureConstructor=u,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,null):this.output[1]>0?(this.TextureConstructor=p,null):(this.TextureConstructor=c,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=b,this.formatValues=i.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=y,this.formatValues=i.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=x,this.formatValues=i.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=c,this.formatValues=i.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=g,this.formatValues=i.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=f,this.formatValues=i.erect2DFloat,null):(this.TextureConstructor=m,this.formatValues=i.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=o,this.formatValues=i.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=a,this.formatValues=i.erect2DArray2,null):(this.TextureConstructor=s,this.formatValues=i.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.formatValues=i.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=l,this.formatValues=i.erect2DArray3,null):(this.TextureConstructor=u,this.formatValues=i.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=d,this.formatValues=i.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=p,this.formatValues=i.erect2DArray4,null):(this.TextureConstructor=c,this.formatValues=i.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return i.linesToString(this.getMainResultKernelNumberTexture())+i.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return i.linesToString(this.getMainResultKernelArray2Texture())+i.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return i.linesToString(this.getMainResultKernelArray3Texture())+i.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return i.linesToString(this.getMainResultKernelArray4Texture())+i.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} float;\n`}getIntTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic,!0)} int;\n`}getSampler2DTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2D;\n`}getSampler2DArrayTacticDeclaration(){return`precision ${this.getVariablePrecisionString(this.texSize,this.tactic)} sampler2DArray;\n`}renderTexture(){return this.immutable?this.texture.clone():this.texture}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,n=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,n),n}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,n=e[0],r=e[1],i=new Float32Array(n*r*4);return t.readPixels(0,0,n,r,t.RGBA,t.FLOAT,i),i}getPixels(e){const{context:t,output:n}=this,[r,s]=n,a=new Uint8Array(r*s*4);return t.readPixels(0,0,r,s,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:i.flipPixels(a,r,s)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0){for(let e=0;e0){const{mappedTextures:n}=this;for(let r=0;r1&&(this.newTexture(),!0)}cloneTexture(){this.texture._refs--;const{context:e,size:t,texture:n,kernel:r}=this;r.debug&&console.warn("cloning internal texture"),e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),i(e,n),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,n,0);const s=e.createTexture();i(e,s),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),e.copyTexSubImage2D(e.TEXTURE_2D,0,0,0,0,0,t[0],t[1]),s._refs=1,this.texture=s}newTexture(){this.texture._refs--;const e=this.context,t=this.size;this.kernel.debug&&console.warn("new internal texture");const n=e.createTexture();i(e,n),e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,t[0],t[1],0,this.textureFormat,this.textureType,null),n._refs=1,this.texture=n}clear(){if(this.texture._refs){this.texture._refs--;const e=this.context,t=this.texture=e.createTexture();i(e,t);const n=this.size;t._refs=1,e.texImage2D(e.TEXTURE_2D,0,this.internalFormat,n[0],n[1],0,this.textureFormat,this.textureType,null)}const{context:e,texture:t}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.bindTexture(e.TEXTURE_2D,t),i(e,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)}delete(){this._deleted||(this._deleted=!0,this.texture._refs&&(this.texture._refs--,this.texture._refs)||this.context.deleteTexture(this.texture))}framebuffer(){return this._framebuffer||(this._framebuffer=this.kernel.getRawValueFramebuffer(this.size[0],this.size[1])),this._framebuffer}}}},{"../../../texture":113}],28:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized2D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":114,"./float":25}],29:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized3D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":114,"./float":25}],30:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":114,"./float":25}],31:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned2D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":114,"./unsigned":33}],32:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned3D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":114,"./unsigned":33}],33:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTexture:i}=e("./index");t.exports={GLTextureUnsigned:class extends i{get textureType(){return this.context.UNSIGNED_BYTE}constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this;e.bindFramebuffer(e.FRAMEBUFFER,this.framebuffer()),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const t=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,t),t}renderValues(){return this._deleted?null:new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":114,"./index":27}],34:[function(e,t,n){const r=e("gl"),{WebGLKernel:i}=e("../web-gl/kernel"),{glKernelString:s}=e("../gl/kernel-string");let a=null,o=null,u=null,l=null,h=null;t.exports={HeadlessGLKernel:class extends i{static get isSupported(){return null!==a||(this.setupFeatureChecks(),a=null!==u),a}static setupFeatureChecks(){if(o=null,l=null,"function"==typeof r)try{if(u=r(2,2,{preserveDrawingBuffer:!0}),!u||!u.getExtension)return;l={STACKGL_resize_drawingbuffer:u.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:u.getExtension("STACKGL_destroy_context"),OES_texture_float:u.getExtension("OES_texture_float"),OES_texture_float_linear:u.getExtension("OES_texture_float_linear"),OES_element_index_uint:u.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:u.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:u.getExtension("WEBGL_color_buffer_float")},h=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getIsTextureFloat(){return Boolean(l.OES_texture_float)}static getIsDrawBuffers(){return Boolean(l.WEBGL_draw_buffers)}static getChannelCount(){return l.WEBGL_draw_buffers?u.getParameter(l.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return u.getParameter(u.MAX_TEXTURE_SIZE)}static get testCanvas(){return o}static get testContext(){return u}static get features(){return h}initCanvas(){return{}}initContext(){return r(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return s(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n"," if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){return super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1]),this}}}},{"../gl/kernel-string":12,"../web-gl/kernel":70,gl:2}],35:[function(e,t,n){t.exports={KernelValue:class{constructor(e,t){const{name:n,kernel:r,context:i,checkContext:s,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:l,type:h,tactic:c}=t;if(!n)throw new Error("name not set");if(!h)throw new Error("type not set");if(!u)throw new Error("origin not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=n,this.origin=u,this.tactic=c,this.varName="constants"===u?`constants.${n}`:n,this.kernel=r,this.strictIntegers=l,this.type=e.type||h,this.size=e.size||null,this.index=null,this.context=i,this.checkContext=null==s||s,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}get id(){return`${this.origin}_${name}`}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}},{}],36:[function(e,t,n){const{utils:r}=e("../utils"),{Input:i}=e("../input");t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!r.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.argumentNames="string"==typeof e?r.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.precision=null,this.tactic=null,this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.built=!1,this.signature=null}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":this.functions=[];for(let t=0;te.name)):null,returnType:this.returnType}}}buildSignature(e){const t=this.constructor;this.signature=t.getSignature(this,t.getArgumentTypes(this,e))}static getArgumentTypes(e,t){const n=new Array(t.length);for(let i=0;it.argumentTypes[e]))||[]:t.argumentTypes||[],{name:r.getFunctionNameFromString(n)||null,source:n,argumentTypes:i,returnType:t.returnType||null}}onActivate(e){}}}},{"../input":110,"../utils":114}],37:[function(e,t,n){const r=`__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nfloat acosh(float x) {\n return log(x + sqrt(x * x - 1.0));\n}\n\nfloat sinh(float x) {\n return (pow(${Math.E}, x) - pow(${Math.E}, -x)) / 2.0;\n}\n\nfloat asinh(float x) {\n return log(x + sqrt(x * x + 1.0));\n}\n\nfloat atan2(float v1, float v2) {\n if (v1 == 0.0 || v2 == 0.0) return 0.0;\n return atan(v1 / v2);\n}\n\nfloat atanh(float x) {\n x = (x + 1.0) / (x - 1.0);\n if (x < 0.0) {\n return 0.5 * log(-x);\n }\n return 0.5 * log(x);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat cosh(float x) {\n return (pow(${Math.E}, x) + pow(${Math.E}, -x)) / 2.0; \n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat tanh(float x) {\n float e = exp(2.0 * x);\n return (e - 1.0) / (e + 1.0);\n}\n\nfloat trunc(float x) {\n if (x >= 0.0) {\n return floor(x); \n } else {\n return ceil(x);\n }\n}\n\nvec4 _round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(_round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(_round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n\n mantissa = value*pow(2.0, -exponent)-1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n \n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`;t.exports={fragmentShader:r}},{}],38:[function(e,t,n){const{utils:r}=e("../../utils"),{FunctionNode:i}=e("../function-node");const s={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4","Matrix(2)":"mat2","Matrix(3)":"mat3","Matrix(4)":"mat4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLCanvas:"sampler2D",OffscreenCanvas:"sampler2D",HTMLImage:"sampler2D",ImageBitmap:"sampler2D",ImageData:"sampler2D",HTMLImageArray:"sampler2DArray"},a={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends i{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);const n=this.getType(e.consequent),r=this.getType(e.alternate);return null===n&&null===r?(t.push("if ("),this.astGeneric(e.test,t),t.push(") {"),this.astGeneric(e.consequent,t),t.push(";"),t.push("} else {"),this.astGeneric(e.alternate,t),t.push(";"),t.push("}"),t):(t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{if(!this.returnType){this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"))}const{returnType:n}=this;if(n){const e=s[n];if(!e)throw new Error(`unknown type ${n}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let n=0;n0&&t.push(", ");let a=this.argumentTypes[this.argumentNames.indexOf(i)];if(!a)throw this.astErrorOutput(`Unknown argument ${i} type`,e);"LiteralInteger"===a&&(this.argumentTypes[n]=a="Number");const o=s[a];if(!o)throw this.astErrorOutput("Unexpected expression",e);const u=r.sanitizeName(i);"sampler2D"===o||"sampler2DArray"===o?t.push(`${o} user_${u},ivec2 user_${u}Size,ivec3 user_${u}Dim`):t.push(`${o} user_${u}`)}t.push(") {\n");for(let n=0;n"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const n=[];this.astGeneric(e.right,n);if("Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(n.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float");break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${i}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const n=this.checkAndUpconvertBitwiseOperators(e,t);if(n)return n;const r={"%":this.fixIntegerDivisionAccuracy?"integerCorrectionModulo":"modulo","**":"pow"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const n={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!n)return null;t.push(n),t.push("(");switch(this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}t.push(",");switch(this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const n={"~":"bitwiseNot"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),i=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const n=[],r=[],i=[],s=[];let a=null;if(e.init){const{declarations:t}=e.init;t.length>1&&(a=!1),this.astGeneric(e.init,n);for(let e=0;e0&&t.push(n.join(""),"\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const n=this.getInternalVariableName("safeI");return t.push(`for (int ${n}=0;${n}0&&o.push(u.join(",")),i.push(o.join(";")),t.push(i.join("")),t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type||"IfStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){if("SwitchStatement"!==e.type)throw this.astErrorOutput("Invalid switch statement",e);const{discriminant:n,cases:r}=e,i=this.getType(n),s=`switchDiscriminant${this.astKey(e,"_")}`;switch(i){case"Float":case"Number":t.push(`float ${s} = `),this.astGeneric(n,t),t.push(";\n");break;case"Integer":t.push(`int ${s} = `),this.astGeneric(n,t),t.push(";\n")}if(1===r.length&&!r[0].test)return this.astGeneric(r[0].consequent,t),t;let a=!1,o=[],u=!1,l=!1;for(let e=0;ee+1){u=!0,this.astGeneric(r[e].consequent,o);continue}t.push(" else {\n")}this.astGeneric(r[e].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:n,name:i,signature:s,origin:a,type:o,xProperty:u,yProperty:l,zProperty:h}=this.getMemberExpressionDetails(e);switch(s){case"value.thread.value":case"this.thread.value":if("x"!==i&&"y"!==i&&"z"!==i)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${i}`),t;case"this.output.value":if(this.dynamicOutput)switch(i){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(i){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===a)return t.push(Math[i]),t;const s=r.sanitizeName(i);switch(n){case"r":return t.push(`user_${s}.r`),t;case"g":return t.push(`user_${s}.g`),t;case"b":return t.push(`user_${s}.b`),t;case"a":return t.push(`user_${s}.a`),t}break;case"this.constants.value":if(void 0===u)switch(o){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r.sanitizeName(i)}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;case"fn()[][]":return this.astCallExpression(e.object.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.object.property)),t.push("]"),t.push("["),t.push(this.memberExpressionPropertyMarkup(e.property)),t.push("]"),t;case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(o){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${a}_${r.sanitizeName(i)}`),t}const c=`${a}_${r.sanitizeName(i)}`;switch(o){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(u)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLVideo":t.push(`getVec4FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");else{const e="user"===a?this.lookupFunctionArgumentBitRatio(this.name,i):this.constantBitRatios[i];switch(e){case 1:t.push(`get8(${c}, ${c}Size, ${c}Dim, `);break;case 2:t.push(`get16(${c}, ${c}Size, ${c}Dim, `);break;case 4:case 0:t.push(`get32(${c}, ${c}Size, ${c}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(u,l,h,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(u,l,h,t),t.push(")");break;case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`${c}[${this.memberExpressionPropertyMarkup(l)}]`),l&&t.push(`[${this.memberExpressionPropertyMarkup(u)}]`);break;default:throw new Error(`unhandled member expression "${o}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const i=this.isAstMathFunction(e);if(n=i||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name,!n)throw this.astErrorOutput("Unhandled function, couldn't find name",e);switch(n){case"pow":n="_pow";break;case"round":n="_round"}if(this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),"Integer"===i)this.castValueToFloat(r,t);else this.astGeneric(r,t)}else{const i=this.lookupFunctionArgumentTypes(n)||[];for(let s=0;s0&&t.push(", ");const u=this.getType(a);switch(o||(this.triggerImplyArgumentType(n,s,u,this),o=u),u){case"Boolean":this.astGeneric(a,t);continue;case"Number":case"Float":if("Integer"===o){t.push("int("),this.astGeneric(a,t),t.push(")");continue}if("Number"===o||"Float"===o){this.astGeneric(a,t);continue}if("LiteralInteger"===o){this.castLiteralToFloat(a,t);continue}break;case"Integer":if("Number"===o||"Float"===o){t.push("float("),this.astGeneric(a,t),t.push(")");continue}if("Integer"===o){this.astGeneric(a,t);continue}break;case"LiteralInteger":if("Integer"===o){this.castLiteralToInteger(a,t);continue}if("Number"===o||"Float"===o){this.castLiteralToFloat(a,t);continue}if("LiteralInteger"===o){this.astGeneric(a,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(o===u){if("Identifier"===a.type)t.push(`user_${r.sanitizeName(a.name)}`);else{if("ArrayExpression"!==a.type&&"MemberExpression"!==a.type&&"CallExpression"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.astGeneric(a,t)}continue}break;case"HTMLCanvas":case"OffscreenCanvas":case"HTMLImage":case"ImageBitmap":case"ImageData":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(o===u){if("Identifier"!==a.type)throw this.astErrorOutput(`Unhandled argument type ${a.type}`,e);this.triggerImplyArgumentBitRatio(this.name,a.name,n,s);const i=r.sanitizeName(a.name);t.push(`user_${i},user_${i}Size,user_${i}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${u} and ${o} for argument named "${a.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const n=this.getType(e),r=e.elements.length;switch(n){case"Matrix(2)":case"Matrix(3)":case"Matrix(4)":t.push(`mat${r}(`);break;default:t.push(`vec${r}(`)}for(let n=0;n0&&t.push(", ");const r=e.elements[n];this.astGeneric(r,t)}return t.push(")"),t}memberExpressionXYZ(e,t,n,r){return n?r.push(this.memberExpressionPropertyMarkup(n),", "):r.push("0, "),t?r.push(this.memberExpressionPropertyMarkup(t),", "):r.push("0, "),r.push(this.memberExpressionPropertyMarkup(e)),r}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}return t.join("")}}}},{"../../utils":114,"../function-node":10}],39:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGLKernelValueFloat:i}=e("./kernel-value/float"),{WebGLKernelValueInteger:s}=e("./kernel-value/integer"),{WebGLKernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGLKernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGLKernelValueHTMLVideo:u}=e("./kernel-value/html-video"),{WebGLKernelValueDynamicHTMLVideo:l}=e("./kernel-value/dynamic-html-video"),{WebGLKernelValueSingleInput:h}=e("./kernel-value/single-input"),{WebGLKernelValueDynamicSingleInput:c}=e("./kernel-value/dynamic-single-input"),{WebGLKernelValueUnsignedInput:p}=e("./kernel-value/unsigned-input"),{WebGLKernelValueDynamicUnsignedInput:d}=e("./kernel-value/dynamic-unsigned-input"),{WebGLKernelValueMemoryOptimizedNumberTexture:m}=e("./kernel-value/memory-optimized-number-texture"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:f}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGLKernelValueNumberTexture:g}=e("./kernel-value/number-texture"),{WebGLKernelValueDynamicNumberTexture:x}=e("./kernel-value/dynamic-number-texture"),{WebGLKernelValueSingleArray:y}=e("./kernel-value/single-array"),{WebGLKernelValueDynamicSingleArray:b}=e("./kernel-value/dynamic-single-array"),{WebGLKernelValueSingleArray1DI:T}=e("./kernel-value/single-array1d-i"),{WebGLKernelValueDynamicSingleArray1DI:v}=e("./kernel-value/dynamic-single-array1d-i"),{WebGLKernelValueSingleArray2DI:S}=e("./kernel-value/single-array2d-i"),{WebGLKernelValueDynamicSingleArray2DI:A}=e("./kernel-value/dynamic-single-array2d-i"),{WebGLKernelValueSingleArray3DI:_}=e("./kernel-value/single-array3d-i"),{WebGLKernelValueDynamicSingleArray3DI:E}=e("./kernel-value/dynamic-single-array3d-i"),{WebGLKernelValueArray2:w}=e("./kernel-value/array2"),{WebGLKernelValueArray3:k}=e("./kernel-value/array3"),{WebGLKernelValueArray4:I}=e("./kernel-value/array4"),{WebGLKernelValueUnsignedArray:D}=e("./kernel-value/unsigned-array"),{WebGLKernelValueDynamicUnsignedArray:C}=e("./kernel-value/dynamic-unsigned-array"),$={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:C,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:D,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:b,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":v,"Array1D(3)":v,"Array1D(4)":v,"Array2D(2)":A,"Array2D(3)":A,"Array2D(4)":A,"Array3D(2)":E,"Array3D(3)":E,"Array3D(4)":E,Input:c,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:f,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:y,"Array(2)":w,"Array(3)":k,"Array(4)":I,"Array1D(2)":T,"Array1D(3)":T,"Array1D(4)":T,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:h,NumberTexture:g,"ArrayTexture(1)":g,"ArrayTexture(2)":g,"ArrayTexture(3)":g,"ArrayTexture(4)":g,MemoryOptimizedNumberTexture:m,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:!1,HTMLVideo:u}}};t.exports={lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const i=$[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]},kernelValueMaps:$}},{"./kernel-value/array2":41,"./kernel-value/array3":42,"./kernel-value/array4":43,"./kernel-value/boolean":44,"./kernel-value/dynamic-html-image":45,"./kernel-value/dynamic-html-video":46,"./kernel-value/dynamic-memory-optimized-number-texture":47,"./kernel-value/dynamic-number-texture":48,"./kernel-value/dynamic-single-array":49,"./kernel-value/dynamic-single-array1d-i":50,"./kernel-value/dynamic-single-array2d-i":51,"./kernel-value/dynamic-single-array3d-i":52,"./kernel-value/dynamic-single-input":53,"./kernel-value/dynamic-unsigned-array":54,"./kernel-value/dynamic-unsigned-input":55,"./kernel-value/float":56,"./kernel-value/html-image":57,"./kernel-value/html-video":58,"./kernel-value/integer":60,"./kernel-value/memory-optimized-number-texture":61,"./kernel-value/number-texture":62,"./kernel-value/single-array":63,"./kernel-value/single-array1d-i":64,"./kernel-value/single-array2d-i":65,"./kernel-value/single-array3d-i":66,"./kernel-value/single-input":67,"./kernel-value/unsigned-array":68,"./kernel-value/unsigned-input":69}],40:[function(e,t,n){const{WebGLKernelValue:r}=e("./index"),{Input:i}=e("../../../input");t.exports={WebGLKernelArray:class extends r{checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:n}=this.kernel.constructor.features;if(e>n||t>n)throw e>t?new Error(`Argument texture width of ${e} larger than maximum size of ${n} for your GPU`):ee===r.name))&&t.push(r)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision=t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);switch(t){case"Array":this.output=a.getDimensions(t);break;case"NumberTexture":case"MemoryOptimizedNumberTexture":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":this.output=e[0].output;break;default:throw new Error("Auto output not supported for input type: "+t)}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let n=y.indexOf(t);-1===n&&(n=y.length,y.push(t),b[n]=[e[0],e[1]]),this.maxTexSize=b[n]}this.maxTexSize[0]this.argumentNames.length)throw new Error("too many arguments for kernel");const{context:n}=this;let r=0;const i=()=>this.createTexture(),s=()=>this.constantTextureCount+r++,o=e=>{this.switchKernels({type:"argumentMismatch",needed:e})},u=()=>n.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++;for(let r=0;rthis.createTexture(),onRequestIndex:()=>r++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[i]=l.bitRatio,this.kernelConstants.push(l),l.setup(),l.forceUploadEachRun&&this.forceUploadKernelConstants.push(l)}}build(){if(this.built)return;if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:n,canvas:r}=this;n.enable(n.SCISSOR_TEST),this.pipeline&&this.precision,n.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),r.width=this.maxTexSize[0],r.height=this.maxTexSize[1];const i=this.threadDim=Array.from(this.output);for(;i.length<3;)i.push(1);const s=this.getVertexShader(arguments),a=n.createShader(n.VERTEX_SHADER);n.shaderSource(a,s),n.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=n.createShader(n.FRAGMENT_SHADER);if(n.shaderSource(u,o),n.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!n.getShaderParameter(a,n.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+n.getShaderInfoLog(a));if(!n.getShaderParameter(u,n.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+n.getShaderInfoLog(u));const l=this.program=n.createProgram();n.attachShader(l,a),n.attachShader(l,u),n.linkProgram(l),this.framebuffer=n.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1],this.rawValueFramebuffers={};const h=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=h.byteLength;let d=this.buffer;d?n.bindBuffer(n.ARRAY_BUFFER,d):(d=this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,d),n.bufferData(n.ARRAY_BUFFER,h.byteLength+c.byteLength,n.STATIC_DRAW)),n.bufferSubData(n.ARRAY_BUFFER,0,h),n.bufferSubData(n.ARRAY_BUFFER,p,c);const m=n.getAttribLocation(this.program,"aPos");n.enableVertexAttribArray(m),n.vertexAttribPointer(m,2,n.FLOAT,!1,0,0);const f=n.getAttribLocation(this.program,"aTexCoord");n.enableVertexAttribArray(f),n.vertexAttribPointer(f,2,n.FLOAT,!1,0,p),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer);let g=0;n.useProgram(this.program);for(let e in this.constants)this.kernelConstants[g++].updateValue(this.constants[e]);this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&(this._mappedTextureSwitched={},this._setupSubOutputTextures()),this.buildSignature(arguments),this.built=!0}translateSource(){const e=i.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});this.translatedSource=e.getPrototypeString("kernel"),this.setupReturnTypes(e)}setupReturnTypes(e){if(this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"")).join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:n}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${n[0]}, ${n[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float divWithIntCheck(float x, float y) {\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\n return float(int(x) / int(y));\n }\n return x / y;\n}\n\nfloat integerCorrectionModulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -(number - (divisor * floor(divWithIntCheck(number, divisor))));\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return number - (divisor * floor(divWithIntCheck(number, divisor)));\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:n}=this;for(let r=0;r{if(t.hasOwnProperty(n))return t[n];throw`unhandled artifact ${n}`}))}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return h(this.constructor,arguments,this,e)}destroy(e){if(!this.context)return;this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer);for(const e in this.rawValueFramebuffers){for(const t in this.rawValueFramebuffers[e])this.context.deleteFramebuffer(this.rawValueFramebuffers[e][t]),delete this.rawValueFramebuffers[e][t];delete this.rawValueFramebuffers[e]}if(this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program),this.texture){this.texture.delete();const e=this.textureCache.indexOf(this.texture.texture);e>-1&&this.textureCache.splice(e,1),this.texture=null}if(this.mappedTextures&&this.mappedTextures.length){for(let e=0;e-1&&this.textureCache.splice(n,1)}this.mappedTextures=null}if(this.kernelArguments)for(let e=0;e0;){const e=this.textureCache.pop();this.context.deleteTexture(e)}if(e){const e=y.indexOf(this.canvas);e>=0&&(y[e]=null,b[e]=null)}if(this.destroyExtensions(),delete this.context,delete this.canvas,!this.gpu)return;const t=this.gpu.kernels.indexOf(this);-1!==t&&this.gpu.kernels.splice(t,1)}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=i.fromKernel(this,s).toJSON(),e.settings.threadDim=this.threadDim,e}}}},{"../../plugins/math-random-uniformly-distributed":112,"../../utils":114,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":37,"./function-node":38,"./kernel-value-maps":39,"./vertex-shader":71}],71:[function(e,t,n){t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}},{}],72:[function(e,t,n){const r=`#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nfloat atan2(float v1, float v2) {\n if (v1 == 0.0 || v2 == 0.0) return 0.0;\n return atan(v1 / v2);\n}\n\nfloat cbrt(float x) {\n if (x >= 0.0) {\n return pow(x, 1.0 / 3.0);\n } else {\n return -pow(x, 1.0 / 3.0);\n }\n}\n\nfloat expm1(float x) {\n return pow(${Math.E}, x) - 1.0; \n}\n\nfloat fround(highp float x) {\n return x;\n}\n\nfloat imul(float v1, float v2) {\n return float(int(v1) * int(v2));\n}\n\nfloat log10(float x) {\n return log2(x) * (1.0 / log2(10.0));\n}\n\nfloat log1p(float x) {\n return log(1.0 + x);\n}\n\nfloat _pow(float v1, float v2) {\n if (v2 == 0.0) return 1.0;\n return pow(v1, v2);\n}\n\nfloat _round(float x) {\n return floor(x + 0.5);\n}\n\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n\n mantissa = value*pow(2.0, -exponent)-1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nfloat modulo(float number, float divisor) {\n if (number < 0.0) {\n number = abs(number);\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return -mod(number, divisor);\n }\n if (divisor < 0.0) {\n divisor = abs(divisor);\n }\n return mod(number, divisor);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}`;t.exports={fragmentShader:r}},{}],73:[function(e,t,n){const{utils:r}=e("../../utils"),{WebGLFunctionNode:i}=e("../web-gl/function-node");t.exports={WebGL2FunctionNode:class extends i{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e),i=r.sanitizeName(e.name);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(i)>-1?t.push(`bool(user_${i})`):t.push(`user_${i}`),t}}}},{"../../utils":114,"../web-gl/function-node":38}],74:[function(e,t,n){const{WebGL2KernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGL2KernelValueFloat:i}=e("./kernel-value/float"),{WebGL2KernelValueInteger:s}=e("./kernel-value/integer"),{WebGL2KernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGL2KernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGL2KernelValueHTMLImageArray:u}=e("./kernel-value/html-image-array"),{WebGL2KernelValueDynamicHTMLImageArray:l}=e("./kernel-value/dynamic-html-image-array"),{WebGL2KernelValueHTMLVideo:h}=e("./kernel-value/html-video"),{WebGL2KernelValueDynamicHTMLVideo:c}=e("./kernel-value/dynamic-html-video"),{WebGL2KernelValueSingleInput:p}=e("./kernel-value/single-input"),{WebGL2KernelValueDynamicSingleInput:d}=e("./kernel-value/dynamic-single-input"),{WebGL2KernelValueUnsignedInput:m}=e("./kernel-value/unsigned-input"),{WebGL2KernelValueDynamicUnsignedInput:f}=e("./kernel-value/dynamic-unsigned-input"),{WebGL2KernelValueMemoryOptimizedNumberTexture:g}=e("./kernel-value/memory-optimized-number-texture"),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:x}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGL2KernelValueNumberTexture:y}=e("./kernel-value/number-texture"),{WebGL2KernelValueDynamicNumberTexture:b}=e("./kernel-value/dynamic-number-texture"),{WebGL2KernelValueSingleArray:T}=e("./kernel-value/single-array"),{WebGL2KernelValueDynamicSingleArray:v}=e("./kernel-value/dynamic-single-array"),{WebGL2KernelValueSingleArray1DI:S}=e("./kernel-value/single-array1d-i"),{WebGL2KernelValueDynamicSingleArray1DI:A}=e("./kernel-value/dynamic-single-array1d-i"),{WebGL2KernelValueSingleArray2DI:_}=e("./kernel-value/single-array2d-i"),{WebGL2KernelValueDynamicSingleArray2DI:E}=e("./kernel-value/dynamic-single-array2d-i"),{WebGL2KernelValueSingleArray3DI:w}=e("./kernel-value/single-array3d-i"),{WebGL2KernelValueDynamicSingleArray3DI:k}=e("./kernel-value/dynamic-single-array3d-i"),{WebGL2KernelValueArray2:I}=e("./kernel-value/array2"),{WebGL2KernelValueArray3:D}=e("./kernel-value/array3"),{WebGL2KernelValueArray4:C}=e("./kernel-value/array4"),{WebGL2KernelValueUnsignedArray:$}=e("./kernel-value/unsigned-array"),{WebGL2KernelValueDynamicUnsignedArray:L}=e("./kernel-value/dynamic-unsigned-array"),R={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:L,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:f,NumberTexture:b,"ArrayTexture(1)":b,"ArrayTexture(2)":b,"ArrayTexture(3)":b,"ArrayTexture(4)":b,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:c},static:{Boolean:r,Float:i,Integer:s,Array:$,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:m,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:x,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:v,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":k,"Array3D(3)":k,"Array3D(4)":k,Input:d,NumberTexture:b,"ArrayTexture(1)":b,"ArrayTexture(2)":b,"ArrayTexture(3)":b,"ArrayTexture(4)":b,MemoryOptimizedNumberTexture:x,HTMLCanvas:o,OffscreenCanvas:o,HTMLImage:o,ImageBitmap:o,ImageData:o,HTMLImageArray:l,HTMLVideo:c},static:{Boolean:r,Float:i,Integer:s,Array:T,"Array(2)":I,"Array(3)":D,"Array(4)":C,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:g,HTMLCanvas:a,OffscreenCanvas:a,HTMLImage:a,ImageBitmap:a,ImageData:a,HTMLImageArray:u,HTMLVideo:h}}};t.exports={kernelValueMaps:R,lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const i=R[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]}}},{"./kernel-value/array2":75,"./kernel-value/array3":76,"./kernel-value/array4":77,"./kernel-value/boolean":78,"./kernel-value/dynamic-html-image":80,"./kernel-value/dynamic-html-image-array":79,"./kernel-value/dynamic-html-video":81,"./kernel-value/dynamic-memory-optimized-number-texture":82,"./kernel-value/dynamic-number-texture":83,"./kernel-value/dynamic-single-array":84,"./kernel-value/dynamic-single-array1d-i":85,"./kernel-value/dynamic-single-array2d-i":86,"./kernel-value/dynamic-single-array3d-i":87,"./kernel-value/dynamic-single-input":88,"./kernel-value/dynamic-unsigned-array":89,"./kernel-value/dynamic-unsigned-input":90,"./kernel-value/float":91,"./kernel-value/html-image":93,"./kernel-value/html-image-array":92,"./kernel-value/html-video":94,"./kernel-value/integer":95,"./kernel-value/memory-optimized-number-texture":96,"./kernel-value/number-texture":97,"./kernel-value/single-array":98,"./kernel-value/single-array1d-i":99,"./kernel-value/single-array2d-i":100,"./kernel-value/single-array3d-i":101,"./kernel-value/single-input":102,"./kernel-value/unsigned-array":103,"./kernel-value/unsigned-input":104}],75:[function(e,t,n){const{WebGLKernelValueArray2:r}=e("../../web-gl/kernel-value/array2");t.exports={WebGL2KernelValueArray2:class extends r{}}},{"../../web-gl/kernel-value/array2":41}],76:[function(e,t,n){const{WebGLKernelValueArray3:r}=e("../../web-gl/kernel-value/array3");t.exports={WebGL2KernelValueArray3:class extends r{}}},{"../../web-gl/kernel-value/array3":42}],77:[function(e,t,n){const{WebGLKernelValueArray4:r}=e("../../web-gl/kernel-value/array4");t.exports={WebGL2KernelValueArray4:class extends r{}}},{"../../web-gl/kernel-value/array4":43}],78:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("../../web-gl/kernel-value/boolean");t.exports={WebGL2KernelValueBoolean:class extends r{}}},{"../../web-gl/kernel-value/boolean":44}],79:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueHTMLImageArray:i}=e("./html-image-array");t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=e[0];this.checkSize(t,n),this.dimensions=[t,n,e.length],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"./html-image-array":92}],80:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicHTMLImage:i}=e("../../web-gl/kernel-value/dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLImage:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-html-image":45}],81:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueDynamicHTMLImage:i}=e("./dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends i{}}},{"../../../utils":114,"./dynamic-html-image":80}],82:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":47}],83:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-number-texture");t.exports={WebGL2KernelValueDynamicNumberTexture:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-number-texture":48}],84:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray:i}=e("../../web-gl2/kernel-value/single-array");t.exports={WebGL2KernelValueDynamicSingleArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array":98}],85:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray1DI:i}=e("../../web-gl2/kernel-value/single-array1d-i");t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array1d-i":99}],86:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray2DI:i}=e("../../web-gl2/kernel-value/single-array2d-i");t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array2d-i":100}],87:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray3DI:i}=e("../../web-gl2/kernel-value/single-array3d-i");t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-array3d-i":101}],88:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleInput:i}=e("../../web-gl2/kernel-value/single-input");t.exports={WebGL2KernelValueDynamicSingleInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,i]=e.size;this.dimensions=new Int32Array([t||1,n||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0],this.textureSize[1]),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":114,"../../web-gl2/kernel-value/single-input":102}],89:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedArray:i}=e("../../web-gl/kernel-value/dynamic-unsigned-array");t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-array":54}],90:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedInput:i}=e("../../web-gl/kernel-value/dynamic-unsigned-input");t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":114,"../../web-gl/kernel-value/dynamic-unsigned-input":55}],91:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueFloat:i}=e("../../web-gl/kernel-value/float");t.exports={WebGL2KernelValueFloat:class extends i{}}},{"../../../utils":114,"../../web-gl/kernel-value/float":56}],92:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelArray:i}=e("../../web-gl/kernel-value/array");t.exports={WebGL2KernelValueHTMLImageArray:class extends i{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}defineTexture(){const{context:e}=this;e.activeTexture(this.contextHandle),e.bindTexture(e.TEXTURE_2D_ARRAY,this.texture),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D_ARRAY,e.TEXTURE_MIN_FILTER,e.NEAREST)}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let n=0;ni})}"undefined"!=typeof window&&s(window),"undefined"!=typeof self&&s(self),t.exports=r},{"./index":109}],108:[function(e,t,n){const{gpuMock:r}=e("gpu-mock.js"),{utils:i}=e("./utils"),{Kernel:s}=e("./backend/kernel"),{CPUKernel:a}=e("./backend/cpu/kernel"),{HeadlessGLKernel:o}=e("./backend/headless-gl/kernel"),{WebGL2Kernel:u}=e("./backend/web-gl2/kernel"),{WebGLKernel:l}=e("./backend/web-gl/kernel"),{kernelRunShortcut:h}=e("./kernel-run-shortcut"),c=[o,u,l],p=["gpu","cpu"],d={headlessgl:o,webgl2:u,webgl:l};let m=!0;function f(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(i.warnDeprecated("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(i.warnDeprecated("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(i.warnDeprecated("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(i.warnDeprecated("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}t.exports={GPU:class{static disableValidation(){m=!1}static enableValidation(){m=!0}static get isGPUSupported(){return c.some((e=>e.isSupported))}static get isKernelMapSupported(){return c.some((e=>e.isSupported&&e.features.kernelMap))}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return l.isSupported}static get isWebGL2Supported(){return u.isSupported}static get isHeadlessGLSupported(){return o.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return u.isSupported}static get isSinglePrecisionSupported(){return c.some((e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat))}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tt.argumentTypes[e])));const l=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:m,onRequestFallback:u,onRequestSwitchKernel:function t(r,i,a){a.debug&&console.warn("Switching kernels");let o=null;if(a.signature&&!s[a.signature]&&(s[a.signature]=a),a.dynamicOutput)for(let e=r.length-1;e>=0;e--){const t=r[e];"outputPrecisionMismatch"===t.type&&(o=t.needed)}const l=a.constructor,h=l.getArgumentTypes(a,i),c=l.getSignature(a,h),d=s[c];if(d)return d.onActivate(a),d;const f=s[c]=new l(e,{argumentTypes:h,constantTypes:a.constantTypes,graphical:a.graphical,loopMaxIterations:a.loopMaxIterations,constants:a.constants,dynamicOutput:a.dynamicOutput,dynamicArgument:a.dynamicArguments,context:a.context,canvas:a.canvas,output:o||a.output,precision:a.precision,pipeline:a.pipeline,immutable:a.immutable,optimizeFloatMemory:a.optimizeFloatMemory,fixIntegerDivisionAccuracy:a.fixIntegerDivisionAccuracy,functions:a.functions,nativeFunctions:a.nativeFunctions,injectedNative:a.injectedNative,subKernels:a.subKernels,strictIntegers:a.strictIntegers,debug:a.debug,gpu:a.gpu,validate:m,returnType:a.returnType,tactic:a.tactic,onRequestFallback:u,onRequestSwitchKernel:t,texture:a.texture,mappedTextures:a.mappedTextures,drawBuffersMap:a.drawBuffersMap});return f.build.apply(f,i),p.replaceKernel(f),n.push(f),f}},o),c=new this.Kernel(e,l),p=h(c);return this.canvas||(this.canvas=c.canvas),this.context||(this.context=c.context),n.push(c),p}createKernelMap(){let e,t;const n=typeof arguments[arguments.length-2];if("function"===n||"string"===n?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],"dev"!==this.mode&&(!this.Kernel.isSupported||!this.Kernel.features.kernelMap)&&this.mode&&p.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const r=f(t);if(t&&"object"==typeof t.argumentTypes&&(r.argumentTypes=Object.keys(t.argumentTypes).map((e=>t.argumentTypes[e]))),Array.isArray(arguments[0])){r.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');return this.nativeFunctions.push(Object.assign({name:e,source:t},n)),this}injectNative(e){return this.injectedNative=e,this}destroy(){return new Promise(((e,t)=>{this.kernels||e(),setTimeout((()=>{try{for(let e=0;et.kernel[i])),t.__defineSetter__(i,(e=>{t.kernel[i]=e}))))}t.kernel=e}t.exports={kernelRunShortcut:function(e){let t=function(){return e.build.apply(e,arguments),t=function(){let t=e.run.apply(e,arguments);if(e.switchingKernels){const r=e.resetSwitchingKernels(),i=e.onRequestSwitchKernel(r,arguments,e);n.kernel=e=i,t=i.run.apply(i,arguments)}return e.renderKernels?e.renderKernels():e.renderOutput?e.renderOutput():t},t.apply(e,arguments)};const n=function(){return t.apply(e,arguments)};return n.exec=function(){return new Promise(((e,n)=>{try{e(t.apply(this,arguments))}catch(e){n(e)}}))},n.replaceKernel=function(t){i(e=t,n)},i(e,n),n}}},{"./utils":114}],112:[function(e,t,n){const r={name:"math-random-uniformly-distributed",onBeforeRun:e=>{e.setUniform1f("randomSeed1",Math.random()),e.setUniform1f("randomSeed2",Math.random())},functionMatch:"Math.random()",functionReplace:"nrand(vTexCoord)",functionReturnType:"Number",source:"// https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0,1]\nhighp float randomSeedShift = 1.0;\nhighp float slide = 1.0;\nuniform highp float randomSeed1;\nuniform highp float randomSeed2;\n\nhighp float nrand(highp vec2 n) {\n highp float result = fract(sin(dot((n.xy + 1.0) * vec2(randomSeed1 * slide, randomSeed2 * randomSeedShift), vec2(12.9898, 78.233))) * 43758.5453);\n randomSeedShift = result;\n if (randomSeedShift > 0.5) {\n slide += 0.00009; \n } else {\n slide += 0.0009;\n }\n return result;\n}"};t.exports=r},{}],113:[function(e,t,n){t.exports={Texture:class{constructor(e){const{texture:t,size:n,dimensions:r,output:i,context:s,type:a="NumberTexture",kernel:o,internalFormat:u,textureFormat:l}=e;if(!i)throw new Error('settings property "output" required.');if(!s)throw new Error('settings property "context" required.');if(!t)throw new Error('settings property "texture" required.');if(!o)throw new Error('settings property "kernel" required.');this.texture=t,t._refs?t._refs++:t._refs=1,this.size=n,this.dimensions=r,this.output=i,this.context=s,this.kernel=o,this.type=a,this._deleted=!1,this.internalFormat=u,this.textureFormat=l}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}clone(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){throw new Error(`Not implemented on ${this.constructor.name}`)}clear(){throw new Error(`Not implemented on ${this.constructor.name}`)}}}},{}],114:[function(e,t,n){const r=e("acorn"),{Input:i}=e("./input"),{Texture:s}=e("./texture"),a=/function ([^(]*)/,o=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,u=/([^\s,]+)/g,l={systemEndianness:()=>d,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),n=new Uint8Array(e);if(t[0]=3735928559,239===n[0])return"LE";if(222===n[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,"function".length).toLowerCase(),getFunctionNameFromString(e){const t=a.exec(e);return t&&0!==t.length?t[1].trim():null},getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(o,"");let n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(u);return null===n&&(n=[]),n},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&(e.isActiveClone=null,t[n]=l.clone(e[n]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(l.isArray(e))return e.length>0&&"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case s:return e.type;case i:return"Input"}if("nodeName"in e)switch(e.nodeName){case"IMG":case"CANVAS":return"HTMLImage";case"VIDEO":return"HTMLVideo"}else{if(e.hasOwnProperty("type"))return e.type;if("undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return"OffscreenCanvas";if("undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap)return"ImageBitmap";if("undefined"!=typeof ImageData&&e instanceof ImageData)return"ImageData"}return"Unknown"},getKernelTextureSize(e,t){let[n,r,i]=t,s=(n||1)*(r||1)*(i||1);return e.optimizeFloatMemory&&"single"===e.precision&&(n=s=Math.ceil(s/4)),r>1&&n*r===s?new Int32Array([n,r]):l.closestSquareDimensions(s)},closestSquareDimensions(e){const t=Math.sqrt(e);let n=Math.ceil(t),r=Math.floor(t);for(;n*rMath.floor((e+t-1)/t)*t,getDimensions(e,t){let n;if(l.isArray(e)){const t=[];let r=e;for(;l.isArray(r);)t.push(r.length),r=r[0];n=t.reverse()}else if(e instanceof s)n=e.output;else{if(!(e instanceof i))throw new Error(`Unknown dimensions of ${e}`);n=e.size}if(t)for(n=Array.from(n);n.length<3;)n.push(1);return new Int32Array(n)},flatten2dArrayTo(e,t){let n=0;for(let r=0;re.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,n){n?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${n}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},flipPixels:(e,t,n)=>{const r=n/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;se.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;s{const n=new Float32Array(t);let r=0;for(let i=0;i{const r=new Array(n);let i=0;for(let s=0;s{const i=new Array(r);let s=0;for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=new Array(n),i=4*t;for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(e),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const{findDependency:n,thisLookup:i,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=r.parse(e),u=[];let h=0;const c=function e(t){if(Array.isArray(t)){const n=[];for(let r=0;rnull!==e));return r.length<1?"":`${t.kind} ${r.join(",")}`;case"VariableDeclarator":if(t.init.object&&"ThisExpression"===t.init.object.type){return i(t.init.property.name,!0)?`${t.id.name} = ${e(t.init)}`:null}return`${t.id.name} = ${e(t.init)}`;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map((t=>e(t))).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map((t=>e(t))).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(n("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`;if(t.callee.object.name){const r=n(t.callee.object.name,t.callee.property.name);return null===r?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`:(u.push(r),`${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map((t=>e(t))).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`${e(t.expression)}`;case"SequenceExpression":return`(${e(t.expressions)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?i(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map((t=>e(t))).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":return`if (${e(t.test)}) ${e(t.consequent)}`;case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let n=0;n{if("VariableDeclaration"!==e.type)throw new Error('Ast is not of type "VariableDeclaration"');const t=[];for(let n=0;n{const n=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].r}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),r=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].g}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),i=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].b}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),s=e.createKernel((function(e){return 255*e[this.thread.y][this.thread.x].a}),{output:[t.width,t.height],precision:"unsigned",argumentTypes:{a:"HTMLImage"}}),a=[n(t),r(t),i(t),s(t)];return a.rKernel=n,a.gKernel=r,a.bKernel=i,a.aKernel=s,a.gpu=e,a},splitRGBAToCanvases:(e,t,n,r)=>{const i=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});i(t);const s=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});s(t);const a=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});a(t);const o=e.createKernel((function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)}),{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return o(t),[i.canvas,s.canvas,a.canvas,o.canvas]},getMinifySafeName:e=>{try{const t=r.parse(`const value = ${e.toString()}`),{init:n}=t.body[0].declarations[0];return n.body.name||n.body.body[0].argument.name}catch(e){throw new Error("Unrecognized function type. Please use `() => yourFunctionVariableHere` or function() { return yourFunctionVariableHere; }")}},sanitizeName:function(e){return h.test(e)&&(e=e.replace(h,"S_S")),c.test(e)?e=e.replace(c,"U_U"):p.test(e)&&(e=e.replace(p,"u_u")),e}},h=/\$/,c=/__/,p=/_/,d=l.getSystemEndianness();t.exports={utils:l}},{"./input":110,"./texture":113,acorn:1}]},{},[107])(107)})); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c32720ff..c5930873 100644 --- a/yarn.lock +++ b/yarn.lock @@ -561,19 +561,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/agent@npm:^2.0.0": - version: 2.2.2 - resolution: "@npmcli/agent@npm:2.2.2" - dependencies: - agent-base: "npm:^7.1.0" - http-proxy-agent: "npm:^7.0.0" - https-proxy-agent: "npm:^7.0.1" - lru-cache: "npm:^10.0.1" - socks-proxy-agent: "npm:^8.0.3" - checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae - languageName: node - linkType: hard - "@npmcli/agent@npm:^3.0.0": version: 3.0.0 resolution: "@npmcli/agent@npm:3.0.0" @@ -587,15 +574,6 @@ __metadata: languageName: node linkType: hard -"@npmcli/fs@npm:^3.1.0": - version: 3.1.1 - resolution: "@npmcli/fs@npm:3.1.1" - dependencies: - semver: "npm:^7.3.5" - checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 - languageName: node - linkType: hard - "@npmcli/fs@npm:^4.0.0": version: 4.0.0 resolution: "@npmcli/fs@npm:4.0.0" @@ -1274,20 +1252,6 @@ __metadata: languageName: node linkType: hard -"@veehz/gpu.js@npm:^2.16.0": - version: 2.16.0 - resolution: "@veehz/gpu.js@npm:2.16.0" - dependencies: - acorn: "npm:8.14.0" - gl: "npm:8.1.6" - gl-wiretap: "npm:0.6.2" - gpu-mock.js: "github:weagle08/gpu-mock.js" - ordered-read-streams: "npm:^2.0.0" - webgpu: "npm:0.2.9" - checksum: 10c0/1f9aed520f34d871908f7014d1f345838a87d5931232ebc8ca95772b6cb6dc496e19d33199799e1946b1f2225f37dccf5bdc2e83727f27000c2a0c229c9b6833 - languageName: node - linkType: hard - "@volar/language-core@npm:2.4.23, @volar/language-core@npm:~2.4.11": version: 2.4.23 resolution: "@volar/language-core@npm:2.4.23" @@ -1376,20 +1340,6 @@ __metadata: languageName: node linkType: hard -"@webgpu/types@npm:^0.1.54": - version: 0.1.65 - resolution: "@webgpu/types@npm:0.1.65" - checksum: 10c0/cc9de41ae18432f292b5e41b1ef1198d200317fd3af424893a75b861fdcff272083e7cb2d51ba79b4deee4d1e93ecec8063d9e6f87d57c69217b48505971c858 - languageName: node - linkType: hard - -"abbrev@npm:^2.0.0": - version: 2.0.0 - resolution: "abbrev@npm:2.0.0" - checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 - languageName: node - linkType: hard - "abbrev@npm:^3.0.0": version: 3.0.1 resolution: "abbrev@npm:3.0.1" @@ -1415,15 +1365,6 @@ __metadata: languageName: node linkType: hard -"acorn@npm:8.14.0": - version: 8.14.0 - resolution: "acorn@npm:8.14.0" - bin: - acorn: bin/acorn - checksum: 10c0/6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7 - languageName: node - linkType: hard - "acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1": version: 8.15.0 resolution: "acorn@npm:8.15.0" @@ -1440,16 +1381,6 @@ __metadata: languageName: node linkType: hard -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" - dependencies: - clean-stack: "npm:^2.0.0" - indent-string: "npm:^4.0.0" - checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 - languageName: node - linkType: hard - "ajv-draft-04@npm:~1.0.0": version: 1.0.0 resolution: "ajv-draft-04@npm:1.0.0" @@ -1694,18 +1625,6 @@ __metadata: languageName: node linkType: hard -"b4a@npm:^1.6.4": - version: 1.7.3 - resolution: "b4a@npm:1.7.3" - peerDependencies: - react-native-b4a: "*" - peerDependenciesMeta: - react-native-b4a: - optional: true - checksum: 10c0/ac16d186e00fa0d16de1f1a4af413953bc762d50d5a0e382aaa744a13886600313b7293403ad77fc83f6b1489c3fc2610494d1026754a51d1b7cdac2115a7598 - languageName: node - linkType: hard - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -1713,20 +1632,6 @@ __metadata: languageName: node linkType: hard -"bare-events@npm:^2.7.0": - version: 2.7.0 - resolution: "bare-events@npm:2.7.0" - checksum: 10c0/0057d26ee21c60bb304cae689dad343e2b3be2a17af26ec26d995c440b6f2c544aab294276626ced1dac9d35b4c5653d0a076a759190c69e1923dbd3e60f5e99 - languageName: node - linkType: hard - -"base64-js@npm:^1.3.1": - version: 1.5.1 - resolution: "base64-js@npm:1.5.1" - checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf - languageName: node - linkType: hard - "basic-auth@npm:^2.0.1": version: 2.0.1 resolution: "basic-auth@npm:2.0.1" @@ -1743,33 +1648,6 @@ __metadata: languageName: node linkType: hard -"bindings@npm:^1.5.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: "npm:1.0.0" - checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba - languageName: node - linkType: hard - -"bit-twiddle@npm:^1.0.2": - version: 1.0.2 - resolution: "bit-twiddle@npm:1.0.2" - checksum: 10c0/edd86fdaeb27fb5acb9dbde247a71e511ebb6c5406ed645038974203dce8c87ef0359f5d5b60212c2a54d0a52ab16a27c4cc3b1cd4e06256a33881ed77f03d7a - languageName: node - linkType: hard - -"bl@npm:^4.0.3": - version: 4.1.0 - resolution: "bl@npm:4.1.0" - dependencies: - buffer: "npm:^5.5.0" - inherits: "npm:^2.0.4" - readable-stream: "npm:^3.4.0" - checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f - languageName: node - linkType: hard - "brace-expansion@npm:^1.1.7": version: 1.1.12 resolution: "brace-expansion@npm:1.1.12" @@ -1805,36 +1683,6 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.5.0": - version: 5.7.1 - resolution: "buffer@npm:5.7.1" - dependencies: - base64-js: "npm:^1.3.1" - ieee754: "npm:^1.1.13" - checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e - languageName: node - linkType: hard - -"cacache@npm:^18.0.0": - version: 18.0.4 - resolution: "cacache@npm:18.0.4" - dependencies: - "@npmcli/fs": "npm:^3.1.0" - fs-minipass: "npm:^3.0.0" - glob: "npm:^10.2.2" - lru-cache: "npm:^10.0.1" - minipass: "npm:^7.0.3" - minipass-collect: "npm:^2.0.1" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - p-map: "npm:^4.0.0" - ssri: "npm:^10.0.0" - tar: "npm:^6.1.11" - unique-filename: "npm:^3.0.0" - checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f - languageName: node - linkType: hard - "cacache@npm:^19.0.1": version: 19.0.1 resolution: "cacache@npm:19.0.1" @@ -1934,20 +1782,6 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^1.1.1": - version: 1.1.4 - resolution: "chownr@npm:1.1.4" - checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db - languageName: node - linkType: hard - -"chownr@npm:^2.0.0": - version: 2.0.0 - resolution: "chownr@npm:2.0.0" - checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 - languageName: node - linkType: hard - "chownr@npm:^3.0.0": version: 3.0.0 resolution: "chownr@npm:3.0.0" @@ -1955,13 +1789,6 @@ __metadata: languageName: node linkType: hard -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -2034,13 +1861,6 @@ __metadata: languageName: node linkType: hard -"core-util-is@npm:~1.0.0": - version: 1.0.3 - resolution: "core-util-is@npm:1.0.3" - checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 - languageName: node - linkType: hard - "corser@npm:^2.0.1": version: 2.0.1 resolution: "corser@npm:2.0.1" @@ -2141,22 +1961,6 @@ __metadata: languageName: node linkType: hard -"decompress-response@npm:^6.0.0": - version: 6.0.0 - resolution: "decompress-response@npm:6.0.0" - dependencies: - mimic-response: "npm:^3.1.0" - checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e - languageName: node - linkType: hard - -"deep-extend@npm:^0.6.0": - version: 0.6.0 - resolution: "deep-extend@npm:0.6.0" - checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 - languageName: node - linkType: hard - "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -2193,13 +1997,6 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.0": - version: 2.1.1 - resolution: "detect-libc@npm:2.1.1" - checksum: 10c0/97053299c1f68c7c4adf7b78c8d506e1d5f3a3fbc775920aaa0ecf7f8fcc6dfa46338a6ca82fe4500b4a51937def314584265a4ec9d565577485c4496aa7d64e - languageName: node - linkType: hard - "diff@npm:^4.0.1": version: 4.0.2 resolution: "diff@npm:4.0.2" @@ -2264,15 +2061,6 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": - version: 1.4.5 - resolution: "end-of-stream@npm:1.4.5" - dependencies: - once: "npm:^1.4.0" - checksum: 10c0/b0701c92a10b89afb1cb45bf54a5292c6f008d744eb4382fa559d54775ff31617d1d7bc3ef617575f552e24fad2c7c1a1835948c66b3f3a4be0a6c1f35c883d8 - languageName: node - linkType: hard - "entities@npm:^4.4.0, entities@npm:^4.5.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -2697,22 +2485,6 @@ __metadata: languageName: node linkType: hard -"events-universal@npm:^1.0.0": - version: 1.0.1 - resolution: "events-universal@npm:1.0.1" - dependencies: - bare-events: "npm:^2.7.0" - checksum: 10c0/a1d9a5e9f95843650f8ec240dd1221454c110189a9813f32cdf7185759b43f1f964367ac7dca4ebc69150b59043f2d77c7e122b0d03abf7c25477ea5494785a5 - languageName: node - linkType: hard - -"expand-template@npm:^2.0.3": - version: 2.0.3 - resolution: "expand-template@npm:2.0.3" - checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 - languageName: node - linkType: hard - "exponential-backoff@npm:^3.1.1": version: 3.1.2 resolution: "exponential-backoff@npm:3.1.2" @@ -2734,13 +2506,6 @@ __metadata: languageName: node linkType: hard -"fast-fifo@npm:^1.3.2": - version: 1.3.2 - resolution: "fast-fifo@npm:1.3.2" - checksum: 10c0/d53f6f786875e8b0529f784b59b4b05d4b5c31c651710496440006a398389a579c8dbcd2081311478b5bf77f4b0b21de69109c5a4eabea9d8e8783d1eb864e4c - languageName: node - linkType: hard - "fast-glob@npm:^3.3.2": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" @@ -2805,13 +2570,6 @@ __metadata: languageName: node linkType: hard -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519 - languageName: node - linkType: hard - "fill-range@npm:^7.1.1": version: 7.1.1 resolution: "fill-range@npm:7.1.1" @@ -2893,13 +2651,6 @@ __metadata: languageName: node linkType: hard -"fs-constants@npm:^1.0.0": - version: 1.0.0 - resolution: "fs-constants@npm:1.0.0" - checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 - languageName: node - linkType: hard - "fs-extra@npm:~11.3.0": version: 11.3.2 resolution: "fs-extra@npm:11.3.2" @@ -2911,15 +2662,6 @@ __metadata: languageName: node linkType: hard -"fs-minipass@npm:^2.0.0": - version: 2.1.0 - resolution: "fs-minipass@npm:2.1.0" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 - languageName: node - linkType: hard - "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -3041,35 +2783,6 @@ __metadata: languageName: node linkType: hard -"github-from-package@npm:0.0.0": - version: 0.0.0 - resolution: "github-from-package@npm:0.0.0" - checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 - languageName: node - linkType: hard - -"gl-wiretap@npm:0.6.2": - version: 0.6.2 - resolution: "gl-wiretap@npm:0.6.2" - checksum: 10c0/bd705d28d8ea9c71cb2dfcb60e344cf343c4c76dd8267df04f6f9ce527c47a633eacd9b0c0b10daa746a4e526c27578a02a8bcdbfd15b3e7254bb14194283424 - languageName: node - linkType: hard - -"gl@npm:8.1.6": - version: 8.1.6 - resolution: "gl@npm:8.1.6" - dependencies: - bindings: "npm:^1.5.0" - bit-twiddle: "npm:^1.0.2" - glsl-tokenizer: "npm:^2.1.5" - nan: "npm:^2.22.0" - node-abi: "npm:^3.71.0" - node-gyp: "npm:^10.2.0" - prebuild-install: "npm:^7.1.2" - checksum: 10c0/4df83359eaf26bd55e319673733806ff7e338317a88846ce3b360e726cf0310b71a40bffa29f47c0ee03a40cb8001aab7a1b74b416e7c5d0c3f35107baf77377 - languageName: node - linkType: hard - "glob-parent@npm:^5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -3088,7 +2801,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.4.5": +"glob@npm:^10.2.2, glob@npm:^10.4.5": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -3137,15 +2850,6 @@ __metadata: languageName: node linkType: hard -"glsl-tokenizer@npm:^2.1.5": - version: 2.1.5 - resolution: "glsl-tokenizer@npm:2.1.5" - dependencies: - through2: "npm:^0.6.3" - checksum: 10c0/5bcc4491afb0b09032702af83f0afa8acadfa0f5c94a7a0d7c3498396cc35722e1915c976c8efef80a1a9ef0976ecb8ce4e044a34b16d7d537ae4c80f346ad19 - languageName: node - linkType: hard - "gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" @@ -3153,13 +2857,6 @@ __metadata: languageName: node linkType: hard -"gpu-mock.js@github:weagle08/gpu-mock.js": - version: 1.3.1 - resolution: "gpu-mock.js@https://github.com/weagle08/gpu-mock.js.git#commit=7f3d7a75d29e34c5098d6102fce006c53b5df50d" - checksum: 10c0/dcf15092047ce622701b10ebe3088afcb3be9d59142d82f8e79ec3e82a0b797a8fe24b48515ac615106e3b7d3d5b048afcac62cf9a9a896c5919d47bfedf17fa - languageName: node - linkType: hard - "graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -3319,13 +3016,6 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13": - version: 1.2.1 - resolution: "ieee754@npm:1.2.1" - checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb - languageName: node - linkType: hard - "ignore@npm:^5.2.0, ignore@npm:^5.3.1": version: 5.3.2 resolution: "ignore@npm:5.3.2" @@ -3364,27 +3054,6 @@ __metadata: languageName: node linkType: hard -"indent-string@npm:^4.0.0": - version: 4.0.0 - resolution: "indent-string@npm:4.0.0" - checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f - languageName: node - linkType: hard - -"inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 - languageName: node - linkType: hard - -"ini@npm:~1.3.0": - version: 1.3.8 - resolution: "ini@npm:1.3.8" - checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a - languageName: node - linkType: hard - "internal-slot@npm:^1.1.0": version: 1.1.0 resolution: "internal-slot@npm:1.1.0" @@ -3528,13 +3197,6 @@ __metadata: languageName: node linkType: hard -"is-lambda@npm:^1.0.1": - version: 1.0.1 - resolution: "is-lambda@npm:1.0.1" - checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d - languageName: node - linkType: hard - "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -3671,13 +3333,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:0.0.1": - version: 0.0.1 - resolution: "isarray@npm:0.0.1" - checksum: 10c0/ed1e62da617f71fe348907c71743b5ed550448b455f8d269f89a7c7ddb8ae6e962de3dab6a74a237b06f5eb7f6ece7a45ada8ce96d87fe972926530f91ae3311 - languageName: node - linkType: hard - "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -3923,26 +3578,6 @@ __metadata: languageName: node linkType: hard -"make-fetch-happen@npm:^13.0.0": - version: 13.0.1 - resolution: "make-fetch-happen@npm:13.0.1" - dependencies: - "@npmcli/agent": "npm:^2.0.0" - cacache: "npm:^18.0.0" - http-cache-semantics: "npm:^4.1.1" - is-lambda: "npm:^1.0.1" - minipass: "npm:^7.0.2" - minipass-fetch: "npm:^3.0.0" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - negotiator: "npm:^0.6.3" - proc-log: "npm:^4.2.0" - promise-retry: "npm:^2.0.1" - ssri: "npm:^10.0.0" - checksum: 10c0/df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e - languageName: node - linkType: hard - "make-fetch-happen@npm:^14.0.3": version: 14.0.3 resolution: "make-fetch-happen@npm:14.0.3" @@ -4018,13 +3653,6 @@ __metadata: languageName: node linkType: hard -"mimic-response@npm:^3.1.0": - version: 3.1.0 - resolution: "mimic-response@npm:3.1.0" - checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 - languageName: node - linkType: hard - "minimatch@npm:10.0.3, minimatch@npm:^10.0.3": version: 10.0.3 resolution: "minimatch@npm:10.0.3" @@ -4052,7 +3680,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6": +"minimist@npm:^1.2.0, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -4068,21 +3696,6 @@ __metadata: languageName: node linkType: hard -"minipass-fetch@npm:^3.0.0": - version: 3.0.5 - resolution: "minipass-fetch@npm:3.0.5" - dependencies: - encoding: "npm:^0.1.13" - minipass: "npm:^7.0.3" - minipass-sized: "npm:^1.0.3" - minizlib: "npm:^2.1.2" - dependenciesMeta: - encoding: - optional: true - checksum: 10c0/9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b - languageName: node - linkType: hard - "minipass-fetch@npm:^4.0.0": version: 4.0.1 resolution: "minipass-fetch@npm:4.0.1" @@ -4134,13 +3747,6 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0": - version: 5.0.0 - resolution: "minipass@npm:5.0.0" - checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 - languageName: node - linkType: hard - "minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" @@ -4148,16 +3754,6 @@ __metadata: languageName: node linkType: hard -"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": - version: 2.1.2 - resolution: "minizlib@npm:2.1.2" - dependencies: - minipass: "npm:^3.0.0" - yallist: "npm:^4.0.0" - checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 - languageName: node - linkType: hard - "minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": version: 3.1.0 resolution: "minizlib@npm:3.1.0" @@ -4167,22 +3763,6 @@ __metadata: languageName: node linkType: hard -"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": - version: 0.5.3 - resolution: "mkdirp-classic@npm:0.5.3" - checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 - languageName: node - linkType: hard - -"mkdirp@npm:^1.0.3": - version: 1.0.4 - resolution: "mkdirp@npm:1.0.4" - bin: - mkdirp: bin/cmd.js - checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf - languageName: node - linkType: hard - "mlly@npm:^1.7.4": version: 1.8.0 resolution: "mlly@npm:1.8.0" @@ -4241,15 +3821,6 @@ __metadata: languageName: node linkType: hard -"nan@npm:^2.22.0": - version: 2.23.0 - resolution: "nan@npm:2.23.0" - dependencies: - node-gyp: "npm:latest" - checksum: 10c0/b986dd257dca53ab43a3b6ca6d0eafde697b69e1d63b242fa4aece50ce97eb169f9c4a5d8eb0eb5f58d118a9595fee11f3198fa210f023440053bb6f54109e73 - languageName: node - linkType: hard - "nanoid@npm:^3.3.11": version: 3.3.11 resolution: "nanoid@npm:3.3.11" @@ -4259,13 +3830,6 @@ __metadata: languageName: node linkType: hard -"napi-build-utils@npm:^2.0.0": - version: 2.0.0 - resolution: "napi-build-utils@npm:2.0.0" - checksum: 10c0/5833aaeb5cc5c173da47a102efa4680a95842c13e0d9cc70428bd3ee8d96bb2172f8860d2811799b5daa5cbeda779933601492a2028a6a5351c6d0fcf6de83db - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -4273,13 +3837,6 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:^0.6.3": - version: 0.6.4 - resolution: "negotiator@npm:0.6.4" - checksum: 10c0/3e677139c7fb7628a6f36335bf11a885a62c21d5390204590a1a214a5631fcbe5ea74ef6a610b60afe84b4d975cbe0566a23f20ee17c77c73e74b80032108dea - languageName: node - linkType: hard - "negotiator@npm:^1.0.0": version: 1.0.0 resolution: "negotiator@npm:1.0.0" @@ -4287,35 +3844,6 @@ __metadata: languageName: node linkType: hard -"node-abi@npm:^3.3.0, node-abi@npm:^3.71.0": - version: 3.77.0 - resolution: "node-abi@npm:3.77.0" - dependencies: - semver: "npm:^7.3.5" - checksum: 10c0/3354289ccca052538f653968ead73d00785e5ab159ce3a575dbff465724dac749821e7c327ae6c4774f29994f94c402fbafc8799b172aabf4aa8a082a070b00a - languageName: node - linkType: hard - -"node-gyp@npm:^10.2.0": - version: 10.3.1 - resolution: "node-gyp@npm:10.3.1" - dependencies: - env-paths: "npm:^2.2.0" - exponential-backoff: "npm:^3.1.1" - glob: "npm:^10.3.10" - graceful-fs: "npm:^4.2.6" - make-fetch-happen: "npm:^13.0.0" - nopt: "npm:^7.0.0" - proc-log: "npm:^4.1.0" - semver: "npm:^7.3.5" - tar: "npm:^6.2.1" - which: "npm:^4.0.0" - bin: - node-gyp: bin/node-gyp.js - checksum: 10c0/87c3b50e1f6f5256b5d2879a8c064eefa53ed444bad2a20870be43bc189db7cbffe22c30af056046c6d904181d73881b1726fd391d2f6f79f89b991019f195ea - languageName: node - linkType: hard - "node-gyp@npm:latest": version: 11.4.2 resolution: "node-gyp@npm:11.4.2" @@ -4336,17 +3864,6 @@ __metadata: languageName: node linkType: hard -"nopt@npm:^7.0.0": - version: 7.2.1 - resolution: "nopt@npm:7.2.1" - dependencies: - abbrev: "npm:^2.0.0" - bin: - nopt: bin/nopt.js - checksum: 10c0/a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81 - languageName: node - linkType: hard - "nopt@npm:^8.0.0": version: 8.1.0 resolution: "nopt@npm:8.1.0" @@ -4421,7 +3938,7 @@ __metadata: languageName: node linkType: hard -"once@npm:^1.3.1, once@npm:^1.4.0": +"once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" dependencies: @@ -4453,15 +3970,6 @@ __metadata: languageName: node linkType: hard -"ordered-read-streams@npm:^2.0.0": - version: 2.0.0 - resolution: "ordered-read-streams@npm:2.0.0" - dependencies: - streamx: "npm:^2.12.5" - checksum: 10c0/4fa598c43cd2f6e9d49b8455955f0a2c29adff08ae3f982383439fd6a85700d8769c74b9ef88da52c6a1a1e73ae9601ea43afd039b9be37249600f4b8ada16c5 - languageName: node - linkType: hard - "own-keys@npm:^1.0.1": version: 1.0.1 resolution: "own-keys@npm:1.0.1" @@ -4491,15 +3999,6 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: "npm:^3.0.0" - checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 - languageName: node - linkType: hard - "p-map@npm:^7.0.2": version: 7.0.3 resolution: "p-map@npm:7.0.3" @@ -4667,28 +4166,6 @@ __metadata: languageName: node linkType: hard -"prebuild-install@npm:^7.1.2": - version: 7.1.3 - resolution: "prebuild-install@npm:7.1.3" - dependencies: - detect-libc: "npm:^2.0.0" - expand-template: "npm:^2.0.3" - github-from-package: "npm:0.0.0" - minimist: "npm:^1.2.3" - mkdirp-classic: "npm:^0.5.3" - napi-build-utils: "npm:^2.0.0" - node-abi: "npm:^3.3.0" - pump: "npm:^3.0.0" - rc: "npm:^1.2.7" - simple-get: "npm:^4.0.0" - tar-fs: "npm:^2.0.0" - tunnel-agent: "npm:^0.6.0" - bin: - prebuild-install: bin.js - checksum: 10c0/25919a42b52734606a4036ab492d37cfe8b601273d8dfb1fa3c84e141a0a475e7bad3ab848c741d2f810cef892fcf6059b8c7fe5b29f98d30e0c29ad009bedff - languageName: node - linkType: hard - "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -4705,13 +4182,6 @@ __metadata: languageName: node linkType: hard -"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": - version: 4.2.0 - resolution: "proc-log@npm:4.2.0" - checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 - languageName: node - linkType: hard - "proc-log@npm:^5.0.0": version: 5.0.0 resolution: "proc-log@npm:5.0.0" @@ -4729,16 +4199,6 @@ __metadata: languageName: node linkType: hard -"pump@npm:^3.0.0": - version: 3.0.3 - resolution: "pump@npm:3.0.3" - dependencies: - end-of-stream: "npm:^1.1.0" - once: "npm:^1.3.1" - checksum: 10c0/ada5cdf1d813065bbc99aa2c393b8f6beee73b5de2890a8754c9f488d7323ffd2ca5f5a0943b48934e3fcbd97637d0337369c3c631aeb9614915db629f1c75c9 - languageName: node - linkType: hard - "punycode.js@npm:^2.3.1": version: 2.3.1 resolution: "punycode.js@npm:2.3.1" @@ -4817,43 +4277,6 @@ __metadata: languageName: node linkType: hard -"rc@npm:^1.2.7": - version: 1.2.8 - resolution: "rc@npm:1.2.8" - dependencies: - deep-extend: "npm:^0.6.0" - ini: "npm:~1.3.0" - minimist: "npm:^1.2.0" - strip-json-comments: "npm:~2.0.1" - bin: - rc: ./cli.js - checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 - languageName: node - linkType: hard - -"readable-stream@npm:>=1.0.33-1 <1.1.0-0": - version: 1.0.34 - resolution: "readable-stream@npm:1.0.34" - dependencies: - core-util-is: "npm:~1.0.0" - inherits: "npm:~2.0.1" - isarray: "npm:0.0.1" - string_decoder: "npm:~0.10.x" - checksum: 10c0/02272551396ed8930ddee1a088bdf0379f0f7cc47ac49ed8804e998076cb7daec9fbd2b1fd9c0490ec72e56e8bb3651abeb8080492b8e0a9c3f2158330908ed6 - languageName: node - linkType: hard - -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": - version: 3.6.2 - resolution: "readable-stream@npm:3.6.2" - dependencies: - inherits: "npm:^2.0.3" - string_decoder: "npm:^1.1.1" - util-deprecate: "npm:^1.0.1" - checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 - languageName: node - linkType: hard - "readdirp@npm:^4.0.1": version: 4.1.2 resolution: "readdirp@npm:4.1.2" @@ -5097,7 +4520,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.1.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 @@ -5301,24 +4724,6 @@ __metadata: languageName: node linkType: hard -"simple-concat@npm:^1.0.0": - version: 1.0.1 - resolution: "simple-concat@npm:1.0.1" - checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 - languageName: node - linkType: hard - -"simple-get@npm:^4.0.0": - version: 4.0.1 - resolution: "simple-get@npm:4.0.1" - dependencies: - decompress-response: "npm:^6.0.0" - once: "npm:^1.3.1" - simple-concat: "npm:^1.0.0" - checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 - languageName: node - linkType: hard - "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -5375,15 +4780,6 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^10.0.0": - version: 10.0.6 - resolution: "ssri@npm:10.0.6" - dependencies: - minipass: "npm:^7.0.3" - checksum: 10c0/e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227 - languageName: node - linkType: hard - "ssri@npm:^12.0.0": version: 12.0.0 resolution: "ssri@npm:12.0.0" @@ -5403,17 +4799,6 @@ __metadata: languageName: node linkType: hard -"streamx@npm:^2.12.5": - version: 2.23.0 - resolution: "streamx@npm:2.23.0" - dependencies: - events-universal: "npm:^1.0.0" - fast-fifo: "npm:^1.3.2" - text-decoder: "npm:^1.1.0" - checksum: 10c0/15708ce37818d588632fe1104e8febde573e33e8c0868bf583fce0703f3faf8d2a063c278e30df2270206811b69997f64eb78792099933a1fe757e786fbcbd44 - languageName: node - linkType: hard - "string-argv@npm:^0.3.1, string-argv@npm:~0.3.1": version: 0.3.2 resolution: "string-argv@npm:0.3.2" @@ -5481,22 +4866,6 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1": - version: 1.3.0 - resolution: "string_decoder@npm:1.3.0" - dependencies: - safe-buffer: "npm:~5.2.0" - checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d - languageName: node - linkType: hard - -"string_decoder@npm:~0.10.x": - version: 0.10.31 - resolution: "string_decoder@npm:0.10.31" - checksum: 10c0/1c628d78f974aa7539c496029f48e7019acc32487fc695464f9d6bdfec98edd7d933a06b3216bc2016918f6e75074c611d84430a53cb0e43071597d6c1ac5e25 - languageName: node - linkType: hard - "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -5529,13 +4898,6 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:~2.0.1": - version: 2.0.1 - resolution: "strip-json-comments@npm:2.0.1" - checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 - languageName: node - linkType: hard - "supports-color@npm:8.1.1, supports-color@npm:^8.1.1, supports-color@npm:~8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" @@ -5561,45 +4923,6 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^2.0.0": - version: 2.1.4 - resolution: "tar-fs@npm:2.1.4" - dependencies: - chownr: "npm:^1.1.1" - mkdirp-classic: "npm:^0.5.2" - pump: "npm:^3.0.0" - tar-stream: "npm:^2.1.4" - checksum: 10c0/decb25acdc6839182c06ec83cba6136205bda1db984e120c8ffd0d80182bc5baa1d916f9b6c5c663ea3f9975b4dd49e3c6bb7b1707cbcdaba4e76042f43ec84c - languageName: node - linkType: hard - -"tar-stream@npm:^2.1.4": - version: 2.2.0 - resolution: "tar-stream@npm:2.2.0" - dependencies: - bl: "npm:^4.0.3" - end-of-stream: "npm:^1.4.1" - fs-constants: "npm:^1.0.0" - inherits: "npm:^2.0.3" - readable-stream: "npm:^3.1.1" - checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 - languageName: node - linkType: hard - -"tar@npm:^6.1.11, tar@npm:^6.2.1": - version: 6.2.1 - resolution: "tar@npm:6.2.1" - dependencies: - chownr: "npm:^2.0.0" - fs-minipass: "npm:^2.0.0" - minipass: "npm:^5.0.0" - minizlib: "npm:^2.1.1" - mkdirp: "npm:^1.0.3" - yallist: "npm:^4.0.0" - checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 - languageName: node - linkType: hard - "tar@npm:^7.4.3": version: 7.5.1 resolution: "tar@npm:7.5.1" @@ -5613,25 +4936,6 @@ __metadata: languageName: node linkType: hard -"text-decoder@npm:^1.1.0": - version: 1.2.3 - resolution: "text-decoder@npm:1.2.3" - dependencies: - b4a: "npm:^1.6.4" - checksum: 10c0/569d776b9250158681c83656ef2c3e0a5d5c660c27ca69f87eedef921749a4fbf02095e5f9a0f862a25cf35258379b06e31dee9c125c9f72e273b7ca1a6d1977 - languageName: node - linkType: hard - -"through2@npm:^0.6.3": - version: 0.6.5 - resolution: "through2@npm:0.6.5" - dependencies: - readable-stream: "npm:>=1.0.33-1 <1.1.0-0" - xtend: "npm:>=4.0.0 <4.1.0-0" - checksum: 10c0/3294325d73b120ffbb8cd00e28a649a99e194cef2638bf782b6c2eb0c163b388f7b7bb908003949f58f9f6b8f771defd24b6e4df051eb410fd87931521963b98 - languageName: node - linkType: hard - "tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15, tinyglobby@npm:^0.2.9": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" @@ -5658,7 +4962,6 @@ __metadata: "@eslint/js": "npm:^9.37.0" "@types/mocha": "npm:^10.0.10" "@types/node": "npm:^24.6.2" - "@veehz/gpu.js": "npm:^2.16.0" chai: "npm:^6.2.0" concurrently: "npm:^9.2.1" eslint: "npm:^9.37.0" @@ -5769,15 +5072,6 @@ __metadata: languageName: node linkType: hard -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: "npm:^5.0.1" - checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a - languageName: node - linkType: hard - "tunnel@npm:^0.0.6": version: 0.0.6 resolution: "tunnel@npm:0.0.6" @@ -5984,15 +5278,6 @@ __metadata: languageName: node linkType: hard -"unique-filename@npm:^3.0.0": - version: 3.0.0 - resolution: "unique-filename@npm:3.0.0" - dependencies: - unique-slug: "npm:^4.0.0" - checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f - languageName: node - linkType: hard - "unique-filename@npm:^4.0.0": version: 4.0.0 resolution: "unique-filename@npm:4.0.0" @@ -6002,15 +5287,6 @@ __metadata: languageName: node linkType: hard -"unique-slug@npm:^4.0.0": - version: 4.0.0 - resolution: "unique-slug@npm:4.0.0" - dependencies: - imurmurhash: "npm:^0.1.4" - checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 - languageName: node - linkType: hard - "unique-slug@npm:^5.0.0": version: 5.0.0 resolution: "unique-slug@npm:5.0.0" @@ -6057,13 +5333,6 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1": - version: 1.0.2 - resolution: "util-deprecate@npm:1.0.2" - checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 - languageName: node - linkType: hard - "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -6163,15 +5432,6 @@ __metadata: languageName: node linkType: hard -"webgpu@npm:0.2.9": - version: 0.2.9 - resolution: "webgpu@npm:0.2.9" - dependencies: - "@webgpu/types": "npm:^0.1.54" - checksum: 10c0/048e31afd7ac7b720aec50cf6cb1cfc4921e35d68f8c4031cf7b38764c4b9bdeca4b6be62a8e439ceb277c7cf3daa0bfb5539c3e93431f0b67c37daf706e9a96 - languageName: node - linkType: hard - "whatwg-encoding@npm:^2.0.0": version: 2.0.0 resolution: "whatwg-encoding@npm:2.0.0" @@ -6253,17 +5513,6 @@ __metadata: languageName: node linkType: hard -"which@npm:^4.0.0": - version: 4.0.0 - resolution: "which@npm:4.0.0" - dependencies: - isexe: "npm:^3.1.1" - bin: - node-which: bin/which.js - checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a - languageName: node - linkType: hard - "which@npm:^5.0.0": version: 5.0.0 resolution: "which@npm:5.0.0" @@ -6318,13 +5567,6 @@ __metadata: languageName: node linkType: hard -"xtend@npm:>=4.0.0 <4.1.0-0": - version: 4.0.2 - resolution: "xtend@npm:4.0.2" - checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e - languageName: node - linkType: hard - "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From e1e792b3b4e7e5aa01661231af1f7d61bf28be57 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 6 Feb 2026 18:14:32 +0800 Subject: [PATCH 056/128] feat: event emitters for backpropagation --- scripts/macros.ts.j2 | 18 ++--- src/index.ts | 2 +- src/nn/ops.gen.ts | 12 +-- src/operations/base.ts | 25 ++++-- src/operations/ops.gen.ts | 158 +++++++++++++++++++------------------- src/operations/ops.ts.j2 | 8 +- 6 files changed, 118 insertions(+), 105 deletions(-) diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2 index 93ec90ce..52a447da 100644 --- a/scripts/macros.ts.j2 +++ b/scripts/macros.ts.j2 @@ -34,7 +34,7 @@ function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = const _{{ name }}_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = {{ operation }}; } return res; @@ -56,13 +56,13 @@ function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tens // class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations) export class {{ classname }} extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -76,13 +76,13 @@ registerOperation('{{ opname }}', {{ classname }}); // class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations) export class {{ classname }} extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _{{ opname }}_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -109,14 +109,14 @@ function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null {% macro powint_op_class() -%} export class PowInt extends Operation { private cache: [Tensor, number]; - public forward(a: Tensor, n: number): Tensor { + protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { this.cache = [a, n]; } return _powint_tensor(a, n, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, n] = this.cache; // backward_operations: @@ -177,11 +177,11 @@ function _transpose_tensor( {% macro transpose_op_class() -%} export class Transpose extends Operation { cache: [Tensor, number, number]; - forward(a: Tensor, dim0: number, dim1: number): Tensor { + protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { this.cache = [a, dim0, dim1]; return _transpose_tensor(a, dim0, dim1, this); } - backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, dim0, dim1] = this.cache; // backward_operations: diff --git a/src/index.ts b/src/index.ts index 25eb2aad..899e1409 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import { Tensor } from './tensor'; export * from './operations/ops.gen'; -export { Operation } from './operations/base'; +export { Operation, opBus } from './operations/base'; export * from './operations/functional'; export * from './creation/index'; export * as nn from './nn/index'; diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts index 5d90e5fa..0d02bc47 100644 --- a/src/nn/ops.gen.ts +++ b/src/nn/ops.gen.ts @@ -13,7 +13,7 @@ import { registerOperation } from '../operations/registry'; const _relu_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.max(a[x], 0); } return res; @@ -32,13 +32,13 @@ function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Relu", "relu", backward_operations) export class Relu extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _relu_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -51,7 +51,7 @@ registerOperation('relu', Relu); const _sigmoid_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = 1 / (1 + Math.exp(-a[x])); } return res; @@ -70,13 +70,13 @@ function _sigmoid_tensor(a: Tensor, operation: Operation | null = null): Tensor // class generated from unary_op_class("Sigmoid", "sigmoid", backward_operations) export class Sigmoid extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _sigmoid_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: diff --git a/src/operations/base.ts b/src/operations/base.ts index 2d249466..b12d866c 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -1,18 +1,31 @@ import { Tensor } from '../tensor'; +export const opBus = new EventTarget(); + abstract class Operation { - abstract forward(...args: (Tensor | number | number[])[]): Tensor; - abstract backward(dz: Tensor): void; + protected abstract _forward(...args: (Tensor | number | number[])[]): Tensor; + protected abstract _backward(dz: Tensor): void; + + forward(...args: (Tensor | number | number[])[]): Tensor { + const result = this._forward(...args); + opBus.dispatchEvent(new CustomEvent('forward', { detail: { operation: this, args, result } })); + return result; + } + + backward(dz: Tensor): void { + opBus.dispatchEvent(new CustomEvent('backward', { detail: { operation: this, dz } })); + this._backward(dz); + } } abstract class UnaryOperation extends Operation { - abstract forward(a: Tensor): Tensor; - abstract backward(dz: Tensor): void; + protected abstract _forward(a: Tensor): Tensor; + protected abstract _backward(dz: Tensor): void; } abstract class BinaryOperation extends Operation { - abstract forward(a: Tensor, b: Tensor): Tensor; - abstract backward(dz: Tensor): void; + protected abstract _forward(a: Tensor, b: Tensor): Tensor; + protected abstract _backward(dz: Tensor): void; } export type OperationConstructor = new () => Operation; diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts index 3e0ad894..de4820f4 100644 --- a/src/operations/ops.gen.ts +++ b/src/operations/ops.gen.ts @@ -41,13 +41,13 @@ function ___left_index___tensor(a: Tensor, b: Tensor, operation: Operation | nul // class generated from binary_op_class("__Left_index__", "__left_index__", backward_operations) export class __Left_index__ extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return ___left_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -83,13 +83,13 @@ function ___right_index___tensor(a: Tensor, b: Tensor, operation: Operation | nu // class generated from binary_op_class("__Right_index__", "__right_index__", backward_operations) export class __Right_index__ extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return ___right_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -127,13 +127,13 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): // class generated from binary_op_class("Add", "add", backward_operations) export class Add extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _add_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -170,13 +170,13 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): // class generated from binary_op_class("Sub", "sub", backward_operations) export class Sub extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _sub_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -213,13 +213,13 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): // class generated from binary_op_class("Mul", "mul", backward_operations) export class Mul extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _mul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -256,13 +256,13 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): // class generated from binary_op_class("Div", "div", backward_operations) export class Div extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _div_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -299,13 +299,13 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): // class generated from binary_op_class("Pow", "pow", backward_operations) export class Pow extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _pow_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -342,13 +342,13 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): // class generated from binary_op_class("Fmod", "fmod", backward_operations) export class Fmod extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _fmod_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -384,13 +384,13 @@ function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul // class generated from binary_op_class("Maximum", "maximum", backward_operations) export class Maximum extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _maximum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -427,13 +427,13 @@ function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul // class generated from binary_op_class("Minimum", "minimum", backward_operations) export class Minimum extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _minimum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -457,14 +457,14 @@ function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null } export class PowInt extends Operation { private cache: [Tensor, number]; - public forward(a: Tensor, n: number): Tensor { + protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { this.cache = [a, n]; } return _powint_tensor(a, n, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, n] = this.cache; // backward_operations: @@ -479,7 +479,7 @@ registerOperation('powint', PowInt); const _log_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.log(a[x]); } return res; @@ -498,13 +498,13 @@ function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Log", "log", backward_operations) export class Log extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _log_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -517,7 +517,7 @@ registerOperation('log', Log); const _sqrt_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.sqrt(a[x]); } return res; @@ -536,13 +536,13 @@ function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Sqrt", "sqrt", backward_operations) export class Sqrt extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _sqrt_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -555,7 +555,7 @@ registerOperation('sqrt', Sqrt); const _exp_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.exp(a[x]); } return res; @@ -574,13 +574,13 @@ function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Exp", "exp", backward_operations) export class Exp extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _exp_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -593,7 +593,7 @@ registerOperation('exp', Exp); const _square_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = a[x] * a[x]; } return res; @@ -612,13 +612,13 @@ function _square_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Square", "square", backward_operations) export class Square extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _square_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -631,7 +631,7 @@ registerOperation('square', Square); const _abs_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.abs(a[x]); } return res; @@ -650,13 +650,13 @@ function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Abs", "abs", backward_operations) export class Abs extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _abs_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -669,7 +669,7 @@ registerOperation('abs', Abs); const _sign_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.sign(a[x]); } return res; @@ -688,13 +688,13 @@ function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Sign", "sign", backward_operations) export class Sign extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _sign_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -707,7 +707,7 @@ registerOperation('sign', Sign); const _neg_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = -a[x]; } return res; @@ -726,13 +726,13 @@ function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Neg", "neg", backward_operations) export class Neg extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _neg_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -745,7 +745,7 @@ registerOperation('neg', Neg); const _reciprocal_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = 1 / a[x]; } return res; @@ -764,13 +764,13 @@ function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tens // class generated from unary_op_class("Reciprocal", "reciprocal", backward_operations) export class Reciprocal extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _reciprocal_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -781,7 +781,7 @@ registerOperation('reciprocal', Reciprocal); export class Reshape extends Operation { private cache: [Tensor]; - public forward(a: Tensor, shape: number[]) { + protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -799,7 +799,7 @@ export class Reshape extends Operation { { operation: a.requires_grad ? this : null, shape } ); } - public backward(dz: Tensor) { + protected _backward(dz: Tensor) { const [a] = this.cache; // backward_operations: @@ -810,7 +810,7 @@ registerOperation('reshape', Reshape); export class Unsqueeze extends Operation { private cache: [Tensor]; - public forward(a: Tensor, dim: number) { + protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { this.cache = [a]; } @@ -828,7 +828,7 @@ export class Unsqueeze extends Operation { { operation: a.requires_grad ? this : null, shape } ); } - public backward(dz: Tensor) { + protected _backward(dz: Tensor) { const [a] = this.cache; // backward_operations: @@ -843,7 +843,7 @@ registerOperation('unsqueeze', Unsqueeze); const _sin_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.sin(a[x]); } return res; @@ -862,13 +862,13 @@ function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Sin", "sin", backward_operations) export class Sin extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _sin_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -881,7 +881,7 @@ registerOperation('sin', Sin); const _cos_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.cos(a[x]); } return res; @@ -900,13 +900,13 @@ function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Cos", "cos", backward_operations) export class Cos extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _cos_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -919,7 +919,7 @@ registerOperation('cos', Cos); const _tan_kernel = function (a: number[], output: number) { const res = new Array(output); - for(let x = 0; x < output; x++) { + for (let x = 0; x < output; x++) { res[x] = Math.tan(a[x]); } return res; @@ -938,13 +938,13 @@ function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Tan", "tan", backward_operations) export class Tan extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _tan_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -966,13 +966,13 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Sum", "sum", backward_operations) export class Sum extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _sum_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -993,13 +993,13 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Mean", "mean", backward_operations) export class Mean extends UnaryOperation { private cache: [Tensor]; - public forward(a: Tensor): Tensor { + protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.cache = [a]; } return _mean_tensor(a, a.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a] = this.cache; // backward_operations: @@ -1058,11 +1058,11 @@ function _transpose_tensor( } export class Transpose extends Operation { cache: [Tensor, number, number]; - forward(a: Tensor, dim0: number, dim1: number): Tensor { + protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { this.cache = [a, dim0, dim1]; return _transpose_tensor(a, dim0, dim1, this); } - backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, dim0, dim1] = this.cache; // backward_operations: @@ -1137,13 +1137,13 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null // class generated from binary_op_class("Matmul", "matmul", backward_operations) export class Matmul extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -1181,13 +1181,13 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T // class generated from binary_op_class("Lt", "lt", backward_operations) export class Lt extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _lt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -1223,13 +1223,13 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T // class generated from binary_op_class("Gt", "gt", backward_operations) export class Gt extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _gt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -1265,13 +1265,13 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T // class generated from binary_op_class("Le", "le", backward_operations) export class Le extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _le_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -1307,13 +1307,13 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T // class generated from binary_op_class("Ge", "ge", backward_operations) export class Ge extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _ge_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -1349,13 +1349,13 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T // class generated from binary_op_class("Eq", "eq", backward_operations) export class Eq extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _eq_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: @@ -1391,13 +1391,13 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T // class generated from binary_op_class("Ne", "ne", backward_operations) export class Ne extends BinaryOperation { private cache: [Tensor, Tensor]; - public forward(a: Tensor, b: Tensor): Tensor { + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.cache = [a, b]; } return _ne_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - public backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.cache; // backward_operations: diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2 index 589962d9..f7a078d2 100644 --- a/src/operations/ops.ts.j2 +++ b/src/operations/ops.ts.j2 @@ -80,7 +80,7 @@ import { registerOperation } from './registry'; export class Reshape extends Operation { private cache: [Tensor]; - public forward(a: Tensor, shape: number[]) { + protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -98,7 +98,7 @@ export class Reshape extends Operation { { operation: a.requires_grad ? this : null, shape } ); } - public backward(dz: Tensor) { + protected _backward(dz: Tensor) { const [a] = this.cache; // backward_operations: @@ -109,7 +109,7 @@ registerOperation('reshape', Reshape); export class Unsqueeze extends Operation { private cache: [Tensor]; - public forward(a: Tensor, dim: number) { + protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { this.cache = [a]; } @@ -127,7 +127,7 @@ export class Unsqueeze extends Operation { { operation: a.requires_grad ? this : null, shape } ); } - public backward(dz: Tensor) { + protected _backward(dz: Tensor) { const [a] = this.cache; // backward_operations: From 21bdfabbcd0717bca29b061dcf3143abd921aead Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 6 Feb 2026 19:24:37 +0800 Subject: [PATCH 057/128] feat: use AccumulateGrad and retain_grad --- src/nn/ops.gen.ts | 20 +- src/nn/ops.ts.j2 | 6 +- src/operations/base.ts | 37 ++++ src/operations/ops.gen.ts | 347 ++++++++++++++++++++------------- src/operations/ops.ts.j2 | 78 +++++--- src/tensor.ts | 39 ++-- test/backward.test.js | 35 +++- test/custom_operations.test.js | 22 ++- test/tensor.test.js | 343 ++++++++++++++++---------------- 9 files changed, 563 insertions(+), 364 deletions(-) diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts index 0d02bc47..f88ad13b 100644 --- a/src/nn/ops.gen.ts +++ b/src/nn/ops.gen.ts @@ -6,7 +6,7 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation } from '../operations/base'; +import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from '../operations/base'; import { registerOperation } from '../operations/registry'; // function generated from unary_op_base("relu", "Math.max(a[x], 0)") @@ -31,18 +31,19 @@ function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Relu", "relu", backward_operations) export class Relu extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _relu_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.gt(0))); + aFn.backward(dz.mul(a.gt(0))); } } registerOperation('relu', Relu); @@ -69,18 +70,19 @@ function _sigmoid_tensor(a: Tensor, operation: Operation | null = null): Tensor } // class generated from unary_op_class("Sigmoid", "sigmoid", backward_operations) export class Sigmoid extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _sigmoid_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1))); + aFn.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1))); } } registerOperation('sigmoid', Sigmoid); \ No newline at end of file diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2 index 7823bfb8..d0289518 100644 --- a/src/nn/ops.ts.j2 +++ b/src/nn/ops.ts.j2 @@ -6,11 +6,11 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation } from '../operations/base'; +import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from '../operations/base'; import { registerOperation } from '../operations/registry'; {{ unary_op_base("relu", "Math.max(a[x], 0)") }} -{{ unary_op_class("Relu", "relu", ["a.backward(dz.mul(a.gt(0)));"]) }} +{{ unary_op_class("Relu", "relu", ["aFn.backward(dz.mul(a.gt(0)));"]) }} {{ unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[x]))") }} -{{ unary_op_class("Sigmoid", "sigmoid", ["a.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)));"]) }} +{{ unary_op_class("Sigmoid", "sigmoid", ["aFn.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)));"]) }} diff --git a/src/operations/base.ts b/src/operations/base.ts index b12d866c..f03ef605 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -3,6 +3,10 @@ import { Tensor } from '../tensor'; export const opBus = new EventTarget(); abstract class Operation { + public next_functions: Operation[] = []; + public saved_tensors: Tensor[] = []; + public _retained_tensors: Tensor[] = []; + protected abstract _forward(...args: (Tensor | number | number[])[]): Tensor; protected abstract _backward(dz: Tensor): void; @@ -14,10 +18,27 @@ abstract class Operation { backward(dz: Tensor): void { opBus.dispatchEvent(new CustomEvent('backward', { detail: { operation: this, dz } })); + for (const x of this._retained_tensors) { + if (!x.grad) { + x.grad = new Tensor(new Array(x.dataLength()).fill(0)); + } + x.grad = x.grad.add(dz); + } this._backward(dz); } } +class NullOp extends Operation { + protected _forward(...args: (Tensor | number | number[])[]): Tensor { + throw new Error('NullOp should not be called'); + } + protected _backward(dz: Tensor): void { + return; + } +} + +export const nullOp = new NullOp(); + abstract class UnaryOperation extends Operation { protected abstract _forward(a: Tensor): Tensor; protected abstract _backward(dz: Tensor): void; @@ -33,3 +54,19 @@ export type UnaryOperationConstructor = new () => UnaryOperation; export type BinaryOperationConstructor = new () => BinaryOperation; export { Operation, UnaryOperation, BinaryOperation }; + +export class AccumulateGrad extends UnaryOperation { + public variable: Tensor; + + protected _forward(variable: Tensor): Tensor { + this.variable = variable; + return variable; + } + + protected _backward(dz: Tensor): void { + if(!this.variable.grad) { + this.variable.grad = new Tensor(new Array(this.variable.dataLength()).fill(0)); + } + this.variable.grad = this.variable.grad.add(dz); + } +} diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts index de4820f4..01760e30 100644 --- a/src/operations/ops.gen.ts +++ b/src/operations/ops.gen.ts @@ -7,8 +7,7 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -// import gpu, { Texture } from '../gpu'; -import { Operation, BinaryOperation, UnaryOperation } from './base'; +import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; @@ -40,15 +39,17 @@ function ___left_index___tensor(a: Tensor, b: Tensor, operation: Operation | nul } // class generated from binary_op_class("__Left_index__", "__left_index__", backward_operations) export class __Left_index__ extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return ___left_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -82,15 +83,17 @@ function ___right_index___tensor(a: Tensor, b: Tensor, operation: Operation | nu } // class generated from binary_op_class("__Right_index__", "__right_index__", backward_operations) export class __Right_index__ extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return ___right_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -126,19 +129,21 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): } // class generated from binary_op_class("Add", "add", backward_operations) export class Add extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _add_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz); - b.backward(dz); + aFn.backward(dz); + bFn.backward(dz); } } registerOperation('add', Add); @@ -169,19 +174,21 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): } // class generated from binary_op_class("Sub", "sub", backward_operations) export class Sub extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _sub_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz); - b.backward(dz.mul(new Tensor(-1))); + aFn.backward(dz); + bFn.backward(dz.mul(new Tensor(-1))); } } registerOperation('sub', Sub); @@ -212,19 +219,21 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): } // class generated from binary_op_class("Mul", "mul", backward_operations) export class Mul extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _mul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(b)); - b.backward(dz.mul(a)); + aFn.backward(dz.mul(b)); + bFn.backward(dz.mul(a)); } } registerOperation('mul', Mul); @@ -255,19 +264,21 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): } // class generated from binary_op_class("Div", "div", backward_operations) export class Div extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _div_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz.div(b)); - b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b)); + aFn.backward(dz.div(b)); + bFn.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b)); } } registerOperation('div', Div); @@ -298,19 +309,21 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): } // class generated from binary_op_class("Pow", "pow", backward_operations) export class Pow extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _pow_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1))))); - b.backward(dz.mul(a.pow(b)).mul(a.log())); + aFn.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1))))); + bFn.backward(dz.mul(a.pow(b)).mul(a.log())); } } registerOperation('pow', Pow); @@ -341,18 +354,20 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): } // class generated from binary_op_class("Fmod", "fmod", backward_operations) export class Fmod extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _fmod_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz); + aFn.backward(dz); } } registerOperation('fmod', Fmod); @@ -383,19 +398,21 @@ function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul } // class generated from binary_op_class("Maximum", "maximum", backward_operations) export class Maximum extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _maximum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.ge(b))); - b.backward(dz.mul(b.gt(a))); + aFn.backward(dz.mul(a.ge(b))); + bFn.backward(dz.mul(b.gt(a))); } } registerOperation('maximum', Maximum); @@ -426,19 +443,21 @@ function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul } // class generated from binary_op_class("Minimum", "minimum", backward_operations) export class Minimum extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _minimum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.le(b))); - b.backward(dz.mul(b.lt(a))); + aFn.backward(dz.mul(a.le(b))); + bFn.backward(dz.mul(b.lt(a))); } } registerOperation('minimum', Minimum); @@ -456,19 +475,23 @@ function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null ); } export class PowInt extends Operation { - private cache: [Tensor, number]; + private n: number; protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { - this.cache = [a, n]; + this.saved_tensors = [a]; + this.n = n; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _powint_tensor(a, n, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, n] = this.cache; + const [a] = this.saved_tensors; + const n = this.n; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(n).mul(a.pow(n - 1))); + aFn.backward(dz.mul(n).mul(a.pow(n - 1))); } } registerOperation('powint', PowInt); @@ -497,18 +520,19 @@ function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Log", "log", backward_operations) export class Log extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _log_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(new Tensor(1).div(a)); + aFn.backward(new Tensor(1).div(a)); } } registerOperation('log', Log); @@ -535,18 +559,19 @@ function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Sqrt", "sqrt", backward_operations) export class Sqrt extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _sqrt_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(new Tensor(1).div(a.sqrt()).div(2)); + aFn.backward(new Tensor(1).div(a.sqrt()).div(2)); } } registerOperation('sqrt', Sqrt); @@ -573,18 +598,19 @@ function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Exp", "exp", backward_operations) export class Exp extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _exp_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.exp())); + aFn.backward(dz.mul(a.exp())); } } registerOperation('exp', Exp); @@ -611,18 +637,19 @@ function _square_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Square", "square", backward_operations) export class Square extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _square_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a).mul(new Tensor(2))); + aFn.backward(dz.mul(a).mul(new Tensor(2))); } } registerOperation('square', Square); @@ -649,18 +676,19 @@ function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Abs", "abs", backward_operations) export class Abs extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _abs_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(functional.sign(a))); + aFn.backward(dz.mul(functional.sign(a))); } } registerOperation('abs', Abs); @@ -687,15 +715,16 @@ function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Sign", "sign", backward_operations) export class Sign extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _sign_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: @@ -725,18 +754,19 @@ function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Neg", "neg", backward_operations) export class Neg extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _neg_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(new Tensor(-1))); + aFn.backward(dz.mul(new Tensor(-1))); } } registerOperation('neg', Neg); @@ -763,24 +793,24 @@ function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tens } // class generated from unary_op_class("Reciprocal", "reciprocal", backward_operations) export class Reciprocal extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _reciprocal_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.pow(-2))); + aFn.backward(dz.mul(a.pow(-2))); } } registerOperation('reciprocal', Reciprocal); export class Reshape extends Operation { - private cache: [Tensor]; protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -790,7 +820,16 @@ export class Reshape extends Operation { } if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); } return new Tensor( @@ -800,19 +839,28 @@ export class Reshape extends Operation { ); } protected _backward(dz: Tensor) { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.reshape(a.shape)); + aFn.backward(dz.reshape(a.shape)); } } registerOperation('reshape', Reshape); export class Unsqueeze extends Operation { - private cache: [Tensor]; protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); } if (dim < 0) { @@ -829,10 +877,11 @@ export class Unsqueeze extends Operation { ); } protected _backward(dz: Tensor) { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.reshape(a.shape)); + aFn.backward(dz.reshape(a.shape)); } } registerOperation('unsqueeze', Unsqueeze); @@ -861,18 +910,19 @@ function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Sin", "sin", backward_operations) export class Sin extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _sin_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.cos())); + aFn.backward(dz.mul(a.cos())); } } registerOperation('sin', Sin); @@ -899,18 +949,19 @@ function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Cos", "cos", backward_operations) export class Cos extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _cos_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.sin().neg())); + aFn.backward(dz.mul(a.sin().neg())); } } registerOperation('cos', Cos); @@ -937,18 +988,19 @@ function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Tan", "tan", backward_operations) export class Tan extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _tan_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(a.cos().pow(-2))); + aFn.backward(dz.mul(a.cos().pow(-2))); } } registerOperation('tan', Tan); @@ -965,19 +1017,20 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Sum", "sum", backward_operations) export class Sum extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _sum_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: const result = new Tensor(Array(a.dataLength()).fill(dz.item())); - a.backward(result); + aFn.backward(result); } } registerOperation('sum', Sum); @@ -992,19 +1045,20 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { // class generated from unary_op_class("Mean", "mean", backward_operations) export class Mean extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _mean_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: const result = new Tensor(Array(a.dataLength()).fill(dz.item() / a.dataLength())); - a.backward(result); + aFn.backward(result); } } registerOperation('mean', Mean); @@ -1057,16 +1111,25 @@ function _transpose_tensor( ); } export class Transpose extends Operation { - cache: [Tensor, number, number]; + private dim0: number; + private dim1: number; protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { - this.cache = [a, dim0, dim1]; + if (a.requires_grad) { + this.saved_tensors = [a]; + this.dim0 = dim0; + this.dim1 = dim1; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _transpose_tensor(a, dim0, dim1, this); } protected _backward(dz: Tensor): void { - const [a, dim0, dim1] = this.cache; + const [a] = this.saved_tensors; + const dim0 = this.dim0; + const dim1 = this.dim1; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.transpose(dim0, dim1)); + aFn.backward(dz.transpose(dim0, dim1)); } } registerOperation('transpose', Transpose); @@ -1136,15 +1199,17 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null } // class generated from binary_op_class("Matmul", "matmul", backward_operations) export class Matmul extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -1180,15 +1245,17 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T } // class generated from binary_op_class("Lt", "lt", backward_operations) export class Lt extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _lt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -1222,15 +1289,17 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T } // class generated from binary_op_class("Gt", "gt", backward_operations) export class Gt extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _gt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -1264,15 +1333,17 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T } // class generated from binary_op_class("Le", "le", backward_operations) export class Le extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _le_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -1306,15 +1377,17 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T } // class generated from binary_op_class("Ge", "ge", backward_operations) export class Ge extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _ge_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -1348,15 +1421,17 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T } // class generated from binary_op_class("Eq", "eq", backward_operations) export class Eq extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _eq_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: @@ -1390,15 +1465,17 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T } // class generated from binary_op_class("Ne", "ne", backward_operations) export class Ne extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _ne_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2 index f7a078d2..6a3d9ff3 100644 --- a/src/operations/ops.ts.j2 +++ b/src/operations/ops.ts.j2 @@ -7,7 +7,7 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation } from './base'; +import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; @@ -22,31 +22,31 @@ import { registerOperation } from './registry'; // binary pointwise {{ binary_op_base("add", "a[a_index] + b[b_index]") }} -{{ binary_op_class("Add", "add", ["a.backward(dz);", "b.backward(dz);"]) }} +{{ binary_op_class("Add", "add", ["aFn.backward(dz);", "bFn.backward(dz);"]) }} {{ binary_op_base("sub", "a[a_index] - b[b_index]") }} -{{ binary_op_class("Sub", "sub", ["a.backward(dz);", "b.backward(dz.mul(new Tensor(-1)));"]) }} +{{ binary_op_class("Sub", "sub", ["aFn.backward(dz);", "bFn.backward(dz.mul(new Tensor(-1)));"]) }} {{ binary_op_base("mul", "a[a_index] * b[b_index]") }} -{{ binary_op_class("Mul", "mul", ["a.backward(dz.mul(b));", "b.backward(dz.mul(a));"]) }} +{{ binary_op_class("Mul", "mul", ["aFn.backward(dz.mul(b));", "bFn.backward(dz.mul(a));"]) }} {{ binary_op_base("div", "a[a_index] / b[b_index]") }} -{{ binary_op_class("Div", "div", ["a.backward(dz.div(b));", "b.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));"]) }} +{{ binary_op_class("Div", "div", ["aFn.backward(dz.div(b));", "bFn.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));"]) }} {{ binary_op_base("pow", "Math.pow(a[a_index], b[b_index])") }} {{ binary_op_class("Pow", "pow", [ - "a.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));", - "b.backward(dz.mul(a.pow(b)).mul(a.log()));" + "aFn.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));", + "bFn.backward(dz.mul(a.pow(b)).mul(a.log()));" ])}} {{ binary_op_base("fmod", "a[a_index] % b[b_index]") }} -{{ binary_op_class("Fmod", "fmod", ["a.backward(dz);"]) }} +{{ binary_op_class("Fmod", "fmod", ["aFn.backward(dz);"]) }} {{ binary_op_base("maximum", "Math.max(a[a_index], b[b_index])") }} -{{ binary_op_class("Maximum", "maximum", ["a.backward(dz.mul(a.ge(b)));", "b.backward(dz.mul(b.gt(a)));"]) }} +{{ binary_op_class("Maximum", "maximum", ["aFn.backward(dz.mul(a.ge(b)));", "bFn.backward(dz.mul(b.gt(a)));"]) }} {{ binary_op_base("minimum", "Math.min(a[a_index], b[b_index])") }} -{{ binary_op_class("Minimum", "minimum", ["a.backward(dz.mul(a.le(b)));", "b.backward(dz.mul(b.lt(a)));"]) }} +{{ binary_op_class("Minimum", "minimum", ["aFn.backward(dz.mul(a.le(b)));", "bFn.backward(dz.mul(b.lt(a)));"]) }} {{ powint_op_base() }} @@ -55,31 +55,30 @@ import { registerOperation } from './registry'; // unary pointwise {{ unary_op_base("log", "Math.log(a[x])") }} -{{ unary_op_class("Log", "log", ["a.backward(new Tensor(1).div(a));"]) }} +{{ unary_op_class("Log", "log", ["aFn.backward(new Tensor(1).div(a));"]) }} {{ unary_op_base("sqrt", "Math.sqrt(a[x])") }} -{{ unary_op_class("Sqrt", "sqrt", ["a.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }} +{{ unary_op_class("Sqrt", "sqrt", ["aFn.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }} {{ unary_op_base("exp", "Math.exp(a[x])") }} -{{ unary_op_class("Exp", "exp", ["a.backward(dz.mul(a.exp()));"]) }} +{{ unary_op_class("Exp", "exp", ["aFn.backward(dz.mul(a.exp()));"]) }} {{ unary_op_base("square", "a[x] * a[x]") }} -{{ unary_op_class("Square", "square", ["a.backward(dz.mul(a).mul(new Tensor(2)));"]) }} +{{ unary_op_class("Square", "square", ["aFn.backward(dz.mul(a).mul(new Tensor(2)));"]) }} {{ unary_op_base("abs", "Math.abs(a[x])") }} -{{ unary_op_class("Abs", "abs", ["a.backward(dz.mul(functional.sign(a)));"]) }} +{{ unary_op_class("Abs", "abs", ["aFn.backward(dz.mul(functional.sign(a)));"]) }} {{ unary_op_base("sign", "Math.sign(a[x])") }} {{ unary_op_class("Sign", "sign", []) }} {{ unary_op_base("neg", "-a[x]") }} -{{ unary_op_class("Neg", "neg", ["a.backward(dz.mul(new Tensor(-1)));"]) }} +{{ unary_op_class("Neg", "neg", ["aFn.backward(dz.mul(new Tensor(-1)));"]) }} {{ unary_op_base("reciprocal", "1 / a[x]") }} -{{ unary_op_class("Reciprocal", "reciprocal", ["a.backward(dz.mul(a.pow(-2)));"]) }} +{{ unary_op_class("Reciprocal", "reciprocal", ["aFn.backward(dz.mul(a.pow(-2)));"]) }} export class Reshape extends Operation { - private cache: [Tensor]; protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -89,7 +88,16 @@ export class Reshape extends Operation { } if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); } return new Tensor( @@ -99,19 +107,28 @@ export class Reshape extends Operation { ); } protected _backward(dz: Tensor) { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.reshape(a.shape)); + aFn.backward(dz.reshape(a.shape)); } } registerOperation('reshape', Reshape); export class Unsqueeze extends Operation { - private cache: [Tensor]; protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); } if (dim < 0) { @@ -128,10 +145,11 @@ export class Unsqueeze extends Operation { ); } protected _backward(dz: Tensor) { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.reshape(a.shape)); + aFn.backward(dz.reshape(a.shape)); } } registerOperation('unsqueeze', Unsqueeze); @@ -139,13 +157,13 @@ registerOperation('unsqueeze', Unsqueeze); // trigonometric {{ unary_op_base("sin", "Math.sin(a[x])") }} -{{ unary_op_class("Sin", "sin", ["a.backward(dz.mul(a.cos()));"]) }} +{{ unary_op_class("Sin", "sin", ["aFn.backward(dz.mul(a.cos()));"]) }} {{ unary_op_base("cos", "Math.cos(a[x])") }} -{{ unary_op_class("Cos", "cos", ["a.backward(dz.mul(a.sin().neg()));"]) }} +{{ unary_op_class("Cos", "cos", ["aFn.backward(dz.mul(a.sin().neg()));"]) }} {{ unary_op_base("tan", "Math.tan(a[x])") }} -{{ unary_op_class("Tan", "tan", ["a.backward(dz.mul(a.cos().pow(-2)));"]) }} +{{ unary_op_class("Tan", "tan", ["aFn.backward(dz.mul(a.cos().pow(-2)));"]) }} // reduction @@ -157,7 +175,7 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } -{{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.dataLength()).fill(dz.item()));", "a.backward(result);"]) }} +{{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.dataLength()).fill(dz.item()));", "aFn.backward(result);"]) }} function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { return new Tensor( @@ -167,7 +185,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } -{{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.dataLength()).fill(dz.item() / a.dataLength()));", "a.backward(result);"]) }} +{{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.dataLength()).fill(dz.item() / a.dataLength()));", "aFn.backward(result);"]) }} // linalg diff --git a/src/tensor.ts b/src/tensor.ts index e6e8c7af..d6d2a1e3 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,5 +1,5 @@ import { _get_original_index } from './broadcasting'; -import { Operation } from './operations/base'; +import { AccumulateGrad, Operation } from './operations/base'; import { getOperation, getOperationCache } from './operations/registry'; /* @@ -46,7 +46,7 @@ function _flatten(data: NestedNumberArray): number[] { export class Tensor { data: number[]; _shape: number[]; - operation: Operation | null = null; + grad_fn: Operation | null = null; public grad: Tensor | null = null; requires_grad: boolean; @@ -60,7 +60,13 @@ export class Tensor { this.requires_grad = options.requires_grad ?? false; this._shape = internal_options.shape ?? _get_shape(data); - this.operation = internal_options.operation ?? null; + this.grad_fn = internal_options.operation ?? null; + + if (this.requires_grad && !this.grad_fn) { + const acc = new AccumulateGrad(); + acc.variable = this; + this.grad_fn = acc; + } } // TODO: Somehow having a shape of [] will have a weird error: @@ -120,13 +126,23 @@ export class Tensor { detach_(): void { this.requires_grad = false; this.grad = null; - this.operation = null; + this.grad_fn = null; } zero_(): void { this.data = Array(this.dataLength()).fill(0); } + private is_retain_grad: boolean = false; + retain_grad(): void { + // leaf node -> no-op + if (this.grad_fn instanceof AccumulateGrad) return; + if (this.is_retain_grad) return; + this.is_retain_grad = true; + + this.grad_fn._retained_tensors.push(this); + } + backward(grad?: Tensor | null): void { if (!this.requires_grad) { // If this tensor does not require gradients, stop propagation. @@ -143,19 +159,8 @@ export class Tensor { grad.toArray_(); } - if (!this.grad) { - this.grad = new Tensor(Array(this.dataLength()).fill(0)); - } - - this.grad.toArray_(); - - // this.grad += grad - for (let i = 0; i < grad.dataLength(); i++) { - this.grad.data[_get_original_index(this.shape, grad.shape, i)] += grad.data[i]; - } - - if (this.operation) { - this.operation.backward(grad); + if (this.grad_fn) { + this.grad_fn.backward(grad); } } diff --git a/test/backward.test.js b/test/backward.test.js index ae2da83f..d66171b3 100644 --- a/test/backward.test.js +++ b/test/backward.test.js @@ -42,9 +42,6 @@ describe('Autograd', () => { y.backward(); - assert.strictEqual(y1.grad?.item(), 1.0); - assert.strictEqual(y2.grad?.item(), 1.0); - assert.strictEqual(x.grad?.item(), 6.0); assert.strictEqual(x.item(), 2.0); }); @@ -56,4 +53,36 @@ describe('Autograd', () => { y.backward(); assert.strictEqual(x.grad?.item(), 6.0); }); + + it('Intermediate tensors do not store grad by default', () => { + const x = new Tensor([2.0], { requires_grad: true }); + + const y1 = x.pow(new Tensor(2.0)); + const y2 = x.mul(new Tensor(2.0)); + + const y = y1.add(y2); + + y.backward(); + + // Intermediate gradients are not retained by default + assert.strictEqual(y1.grad, null); + assert.strictEqual(y2.grad, null); + }); + + it('Intermediate tensors store grads after retain_grad', () => { + const x = new Tensor([2.0], { requires_grad: true }); + + const y1 = x.pow(new Tensor(2.0)); + const y2 = x.mul(new Tensor(2.0)); + + const y = y1.add(y2); + + y1.retain_grad(); + y2.retain_grad(); + + y.backward(); + + assert.strictEqual(y1.grad.item(), 1.0); + assert.strictEqual(y2.grad.item(), 1.0); + }); }); diff --git a/test/custom_operations.test.js b/test/custom_operations.test.js index 2b954286..cbede388 100644 --- a/test/custom_operations.test.js +++ b/test/custom_operations.test.js @@ -4,7 +4,7 @@ import { Tensor } from 'torch'; describe('Custom Operations', () => { describe('Matmul', () => { - it('should perform matrix multiplication on 2D tensors', () => { + it('should perform matrix multiplication on 2D tensors (1)', () => { const t1 = new Tensor([ [1, 2, 3], [4, 5, 6] @@ -20,6 +20,26 @@ describe('Custom Operations', () => { assert.deepStrictEqual(Array.from(result.toArray()), [31, 19, 85, 55]); }); + it('should perform matrix multiplication on 2D tensors (2)', () => { + const t1 = new Tensor([ + [1, 2, 3], + [4, 5, 6] + ]); + + const t2 = new Tensor([ + [9, 9, 1], + [6, 4, 3], + [5, 5, 6] + ]); + + const result = t1.matmul(t2); + + const expected = [36, 32, 25, 96, 86, 55]; + + assert.deepStrictEqual(Array.from(result.toArray()), expected); + assert.deepStrictEqual(result.shape, [2, 3]); + }); + it('should perform dot product on 1D tensors', () => { const t1 = new Tensor([1, 2, 3]); const t2 = new Tensor([4, 5, 6]); diff --git a/test/tensor.test.js b/test/tensor.test.js index d482fd05..8353279b 100644 --- a/test/tensor.test.js +++ b/test/tensor.test.js @@ -19,209 +19,220 @@ describe('Tensor', () => { }); }); - describe('Addition', () => { - it('should add two tensors with same shape', () => { - const t1 = new Tensor([10]); - const t2 = new Tensor([20]); - const result = t1.add(t2); - - assert.deepStrictEqual(Array.from(result.toArray()), [30]); - assert.deepStrictEqual(result.shape, [1]); + describe('Shape', () => { + it('should return the shape of the 1D tensor', () => { + const tensor = new Tensor([10, 20, 30]); + assert.deepStrictEqual(tensor.shape, [3]); }); - it('should add tensors with different shapes (broadcasting)', () => { - const t1 = new Tensor([10, 20, 30]); - const t2 = new Tensor([1]); - const result = t1.add(t2); - - assert.deepStrictEqual(Array.from(result.toArray()), [11, 21, 31]); - assert.deepStrictEqual(result.shape, [3]); + it('should return the shape of the 2D tensor', () => { + const tensor = new Tensor([ + [1, 2, 5], + [3, 4, 6] + ]); + assert.deepStrictEqual(tensor.shape, [2, 3]); }); - it('should add two 1D tensors of same length', () => { - const t1 = new Tensor([1, 2, 3]); - const t2 = new Tensor([4, 5, 6]); - const result = t1.add(t2); + describe('Reshape', () => { + it('should reshape a tensor', () => { + const t = new Tensor([1, 2, 3, 4]); + const result = t.reshape([2, 2]); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4]); + assert.deepStrictEqual(result.shape, [2, 2]); + }); - assert.deepStrictEqual(Array.from(result.toArray()), [5, 7, 9]); - assert.deepStrictEqual(result.shape, [3]); - }); - }); + it('should not reshape a tensor if the shape is not compatible', () => { + const t = new Tensor([1, 2, 3, 4]); + assert.throws(() => t.reshape([2, 3]), Error); + }); - describe('Multiplication', () => { - it('should multiply two tensors with same shape, scalar', () => { - const t1 = new Tensor([10]); - const t2 = new Tensor([20]); - const result = t1.mul(t2); + it('should reshape a tensor with different dimensions', () => { + const t = new Tensor([1, 2, 3, 4, 5, 6]); + const result = t.reshape([2, 3]); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result.shape, [2, 3]); - assert.deepStrictEqual(Array.from(result.toArray()), [200]); - assert.deepStrictEqual(result.shape, [1]); - }); + const result2 = t.reshape([3, 2]); + assert.deepStrictEqual(Array.from(result2.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result2.shape, [3, 2]); - it('should multiply two tensors with same shape, scalar 2', () => { - const t1 = new Tensor([-1.0604]); - const t2 = new Tensor([0.7560]); - const result = t1.mul(t2); + const result3 = t.reshape([6]); + assert.deepStrictEqual(Array.from(result3.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result3.shape, [6]); - assert.closeTo(Array.from(result.toArray())[0], -0.8016, 0.001); - assert.deepStrictEqual(result.shape, [1]); + const result4 = t.reshape([1, 2, 3]); + assert.deepStrictEqual(Array.from(result4.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result4.shape, [1, 2, 3]); + }); }); - it('should multiply two tensors with the same shape, integers', () => { - const i1 = [[2, 3], [5, 7], [11, 13]] - const t1 = new Tensor(i1); + describe('Unsqueeze', () => { + it('should unsqueeze a tensor', () => { + const t = new Tensor([1, 2, 3]); + let result = t.unsqueeze(0); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]); + assert.deepStrictEqual(result.shape, [1, 3]); - const i2 = [[1, 2], [3, 4], [5, 6]] - const t2 = new Tensor(i2); - - const result = t1.mul(t2); - const expected = [[2, 6], [15, 28], [55, 78]] + let s = new Tensor([1, 2, 3, 4, 5, 6]); + s = s.reshape([2, 3]); - for(let i=0;i { - const i1 = [[-0.4583, -0.2220], [-1.3351, -1.0604], [-0.4482, -1.3160]] - const t1 = new Tensor(i1); + result = s.unsqueeze(1); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result.shape, [2, 1, 3]); - const i2 = [[0.8340, 0.4923], [0.7729, 0.7560], [0.5616, 0.0999]]; - const t2 = new Tensor(i2); + result = s.unsqueeze(2); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result.shape, [2, 3, 1]); + }); - const result = t1.mul(t2); - const expected = [[-0.3822, -0.1093], [-1.0319, -0.8016], [-0.2517, -0.1315]] + it('should unsqueeze a tensor with negative dimension', () => { + const t = new Tensor([1, 2, 3]); + let result = t.unsqueeze(-1); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]); + assert.deepStrictEqual(result.shape, [3, 1]); - for(let i=0;i { - it('should multiply two tensors with different shapes (broadcasting)', () => { - const t1 = new Tensor([10, 20, 30]); - const t2 = new Tensor([1]); - const result = t1.mul(t2); + result = s.unsqueeze(-2); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result.shape, [2, 1, 3]); - assert.deepStrictEqual(Array.from(result.toArray()), [10, 20, 30]); - assert.deepStrictEqual(result.shape, [3]); + result = s.unsqueeze(-1); + assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(result.shape, [2, 3, 1]); + }); }); }); +}); - describe('Matrix Multiplication', () => { - it('should multiply two tensors with dim 1', () => { - const t1 = new Tensor([10]); - const t2 = new Tensor([20]); - const result = t1.matmul(t2); - - assert.deepStrictEqual(Array.from(result.toArray()), [200]); - assert.deepStrictEqual(result.shape, [1]); - }); - - it('should multiply two tensors with the correct values', () => { - const t1 = new Tensor([ - [1, 2, 3], - [4, 5, 6] - ]); - - const t2 = new Tensor([ - [9, 9, 1], - [6, 4, 3], - [5, 5, 6] - ]); +describe('Operations', () => { + describe('Binary Pointwise Operations', () => { + describe('Addition', () => { + it('should add two tensors with same shape', () => { + const t1 = new Tensor([10]); + const t2 = new Tensor([20]); + const result = t1.add(t2); - const result = t1.matmul(t2); + assert.deepStrictEqual(Array.from(result.toArray()), [30]); + assert.deepStrictEqual(result.shape, [1]); + }); - const expected = [36, 32, 25, 96, 86, 55]; + it('should add two 1D tensors of same length', () => { + const t1 = new Tensor([1, 2, 3]); + const t2 = new Tensor([4, 5, 6]); + const result = t1.add(t2); - assert.deepStrictEqual(Array.from(result.toArray()), expected); - assert.deepStrictEqual(result.shape, [2, 3]); + assert.deepStrictEqual(Array.from(result.toArray()), [5, 7, 9]); + assert.deepStrictEqual(result.shape, [3]); + }); }); - }); - describe('Reshape', () => { - it('should reshape a tensor', () => { - const t = new Tensor([1, 2, 3, 4]); - const result = t.reshape([2, 2]); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4]); - assert.deepStrictEqual(result.shape, [2, 2]); - }); + describe('Multiplication', () => { + it('should multiply two tensors with same shape, scalar', () => { + const t1 = new Tensor([10]); + const t2 = new Tensor([20]); + const result = t1.mul(t2); - it('should not reshape a tensor if the shape is not compatible', () => { - const t = new Tensor([1, 2, 3, 4]); - assert.throws(() => t.reshape([2, 3]), Error); - }); + assert.deepStrictEqual(Array.from(result.toArray()), [200]); + assert.deepStrictEqual(result.shape, [1]); + }); + + it('should multiply two tensors with same shape, scalar 2', () => { + const t1 = new Tensor([-1.0604]); + const t2 = new Tensor([0.756]); + const result = t1.mul(t2); - it('should reshape a tensor with different dimensions', () => { - const t = new Tensor([1, 2, 3, 4, 5, 6]); - const result = t.reshape([2, 3]); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [2, 3]); + assert.closeTo(Array.from(result.toArray())[0], -0.8016, 0.001); + assert.deepStrictEqual(result.shape, [1]); + }); - const result2 = t.reshape([3, 2]); - assert.deepStrictEqual(Array.from(result2.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result2.shape, [3, 2]); + it('should multiply two tensors with the same shape, integers', () => { + const i1 = [ + [2, 3], + [5, 7], + [11, 13] + ]; + const t1 = new Tensor(i1); + + const i2 = [ + [1, 2], + [3, 4], + [5, 6] + ]; + const t2 = new Tensor(i2); + + const result = t1.mul(t2); + const expected = [ + [2, 6], + [15, 28], + [55, 78] + ]; + + for (let i = 0; i < expected.length; i++) { + for (let j = 0; j < expected[i].length; j++) { + assert.closeTo(result.data[i * expected[i].length + j], expected[i][j], 0.001); + } + } + }); - const result3 = t.reshape([6]); - assert.deepStrictEqual(Array.from(result3.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result3.shape, [6]); + it('should multiply two tensors with the same shape', () => { + const i1 = [ + [-0.4583, -0.222], + [-1.3351, -1.0604], + [-0.4482, -1.316] + ]; + const t1 = new Tensor(i1); + + const i2 = [ + [0.834, 0.4923], + [0.7729, 0.756], + [0.5616, 0.0999] + ]; + const t2 = new Tensor(i2); + + const result = t1.mul(t2); + const expected = [ + [-0.3822, -0.1093], + [-1.0319, -0.8016], + [-0.2517, -0.1315] + ]; + + for (let i = 0; i < expected.length; i++) { + for (let j = 0; j < expected[i].length; j++) { + assert.closeTo(result.data[i * expected[i].length + j], expected[i][j], 0.001); + } + } - const result4 = t.reshape([1, 2, 3]); - assert.deepStrictEqual(Array.from(result4.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result4.shape, [1, 2, 3]); + assert.deepStrictEqual(result.shape, [3, 2]); + }); }); }); - describe('Unsqueeze', () => { - it('should unsqueeze a tensor', () => { - const t = new Tensor([1, 2, 3]); - let result = t.unsqueeze(0); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]); - assert.deepStrictEqual(result.shape, [1, 3]); - - let s = new Tensor([1, 2, 3, 4, 5, 6]); - s = s.reshape([2, 3]); - - result = s.unsqueeze(0); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [1, 2, 3]); - - result = s.unsqueeze(1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [2, 1, 3]); + describe('Operations with Broadcasting', () => { + it('should multiply two tensors with different shapes (broadcasting)', () => { + const t1 = new Tensor([10, 20, 30]); + const t2 = new Tensor([1]); + const result = t1.mul(t2); - result = s.unsqueeze(2); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [2, 3, 1]); + assert.deepStrictEqual(Array.from(result.toArray()), [10, 20, 30]); + assert.deepStrictEqual(result.shape, [3]); }); + it('should add tensors with different shapes (broadcasting)', () => { + const t1 = new Tensor([10, 20, 30]); + const t2 = new Tensor([1]); + const result = t1.add(t2); - it('should unsqueeze a tensor with negative dimension', () => { - const t = new Tensor([1, 2, 3]); - let result = t.unsqueeze(-1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]); - assert.deepStrictEqual(result.shape, [3, 1]); - - let s = new Tensor([1, 2, 3, 4, 5, 6]); - s = s.reshape([2, 3]); - - result = s.unsqueeze(-3); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [1, 2, 3]); - - result = s.unsqueeze(-2); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [2, 1, 3]); - - result = s.unsqueeze(-1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(result.shape, [2, 3, 1]); + assert.deepStrictEqual(Array.from(result.toArray()), [11, 21, 31]); + assert.deepStrictEqual(result.shape, [3]); }); }); @@ -239,11 +250,11 @@ describe('Tensor', () => { const input = [1, 2, 3, -4, 2.5, -6.7]; const t = new Tensor(input); const result = t.exp(); - const expected = input.map((x) => Math.exp(x)); + const expected = input.map(x => Math.exp(x)); for (let i = 0; i < expected.length; i++) { assert.closeTo(result.data[i], expected[i], 0.0001); } assert.deepStrictEqual(result.shape, [6]); - }) + }); }); }); From a595feee75c0101a62ba2069ea543dd4c3e5ffd1 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 6 Feb 2026 19:28:08 +0800 Subject: [PATCH 058/128] fix: error handling for github workflow --- .github/workflows/push.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index f8d307df..7e966ac1 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -32,13 +32,22 @@ jobs: run: yarn docs - name: Copy build to docs/build - run: cp -r build docs/build + run: | + if [ -d "build" ]; then + cp -r build docs/build + fi - name: Copy examples to docs/examples - run: cp -r examples docs/examples + run: | + if [ -d "examples" ]; then + cp -r examples docs/examples + fi - name: Copy vendor files to docs/vendor - run: cp -r vendor docs/vendor + run: | + if [ -d "vendor" ]; then + cp -r vendor docs/vendor + fi - name: Deploy docs uses: peaceiris/actions-gh-pages@v4 From c37cfa03c2c43e7a37eb8c69094fd7abbfd0ea82 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Thu, 12 Feb 2026 21:40:36 +0800 Subject: [PATCH 059/128] feat: id for all tensor and operations --- .envrc | 1 + .gitignore | 5 ++++- scripts/macros.ts.j2 | 44 ++++++++++++++++++++++++++++-------------- shell.nix | 7 +++++++ src/operations/base.ts | 11 ++++++++++- src/tensor.ts | 2 ++ src/util.ts | 5 +++++ test/loss.test.js | 5 ----- 8 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 .envrc create mode 100644 src/util.ts diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..65326bb6 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix \ No newline at end of file diff --git a/.gitignore b/.gitignore index f61d2d7f..aaf4e907 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,7 @@ yarn-error.log .pnp.* # We use .node-version -/.tool-versions \ No newline at end of file +/.tool-versions + +.direnv +.idea \ No newline at end of file diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2 index 52a447da..21c5a29b 100644 --- a/scripts/macros.ts.j2 +++ b/scripts/macros.ts.j2 @@ -55,15 +55,17 @@ function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tens {% macro binary_op_class(classname, opname, backward_operations) -%} // class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations) export class {{ classname }} extends BinaryOperation { - private cache: [Tensor, Tensor]; protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { - this.cache = [a, b]; + this.saved_tensors = [a, b]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, b] = this.cache; + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; // backward_operations: {{ backward_operations | join("\n ") }} @@ -75,15 +77,16 @@ registerOperation('{{ opname }}', {{ classname }}); {% macro unary_op_class(classname, opname, backward_operations) -%} // class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations) export class {{ classname }} extends UnaryOperation { - private cache: [Tensor]; protected _forward(a: Tensor): Tensor { if (a.requires_grad) { - this.cache = [a]; + this.saved_tensors = [a]; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _{{ opname }}_tensor(a, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.cache; + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; // backward_operations: {{ backward_operations | join("\n ") }} @@ -108,19 +111,23 @@ function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null {% macro powint_op_class() -%} export class PowInt extends Operation { - private cache: [Tensor, number]; + private n: number; protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { - this.cache = [a, n]; + this.saved_tensors = [a]; + this.n = n; } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _powint_tensor(a, n, a.requires_grad ? this : null); } protected _backward(dz: Tensor): void { - const [a, n] = this.cache; + const [a] = this.saved_tensors; + const n = this.n; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.mul(n).mul(a.pow(n - 1))); + aFn.backward(dz.mul(n).mul(a.pow(n - 1))); } } registerOperation('powint', PowInt); @@ -176,16 +183,25 @@ function _transpose_tensor( {% macro transpose_op_class() -%} export class Transpose extends Operation { - cache: [Tensor, number, number]; + private dim0: number; + private dim1: number; protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { - this.cache = [a, dim0, dim1]; + if (a.requires_grad) { + this.saved_tensors = [a]; + this.dim0 = dim0; + this.dim1 = dim1; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); return _transpose_tensor(a, dim0, dim1, this); } protected _backward(dz: Tensor): void { - const [a, dim0, dim1] = this.cache; + const [a] = this.saved_tensors; + const dim0 = this.dim0; + const dim1 = this.dim1; + const [aFn] = this.next_functions; // backward_operations: - a.backward(dz.transpose(dim0, dim1)); + aFn.backward(dz.transpose(dim0, dim1)); } } registerOperation('transpose', Transpose); diff --git a/shell.nix b/shell.nix index bce33d68..11f0888f 100644 --- a/shell.nix +++ b/shell.nix @@ -21,5 +21,12 @@ pkgs.mkShell { pkgs.xorg.libXext ] }:$LD_LIBRARY_PATH" + # Create venv if it doesn't exist + if [ ! -d "venv" ]; then + python -m venv venv + fi + + # Source the venv + source venv/bin/activate ''; } diff --git a/src/operations/base.ts b/src/operations/base.ts index f03ef605..ec287c89 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -1,8 +1,10 @@ import { Tensor } from '../tensor'; +import { getNextId } from '../util'; export const opBus = new EventTarget(); abstract class Operation { + public id: number = getNextId(); public next_functions: Operation[] = []; public saved_tensors: Tensor[] = []; public _retained_tensors: Tensor[] = []; @@ -12,7 +14,14 @@ abstract class Operation { forward(...args: (Tensor | number | number[])[]): Tensor { const result = this._forward(...args); - opBus.dispatchEvent(new CustomEvent('forward', { detail: { operation: this, args, result } })); + opBus.dispatchEvent(new CustomEvent('forward', { + detail: { + operation: this, + args, + result, + requires_grad: result.requires_grad + } + })); return result; } diff --git a/src/tensor.ts b/src/tensor.ts index d6d2a1e3..9a2442b6 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,6 +1,7 @@ import { _get_original_index } from './broadcasting'; import { AccumulateGrad, Operation } from './operations/base'; import { getOperation, getOperationCache } from './operations/registry'; +import { getNextId } from './util'; /* * TODO: @@ -44,6 +45,7 @@ function _flatten(data: NestedNumberArray): number[] { } export class Tensor { + public id: number = getNextId(); data: number[]; _shape: number[]; grad_fn: Operation | null = null; diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 00000000..038f3110 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,5 @@ +let globalId = 0; + +export const getNextId = () => { + return globalId++; +}; diff --git a/test/loss.test.js b/test/loss.test.js index 2664f922..49e8a921 100644 --- a/test/loss.test.js +++ b/test/loss.test.js @@ -11,8 +11,6 @@ describe('BCELoss', () => { const loss = new torch.nn.BCELoss(); const result = loss.forward(input, target); - console.log("BCELoss result:", result.item()); - assert.closeTo(result.item(), 2.0712, 0.001); }) @@ -33,9 +31,6 @@ describe('BCELoss', () => { const loss = new torch.nn.BCELoss(); const result = loss.forward(m.forward(input), target); - console.log(m.forward(input)) - console.log("BCELoss result:", result.item()); - assert.closeTo(result.item(), 0.7657, 0.001); }); }); From 6449e1361e8186b126d80b17a864fc7875cc3cbe Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sat, 28 Feb 2026 00:24:51 +0800 Subject: [PATCH 060/128] feat: eventBus for tensors and operations --- src/index.ts | 10 +++++++--- src/operations/base.ts | 16 +++++++++++----- src/tensor.ts | 4 +++- src/util.ts | 2 ++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 899e1409..134c9ab3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,13 @@ -import { Tensor } from './tensor'; +export { Tensor } from './tensor'; +export { Operation } from './operations/base'; export * from './operations/ops.gen'; -export { Operation, opBus } from './operations/base'; export * from './operations/functional'; + export * from './creation/index'; + export * as nn from './nn/index'; + export * as optim from './optim/index'; -export { Tensor }; + +export { eventBus } from './util'; \ No newline at end of file diff --git a/src/operations/base.ts b/src/operations/base.ts index ec287c89..67c83125 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -1,7 +1,5 @@ import { Tensor } from '../tensor'; -import { getNextId } from '../util'; - -export const opBus = new EventTarget(); +import { eventBus, getNextId } from '../util'; abstract class Operation { public id: number = getNextId(); @@ -13,8 +11,14 @@ abstract class Operation { protected abstract _backward(dz: Tensor): void; forward(...args: (Tensor | number | number[])[]): Tensor { + eventBus.dispatchEvent(new CustomEvent('operation.beforeForward', { + detail: { + operation: this, + args + } + })); const result = this._forward(...args); - opBus.dispatchEvent(new CustomEvent('forward', { + eventBus.dispatchEvent(new CustomEvent('operation.afterForward', { detail: { operation: this, args, @@ -26,7 +30,7 @@ abstract class Operation { } backward(dz: Tensor): void { - opBus.dispatchEvent(new CustomEvent('backward', { detail: { operation: this, dz } })); + eventBus.dispatchEvent(new CustomEvent('operation.beforeBackward', { detail: { operation: this, dz } })); for (const x of this._retained_tensors) { if (!x.grad) { x.grad = new Tensor(new Array(x.dataLength()).fill(0)); @@ -34,6 +38,7 @@ abstract class Operation { x.grad = x.grad.add(dz); } this._backward(dz); + eventBus.dispatchEvent(new CustomEvent('operation.afterBackward', { detail: { operation: this, dz } })); } } @@ -76,6 +81,7 @@ export class AccumulateGrad extends UnaryOperation { if(!this.variable.grad) { this.variable.grad = new Tensor(new Array(this.variable.dataLength()).fill(0)); } + eventBus.dispatchEvent(new CustomEvent('operation.accumulateGrad', { detail: { operation: this, dz } })); this.variable.grad = this.variable.grad.add(dz); } } diff --git a/src/tensor.ts b/src/tensor.ts index 9a2442b6..4aed0b56 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,7 +1,7 @@ import { _get_original_index } from './broadcasting'; import { AccumulateGrad, Operation } from './operations/base'; import { getOperation, getOperationCache } from './operations/registry'; -import { getNextId } from './util'; +import { getNextId, eventBus } from './util'; /* * TODO: @@ -162,7 +162,9 @@ export class Tensor { } if (this.grad_fn) { + eventBus.dispatchEvent(new CustomEvent('tensor.beforeBackward', { detail: { tensor: this } })); this.grad_fn.backward(grad); + eventBus.dispatchEvent(new CustomEvent('tensor.afterBackward', { detail: { tensor: this } })); } } diff --git a/src/util.ts b/src/util.ts index 038f3110..13d546e2 100644 --- a/src/util.ts +++ b/src/util.ts @@ -3,3 +3,5 @@ let globalId = 0; export const getNextId = () => { return globalId++; }; + +export const eventBus = new EventTarget(); \ No newline at end of file From a366a6400c7634001b57652c1074e693a3784377 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sat, 28 Feb 2026 12:32:12 +0800 Subject: [PATCH 061/128] feat: eventBus event constants --- src/index.ts | 2 +- src/operations/base.ts | 14 +++---- src/tensor.ts | 6 +-- src/util.ts | 11 ++++- test/eventListener.test.js | 86 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 test/eventListener.test.js diff --git a/src/index.ts b/src/index.ts index 134c9ab3..8a839e95 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,4 +10,4 @@ export * as nn from './nn/index'; export * as optim from './optim/index'; -export { eventBus } from './util'; \ No newline at end of file +export { eventBus, events } from './util'; \ No newline at end of file diff --git a/src/operations/base.ts b/src/operations/base.ts index 67c83125..b9593c09 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -1,5 +1,5 @@ import { Tensor } from '../tensor'; -import { eventBus, getNextId } from '../util'; +import { eventBus, getNextId, events } from '../util'; abstract class Operation { public id: number = getNextId(); @@ -11,14 +11,14 @@ abstract class Operation { protected abstract _backward(dz: Tensor): void; forward(...args: (Tensor | number | number[])[]): Tensor { - eventBus.dispatchEvent(new CustomEvent('operation.beforeForward', { + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_FORWARD, { detail: { operation: this, args } })); const result = this._forward(...args); - eventBus.dispatchEvent(new CustomEvent('operation.afterForward', { + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_AFTER_FORWARD, { detail: { operation: this, args, @@ -30,7 +30,7 @@ abstract class Operation { } backward(dz: Tensor): void { - eventBus.dispatchEvent(new CustomEvent('operation.beforeBackward', { detail: { operation: this, dz } })); + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_BACKWARD, { detail: { operation: this, dz } })); for (const x of this._retained_tensors) { if (!x.grad) { x.grad = new Tensor(new Array(x.dataLength()).fill(0)); @@ -38,7 +38,7 @@ abstract class Operation { x.grad = x.grad.add(dz); } this._backward(dz); - eventBus.dispatchEvent(new CustomEvent('operation.afterBackward', { detail: { operation: this, dz } })); + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_AFTER_BACKWARD, { detail: { operation: this, dz } })); } } @@ -78,10 +78,10 @@ export class AccumulateGrad extends UnaryOperation { } protected _backward(dz: Tensor): void { - if(!this.variable.grad) { + if (!this.variable.grad) { this.variable.grad = new Tensor(new Array(this.variable.dataLength()).fill(0)); } - eventBus.dispatchEvent(new CustomEvent('operation.accumulateGrad', { detail: { operation: this, dz } })); + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); this.variable.grad = this.variable.grad.add(dz); } } diff --git a/src/tensor.ts b/src/tensor.ts index 4aed0b56..d060b455 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,7 +1,7 @@ import { _get_original_index } from './broadcasting'; import { AccumulateGrad, Operation } from './operations/base'; import { getOperation, getOperationCache } from './operations/registry'; -import { getNextId, eventBus } from './util'; +import { getNextId, eventBus, events } from './util'; /* * TODO: @@ -162,9 +162,9 @@ export class Tensor { } if (this.grad_fn) { - eventBus.dispatchEvent(new CustomEvent('tensor.beforeBackward', { detail: { tensor: this } })); + eventBus.dispatchEvent(new CustomEvent(events.TENSOR_BEFORE_BACKWARD, { detail: { tensor: this } })); this.grad_fn.backward(grad); - eventBus.dispatchEvent(new CustomEvent('tensor.afterBackward', { detail: { tensor: this } })); + eventBus.dispatchEvent(new CustomEvent(events.TENSOR_AFTER_BACKWARD, { detail: { tensor: this } })); } } diff --git a/src/util.ts b/src/util.ts index 13d546e2..341b1da7 100644 --- a/src/util.ts +++ b/src/util.ts @@ -4,4 +4,13 @@ export const getNextId = () => { return globalId++; }; -export const eventBus = new EventTarget(); \ No newline at end of file +export const eventBus = new EventTarget(); +export const events = { + TENSOR_BEFORE_BACKWARD: 'tensor.beforeBackward', + TENSOR_AFTER_BACKWARD: 'tensor.afterBackward', + OPERATION_BEFORE_FORWARD: 'operation.beforeForward', + OPERATION_AFTER_FORWARD: 'operation.afterForward', + OPERATION_BEFORE_BACKWARD: 'operation.beforeBackward', + OPERATION_AFTER_BACKWARD: 'operation.afterBackward', + OPERATION_ACCUMULATE_GRAD: 'operation.accumulateGrad', +} \ No newline at end of file diff --git a/test/eventListener.test.js b/test/eventListener.test.js new file mode 100644 index 00000000..b6b13f72 --- /dev/null +++ b/test/eventListener.test.js @@ -0,0 +1,86 @@ +import { assert } from 'chai'; +import * as torch from 'torch'; + +describe('Event Bus', () => { + const a = new torch.Tensor([1, 2, 3], { requires_grad: true }); + const b = new torch.Tensor([4, 5, 6], { requires_grad: true }); + const ab = a.add(b); + const sum = ab.sum(); + + describe('tensor.beforeBackward', () => { + it('should dispatch event before backward', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.TENSOR_BEFORE_BACKWARD, () => { + eventDispatched = true; + }); + sum.backward(); + assert.isTrue(eventDispatched); + }); + }); + + describe('tensor.afterBackward', () => { + it('should dispatch event after backward', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.TENSOR_AFTER_BACKWARD, () => { + eventDispatched = true; + }); + sum.backward(); + assert.isTrue(eventDispatched); + }); + }); + + describe('operation.beforeForward', () => { + it('should dispatch event before forward', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.OPERATION_BEFORE_FORWARD, () => { + eventDispatched = true; + }); + const c = a.add(b); + assert.isTrue(eventDispatched); + }); + }); + + describe('operation.afterForward', () => { + it('should dispatch event after forward', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.OPERATION_AFTER_FORWARD, () => { + eventDispatched = true; + }); + const c = a.add(b); + assert.isTrue(eventDispatched); + }); + }); + + describe('operation.beforeBackward', () => { + it('should dispatch event before backward', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.OPERATION_BEFORE_BACKWARD, () => { + eventDispatched = true; + }); + sum.backward(); + assert.isTrue(eventDispatched); + }); + }); + + describe('operation.afterBackward', () => { + it('should dispatch event after backward', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.OPERATION_AFTER_BACKWARD, () => { + eventDispatched = true; + }); + sum.backward(); + assert.isTrue(eventDispatched); + }); + }); + + describe('operation.accumulateGrad', () => { + it('should dispatch event after accumulateGrad', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.OPERATION_ACCUMULATE_GRAD, () => { + eventDispatched = true; + }); + sum.backward(); + assert.isTrue(eventDispatched); + }); + }); +}); \ No newline at end of file From 5dc21652e9306f34fe4fcbbb4a30edb01244beb1 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sat, 28 Feb 2026 14:41:39 +0800 Subject: [PATCH 062/128] feat: export AccumulateGrad --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 8a839e95..61ca094d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ export { Tensor } from './tensor'; -export { Operation } from './operations/base'; +export { Operation, AccumulateGrad } from './operations/base'; export * from './operations/ops.gen'; export * from './operations/functional'; From 089a39805f22b02a19a536d47073d92a227ac97e Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sat, 28 Feb 2026 14:48:43 +0800 Subject: [PATCH 063/128] feat: emits requires grad for forward --- src/operations/base.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/operations/base.ts b/src/operations/base.ts index b9593c09..a354ba89 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -1,6 +1,15 @@ import { Tensor } from '../tensor'; import { eventBus, getNextId, events } from '../util'; +function resultRequiresGrad(...args: (Tensor | number | number[])[]): boolean { + for (const arg of args) { + if (arg instanceof Tensor && arg.requires_grad) { + return true; + } + } + return false; +} + abstract class Operation { public id: number = getNextId(); public next_functions: Operation[] = []; @@ -11,9 +20,11 @@ abstract class Operation { protected abstract _backward(dz: Tensor): void; forward(...args: (Tensor | number | number[])[]): Tensor { + const requires_grad = resultRequiresGrad(...args); eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_FORWARD, { detail: { operation: this, + requires_grad, args } })); @@ -21,9 +32,9 @@ abstract class Operation { eventBus.dispatchEvent(new CustomEvent(events.OPERATION_AFTER_FORWARD, { detail: { operation: this, + requires_grad, args, - result, - requires_grad: result.requires_grad + result } })); return result; From 9f90122c320300debb751d46f7623ef06e4c8ce7 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sat, 28 Feb 2026 14:59:36 +0800 Subject: [PATCH 064/128] feat: emit before and after accumulate grad --- src/operations/base.ts | 3 ++- src/util.ts | 3 ++- test/eventListener.test.js | 11 ++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/operations/base.ts b/src/operations/base.ts index a354ba89..eba9dd68 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -92,7 +92,8 @@ export class AccumulateGrad extends UnaryOperation { if (!this.variable.grad) { this.variable.grad = new Tensor(new Array(this.variable.dataLength()).fill(0)); } - eventBus.dispatchEvent(new CustomEvent(events.OPERATION_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); this.variable.grad = this.variable.grad.add(dz); + eventBus.dispatchEvent(new CustomEvent(events.OPERATION_AFTER_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); } } diff --git a/src/util.ts b/src/util.ts index 341b1da7..23a0048c 100644 --- a/src/util.ts +++ b/src/util.ts @@ -12,5 +12,6 @@ export const events = { OPERATION_AFTER_FORWARD: 'operation.afterForward', OPERATION_BEFORE_BACKWARD: 'operation.beforeBackward', OPERATION_AFTER_BACKWARD: 'operation.afterBackward', - OPERATION_ACCUMULATE_GRAD: 'operation.accumulateGrad', + OPERATION_BEFORE_ACCUMULATE_GRAD: 'operation.beforeAccumulateGrad', + OPERATION_AFTER_ACCUMULATE_GRAD: 'operation.afterAccumulateGrad', } \ No newline at end of file diff --git a/test/eventListener.test.js b/test/eventListener.test.js index b6b13f72..8c056638 100644 --- a/test/eventListener.test.js +++ b/test/eventListener.test.js @@ -74,9 +74,18 @@ describe('Event Bus', () => { }); describe('operation.accumulateGrad', () => { + it('should dispatch event before accumulateGrad', () => { + let eventDispatched = false; + torch.eventBus.addEventListener(torch.events.OPERATION_BEFORE_ACCUMULATE_GRAD, () => { + eventDispatched = true; + }); + sum.backward(); + assert.isTrue(eventDispatched); + }); + it('should dispatch event after accumulateGrad', () => { let eventDispatched = false; - torch.eventBus.addEventListener(torch.events.OPERATION_ACCUMULATE_GRAD, () => { + torch.eventBus.addEventListener(torch.events.OPERATION_AFTER_ACCUMULATE_GRAD, () => { eventDispatched = true; }); sum.backward(); From 4cdcdef8ccc7f1dfd9238a0316454a5891b00904 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 2 Mar 2026 14:42:47 +0800 Subject: [PATCH 065/128] feat: nn.Sequential --- src/nn/module.ts | 71 ++++++++++++++++++++++++++++++++++++++------- test/module.test.js | 47 ++++++++++++++++++++++++++++++ tsconfig.json | 33 ++++++++++----------- 3 files changed, 123 insertions(+), 28 deletions(-) diff --git a/src/nn/module.ts b/src/nn/module.ts index 90cee378..b01915b8 100644 --- a/src/nn/module.ts +++ b/src/nn/module.ts @@ -1,15 +1,15 @@ -import { Tensor } from "../tensor"; -import { NestedNumberArray } from "../tensor"; -import { Operation } from "../operations/base"; -import { rand } from "../creation"; -import { functional } from "."; +import { Tensor } from '../tensor'; +import { NestedNumberArray } from '../tensor'; +import { Operation } from '../operations/base'; +import { rand } from '../creation'; +import { functional } from '.'; export class Parameter extends Tensor { constructor( data: NestedNumberArray | Tensor | Parameter, // Default to requires_grad=true options: { requires_grad?: boolean } = { - requires_grad: true, + requires_grad: true }, internal_options: { operation?: Operation; shape?: number[] } = {} ) { @@ -67,11 +67,19 @@ export class Linear extends Module { super(); const k = Math.sqrt(1 / in_features); - this.weight = new Parameter(rand([out_features, in_features]).mul(2 * k).sub(k)); - this.bias = new Parameter(rand([out_features]).mul(2 * k).sub(k)); - - this.register("weight", this.weight); - this.register("bias", this.bias); + this.weight = new Parameter( + rand([out_features, in_features]) + .mul(2 * k) + .sub(k) + ); + this.bias = new Parameter( + rand([out_features]) + .mul(2 * k) + .sub(k) + ); + + this.register('weight', this.weight); + this.register('bias', this.bias); } forward(input: Tensor) { @@ -98,3 +106,44 @@ export class Sigmoid extends Module { return functional.sigmoid(input); } } + +export class Sequential extends Module { + private _modulesArr: Module[]; + + constructor(...modules: Module[]) { + super(); + this._modulesArr = modules; + for (let i = 0; i < modules.length; i++) { + this.register(i.toString(), modules[i]); + } + } + + append(module: Module): this { + this.register(this._modulesArr.length.toString(), module); + this._modulesArr.push(module); + return this; + } + + extend(sequential: Sequential): this { + for (const module of sequential._modulesArr) { + this.append(module); + } + return this; + } + + insert(index: number, module: Module): this { + this._modulesArr.splice(index, 0, module); + for (let i = index; i < this._modulesArr.length; i++) { + this.register(i.toString(), this._modulesArr[i]); + } + return this; + } + + forward(input: Tensor) { + let x = input; + for (const module of this._modulesArr) { + x = module.forward(x); + } + return x; + } +} diff --git a/test/module.test.js b/test/module.test.js index 255ea096..e98b6413 100644 --- a/test/module.test.js +++ b/test/module.test.js @@ -25,4 +25,51 @@ describe('Module', () => { assert.deepStrictEqual(output.shape, [128, 30]); }); }); + + describe('Sequential', () => { + it('should forward the correct shape', () => { + const model = new torch.nn.Sequential( + new torch.nn.Linear(10, 20), + new torch.nn.ReLU(), + new torch.nn.Linear(20, 30) + ); + + const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const output = model.forward(input); + assert.deepStrictEqual(output.shape, [30]); + }); + + it('should append a module', () => { + const model = new torch.nn.Sequential(); + model.append(new torch.nn.Linear(10, 20)); + model.append(new torch.nn.ReLU()); + model.append(new torch.nn.Linear(20, 30)); + + const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const output = model.forward(input); + assert.deepStrictEqual(output.shape, [30]); + }); + + it('should extend with modules', () => { + const model = new torch.nn.Sequential(new torch.nn.Linear(10, 20), new torch.nn.ReLU()); + const model2 = new torch.nn.Sequential(new torch.nn.Linear(20, 30), new torch.nn.ReLU()); + model.extend(model2); + + const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const output = model.forward(input); + assert.deepStrictEqual(output.shape, [30]); + }); + + it('should insert a module', () => { + const model = new torch.nn.Sequential( + new torch.nn.Linear(10, 20), + new torch.nn.Linear(30, 40) + ); + model.insert(1, new torch.nn.Linear(20, 30)); + + const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const output = model.forward(input); + assert.deepStrictEqual(output.shape, [40]); + }); + }); }); diff --git a/tsconfig.json b/tsconfig.json index e2a5a6fe..27bd2a93 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,17 @@ { - "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": ["ESNext", "DOM"], - "moduleResolution": "bundler", - "strict": false, - "noImplicitAny": false, - "resolveJsonModule": true, - "esModuleInterop": true, - "noEmit": true, - "skipLibCheck": true, - "types": ["node", "mocha"] - }, - "include": ["src", "test", "vite.config.browser.ts", "vite.config.node.ts"] - } - \ No newline at end of file + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "bundler", + "strict": false, + "noImplicitAny": false, + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": true, + "skipLibCheck": true, + "types": ["node", "mocha"] + }, + "include": ["src", "test", "vite.config.browser.ts", "vite.config.node.ts"] +} From 2e37563f1286d3e003ad19337312d9acb3b43599 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 2 Mar 2026 14:50:56 +0800 Subject: [PATCH 066/128] feat: fix build config and examples --- .github/workflows/push.yml | 14 ++++++++------ README.md | 2 ++ examples/browser/index.html | 16 +--------------- examples/index.html | 18 ++++++++++++++++++ examples/is_gpu_supported.js | 12 ------------ examples/pyodide/index.html | 4 +--- vite.config.browser.ts | 10 ++-------- vite.config.node.ts | 4 ---- 8 files changed, 32 insertions(+), 48 deletions(-) create mode 100644 examples/index.html delete mode 100644 examples/is_gpu_supported.js diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 7e966ac1..6641b328 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -37,16 +37,18 @@ jobs: cp -r build docs/build fi - - name: Copy examples to docs/examples + - name: Copy build to docs/media/build run: | - if [ -d "examples" ]; then - cp -r examples docs/examples + if [ -d "build" ]; then + mkdir -p docs/media + cp -r build docs/media/build fi - - name: Copy vendor files to docs/vendor + - name: Copy examples to docs/media/examples run: | - if [ -d "vendor" ]; then - cp -r vendor docs/vendor + if [ -d "examples" ]; then + mkdir -p docs/media + cp -r examples docs/media/examples fi - name: Deploy docs diff --git a/README.md b/README.md index ff61eaa9..3d39c830 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ First, build it: yarn build ``` +See [examples/](examples/) for examples. + ### Node See `examples/basic_backpropagation.js`. diff --git a/examples/browser/index.html b/examples/browser/index.html index 471f92ea..65030fc1 100644 --- a/examples/browser/index.html +++ b/examples/browser/index.html @@ -5,26 +5,12 @@ torch.js browser backprop example - - -

 
-  
   
 
 
-
\ No newline at end of file
+
diff --git a/examples/index.html b/examples/index.html
new file mode 100644
index 00000000..70308ffb
--- /dev/null
+++ b/examples/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+    
+    
+    Examples
+
+
+
+    

Examples

+ + + + diff --git a/examples/is_gpu_supported.js b/examples/is_gpu_supported.js deleted file mode 100644 index 63dcc0f4..00000000 --- a/examples/is_gpu_supported.js +++ /dev/null @@ -1,12 +0,0 @@ -// Script to check if GPU is supported on the system -import { GPU } from "../build/node/torch.node.es.js"; - -console.log("Is GPU supported:", GPU.isGPUSupported); -console.log("Is kernel map supported:", GPU.isKernelMapSupported); -console.log("Is off-screen canvas supported:", GPU.isOffscreenCanvasSupported); -console.log("Is WebGL supported:", GPU.isWebGLSupported); -console.log("Is WebGL2 supported:", GPU.isWebGL2Supported); -console.log("Is HeadlessGL supported:", GPU.isHeadlessGLSupported); -console.log("Is Canvas supported:", GPU.isCanvasSupported); -console.log("Is GPUHTMLImageArray supported:", GPU.isGPUHTMLImageArraySupported); -console.log("Is SinglePrecision supported:", GPU.isSinglePrecisionSupported); diff --git a/examples/pyodide/index.html b/examples/pyodide/index.html index 092fb669..e5381f2f 100644 --- a/examples/pyodide/index.html +++ b/examples/pyodide/index.html @@ -5,8 +5,6 @@ torch+pyodide browser backprop example - - @@ -116,4 +114,4 @@

Output:

- \ No newline at end of file + diff --git a/vite.config.browser.ts b/vite.config.browser.ts index e85187b5..4340ab5b 100644 --- a/vite.config.browser.ts +++ b/vite.config.browser.ts @@ -9,8 +9,7 @@ export default defineConfig({ }) ], build: { - // Avoid transforming/minifying function bodies used by gpu.js kernel parser - minify: false, + minify: true, sourcemap: true, lib: { entry: path.resolve(__dirname, 'src/index.ts'), @@ -30,10 +29,5 @@ export default defineConfig({ }, esbuild: { keepNames: true, - }, - resolve: { - alias: { - 'gpu.js': path.resolve(__dirname, './vendor/gpu-browser.min.js'), - }, - }, + } }); diff --git a/vite.config.node.ts b/vite.config.node.ts index 22ed2b7a..9e31fe3b 100644 --- a/vite.config.node.ts +++ b/vite.config.node.ts @@ -8,10 +8,6 @@ export default defineConfig({ fileName: (format) => format === 'es' ? 'torch.node.es.mjs' : 'torch.node.cjs', formats: ['es', 'cjs'] }, - rollupOptions: { - // Don't bundle 'gpu.js'. The user's Node project will provide it. - external: ['@veehz/gpu.js'] - }, outDir: 'build/node', target: 'node20', minify: false, From b5dee405638c50d6f3272fb342da773eb47c185b Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 3 Mar 2026 13:24:45 +0800 Subject: [PATCH 067/128] fix: matrix and transpose backward --- scripts/macros.ts.j2 | 3 +++ src/operations/ops.gen.ts | 6 +++++- src/operations/ops.ts.j2 | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2 index 21c5a29b..e30deaee 100644 --- a/scripts/macros.ts.j2 +++ b/scripts/macros.ts.j2 @@ -140,6 +140,9 @@ function _transpose_tensor( dim1: number, operation: Operation | null = null ): Tensor { + dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; + dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; + const output_shape = [...a.shape]; [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]]; const size = a.dataLength(); diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts index 01760e30..291d62e0 100644 --- a/src/operations/ops.gen.ts +++ b/src/operations/ops.gen.ts @@ -1071,6 +1071,9 @@ function _transpose_tensor( dim1: number, operation: Operation | null = null ): Tensor { + dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; + dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; + const output_shape = [...a.shape]; [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]]; const size = a.dataLength(); @@ -1212,7 +1215,8 @@ export class Matmul extends BinaryOperation { const [aFn, bFn] = this.next_functions; // backward_operations: - + aFn.backward(dz.matmul(b.transpose(-2, -1))); + bFn.backward(a.transpose(-2, -1).matmul(dz)); } } registerOperation('matmul', Matmul); diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2 index 6a3d9ff3..7aa75453 100644 --- a/src/operations/ops.ts.j2 +++ b/src/operations/ops.ts.j2 @@ -193,7 +193,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { {{ transpose_op_class() }} {{ matmul_op_base() }} -{{ binary_op_class("Matmul", "matmul", []) }} +{{ binary_op_class("Matmul", "matmul", ["aFn.backward(dz.matmul(b.transpose(-2, -1)));", "bFn.backward(a.transpose(-2, -1).matmul(dz));"]) }} // comparison From d452598272fef4b934472a67b7bb4d487bfe9130 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 3 Mar 2026 13:46:26 +0800 Subject: [PATCH 068/128] fix: backward shape --- scripts/macros.ts.j2 | 48 ++++++++++++++++++++++++++++++++++ src/operations/base.ts | 3 ++- src/operations/ops.gen.ts | 34 ++++++++++++++++++++---- src/operations/ops.ts.j2 | 9 ++++--- test/custom_operations.test.js | 23 ++++++++++++++++ test/module.test.js | 11 ++++++++ 6 files changed, 118 insertions(+), 10 deletions(-) diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2 index e30deaee..cb47b274 100644 --- a/scripts/macros.ts.j2 +++ b/scripts/macros.ts.j2 @@ -140,6 +140,9 @@ function _transpose_tensor( dim1: number, operation: Operation | null = null ): Tensor { + if(a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { + throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); + } dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; @@ -274,4 +277,49 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null { operation: operation, shape: shape_after_removing_extra_dims } ); } +{%- endmacro %} + +{% macro matmul_op_class() -%} +// class generated from matmul_op_class() +export class Matmul extends BinaryOperation { + protected _forward(a: Tensor, b: Tensor): Tensor { + if (a.requires_grad || b.requires_grad) { + this.saved_tensors = [a, b]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); + return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); + } + protected _backward(dz: Tensor): void { + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; + + // backward_operations: + if(a.shape.length == 1 && b.shape.length == 1) { + aFn.backward(dz); + bFn.backward(dz); + return; + } + + if(a.shape.length == 1) { + const dz1 = dz.unsqueeze(0); + const a1 = a.unsqueeze(0); + aFn.backward(dz1.matmul(b.transpose(-2, -1))); + bFn.backward(a1.transpose(0, 1).matmul(dz1)); + return; + } + + if(b.shape.length == 1) { + const dz1 = dz.unsqueeze(0); + const b1 = b.unsqueeze(1); + aFn.backward(dz1.matmul(b1.transpose(0, 1))); + bFn.backward(a.transpose(-2, -1).matmul(dz1)); + return; + } + + aFn.backward(dz.matmul(b.transpose(-2, -1))); + bFn.backward(a.transpose(-2, -1).matmul(dz)); + } +} +registerOperation('matmul', Matmul); {%- endmacro %} \ No newline at end of file diff --git a/src/operations/base.ts b/src/operations/base.ts index eba9dd68..b412fcde 100644 --- a/src/operations/base.ts +++ b/src/operations/base.ts @@ -1,3 +1,4 @@ +import { zeros_like } from '../creation'; import { Tensor } from '../tensor'; import { eventBus, getNextId, events } from '../util'; @@ -90,7 +91,7 @@ export class AccumulateGrad extends UnaryOperation { protected _backward(dz: Tensor): void { if (!this.variable.grad) { - this.variable.grad = new Tensor(new Array(this.variable.dataLength()).fill(0)); + this.variable.grad = zeros_like(this.variable); } eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); this.variable.grad = this.variable.grad.add(dz); diff --git a/src/operations/ops.gen.ts b/src/operations/ops.gen.ts index 291d62e0..5106dbbf 100644 --- a/src/operations/ops.gen.ts +++ b/src/operations/ops.gen.ts @@ -10,6 +10,7 @@ import { import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; +import { zeros_like } from '../creation'; // debug operations @@ -1029,8 +1030,7 @@ export class Sum extends UnaryOperation { const [aFn] = this.next_functions; // backward_operations: - const result = new Tensor(Array(a.dataLength()).fill(dz.item())); - aFn.backward(result); + aFn.backward(zeros_like(a).add(dz.item())); } } registerOperation('sum', Sum); @@ -1057,8 +1057,7 @@ export class Mean extends UnaryOperation { const [aFn] = this.next_functions; // backward_operations: - const result = new Tensor(Array(a.dataLength()).fill(dz.item() / a.dataLength())); - aFn.backward(result); + aFn.backward(zeros_like(a).add(dz.item() / a.dataLength())); } } registerOperation('mean', Mean); @@ -1071,6 +1070,9 @@ function _transpose_tensor( dim1: number, operation: Operation | null = null ): Tensor { + if(a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { + throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); + } dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; @@ -1200,7 +1202,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null { operation: operation, shape: shape_after_removing_extra_dims } ); } -// class generated from binary_op_class("Matmul", "matmul", backward_operations) +// class generated from matmul_op_class() export class Matmul extends BinaryOperation { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { @@ -1215,6 +1217,28 @@ export class Matmul extends BinaryOperation { const [aFn, bFn] = this.next_functions; // backward_operations: + if(a.shape.length == 1 && b.shape.length == 1) { + aFn.backward(dz); + bFn.backward(dz); + return; + } + + if(a.shape.length == 1) { + const dz1 = dz.unsqueeze(0); + const a1 = a.unsqueeze(0); + aFn.backward(dz1.matmul(b.transpose(-2, -1))); + bFn.backward(a1.transpose(0, 1).matmul(dz1)); + return; + } + + if(b.shape.length == 1) { + const dz1 = dz.unsqueeze(0); + const b1 = b.unsqueeze(1); + aFn.backward(dz1.matmul(b1.transpose(0, 1))); + bFn.backward(a.transpose(-2, -1).matmul(dz1)); + return; + } + aFn.backward(dz.matmul(b.transpose(-2, -1))); bFn.backward(a.transpose(-2, -1).matmul(dz)); } diff --git a/src/operations/ops.ts.j2 b/src/operations/ops.ts.j2 index 7aa75453..ef5934b6 100644 --- a/src/operations/ops.ts.j2 +++ b/src/operations/ops.ts.j2 @@ -1,4 +1,4 @@ -{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class, kernel_options, powint_op_base, powint_op_class, transpose_op_base, transpose_op_class, matmul_op_base %} +{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class, kernel_options, powint_op_base, powint_op_class, transpose_op_base, transpose_op_class, matmul_op_base, matmul_op_class %} import { Tensor } from '../tensor'; import { _broadcast_shape, @@ -10,6 +10,7 @@ import { import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; +import { zeros_like } from '../creation'; // debug operations @@ -175,7 +176,7 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } -{{ unary_op_class("Sum", "sum", ["const result = new Tensor(Array(a.dataLength()).fill(dz.item()));", "aFn.backward(result);"]) }} +{{ unary_op_class("Sum", "sum", ["aFn.backward(zeros_like(a).add(dz.item()));"]) }} function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { return new Tensor( @@ -185,7 +186,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } -{{ unary_op_class("Mean", "mean", ["const result = new Tensor(Array(a.dataLength()).fill(dz.item() / a.dataLength()));", "aFn.backward(result);"]) }} +{{ unary_op_class("Mean", "mean", ["aFn.backward(zeros_like(a).add(dz.item() / a.dataLength()));"]) }} // linalg @@ -193,7 +194,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { {{ transpose_op_class() }} {{ matmul_op_base() }} -{{ binary_op_class("Matmul", "matmul", ["aFn.backward(dz.matmul(b.transpose(-2, -1)));", "bFn.backward(a.transpose(-2, -1).matmul(dz));"]) }} +{{ matmul_op_class() }} // comparison diff --git a/test/custom_operations.test.js b/test/custom_operations.test.js index cbede388..6b74fecc 100644 --- a/test/custom_operations.test.js +++ b/test/custom_operations.test.js @@ -65,6 +65,27 @@ describe('Custom Operations', () => { const data = Array.from(result.toArray()); assert.deepStrictEqual(data, [9026, 4236, 3813, 4314, 2363, 5074, 8831, 13874]); }); + + it('should calculate backward correctly for matmul', () => { + const t1 = new Tensor([ + [1, 2], + [3, 4] + ], { requires_grad: true }); + + const t2 = new Tensor([ + [5, 6], + [7, 8] + ], { requires_grad: true }); + + const result = t1.matmul(t2); + result.sum().backward(); + + const t1Grad = Array.from(t1.grad.toArray()); + assert.deepStrictEqual(t1Grad, [11, 15, 11, 15]); + + const t2Grad = Array.from(t2.grad.toArray()); + assert.deepStrictEqual(t2Grad, [4, 4, 6, 6]); + }); }); describe('Transpose', () => { @@ -90,6 +111,8 @@ describe('Custom Operations', () => { const data = Array.from(result.toArray()); assert.deepStrictEqual(data, [1, 3, 2, 4, 5, 7, 6, 8]); }); + + }); }); diff --git a/test/module.test.js b/test/module.test.js index e98b6413..dfc1d342 100644 --- a/test/module.test.js +++ b/test/module.test.js @@ -24,6 +24,17 @@ describe('Module', () => { const output = m.forward(input); assert.deepStrictEqual(output.shape, [128, 30]); }); + + it('should backward a tensor', () => { + const linear = new torch.nn.Linear(10, 20); + const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const output = linear.forward(input).sum(); + console.log("weight shape", linear.weight.shape); + console.log("bias shape", linear.bias.shape); + output.backward(); + assert.deepStrictEqual(linear.weight.grad.shape, [20, 10]); + assert.deepStrictEqual(linear.bias.grad.shape, [20]); + }); }); describe('Sequential', () => { From 161f966a4183096482c094ce7c572d10b4e80cec Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 3 Mar 2026 14:35:23 +0800 Subject: [PATCH 069/128] feat: add test for linear backward --- test/module.test.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test/module.test.js b/test/module.test.js index dfc1d342..2cf3b14a 100644 --- a/test/module.test.js +++ b/test/module.test.js @@ -25,16 +25,25 @@ describe('Module', () => { assert.deepStrictEqual(output.shape, [128, 30]); }); - it('should backward a tensor', () => { + it('should backward a linear with correct shape', () => { const linear = new torch.nn.Linear(10, 20); const input = new torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); const output = linear.forward(input).sum(); - console.log("weight shape", linear.weight.shape); - console.log("bias shape", linear.bias.shape); output.backward(); assert.deepStrictEqual(linear.weight.grad.shape, [20, 10]); assert.deepStrictEqual(linear.bias.grad.shape, [20]); }); + + it('should backward a linear with correct values', () => { + const linear = new torch.nn.Linear(2, 3); + linear.weight.data = new torch.Tensor([[1, 2], [3, 4], [5, 6]]); + linear.bias.data = new torch.Tensor([1, 2, 3]); + const input = new torch.Tensor([1, 2]); + const output = linear.forward(input).sum(); + output.backward(); + assert.deepStrictEqual(linear.weight.grad.data, [1, 2, 1, 2, 1, 2]); + assert.deepStrictEqual(linear.bias.grad.data, [1, 1, 1]); + }); }); describe('Sequential', () => { From b1c6561003f0ade608decd18947715a3a8957e70 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 3 Mar 2026 16:45:54 +0800 Subject: [PATCH 070/128] feat: rename Operation -> TorchFunction --- CONTRIBUTING.md | 12 +- scripts/macros.ts.j2 | 24 ++-- src/{operations => functions}/base.ts | 20 +-- src/{operations => functions}/functional.ts | 0 src/{operations => functions}/ops.gen.ts | 138 ++++++++++---------- src/{operations => functions}/ops.ts.j2 | 10 +- src/{operations => functions}/registry.ts | 14 +- src/index.ts | 8 +- src/nn/functional.ts | 2 +- src/nn/module.ts | 4 +- src/nn/ops.gen.ts | 12 +- src/nn/ops.ts.j2 | 4 +- src/tensor.ts | 8 +- 13 files changed, 128 insertions(+), 128 deletions(-) rename src/{operations => functions}/base.ts (83%) rename src/{operations => functions}/functional.ts (100%) rename src/{operations => functions}/ops.gen.ts (91%) rename src/{operations => functions}/ops.ts.j2 (95%) rename src/{operations => functions}/registry.ts (51%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d2c92c8..28a8bf80 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ - [`src`](src) - [`index.ts`](src/index.ts) is the entry point of the library. - [`tensor.ts`](src/tensor.ts) is the main tensor class. - - [`operations`](operations) contains all operations that tensors can perform. + - [`function`](function) contains all functions that tensors can perform. - [`nn`](nn) contains all neural network modules (for everything under `torch.nn`). - [`optim`](optim) contains all optimizers (for everything under `torch.optim`). - [`creation`](creation) contains all tensor creation functions (all functions that create a tensor not from scratch, including `zeros`, `randn`). @@ -28,13 +28,13 @@ You will have to run `yarn generate` or `python3 scripts/generate.py`. This is to allow for testing in `.gen.ts` files before moving the edits to `.ts.j2`. -### Adding a new Operation +### Adding a new Function -To add a new operation, add it to [`src/operations/ops.ts.j2`](src/operations/ops.ts.j2). +To add a new function, add it to [`src/function/ops.ts.j2`](src/function/ops.ts.j2). -You may see the macros at [`scripts/macros.ts.j2`](scripts/macros.ts.j2) and the output at [`src/operations/ops.gen.ts`](src/operations/ops.gen.ts) (you need to run `yarn generate` to regenerate it) to see how it works. +You may see the macros at [`scripts/macros.ts.j2`](scripts/macros.ts.j2) and the output at [`src/function/ops.gen.ts`](src/function/ops.gen.ts) (you need to run `yarn generate` to regenerate it) to see how it works. -- To allow for `torch.(, )`, add it as well to [`src/operations/functional.ts`](src/operations/functional.ts). +- To allow for `torch.(, )`, add it as well to [`src/function/functional.ts`](src/function/functional.ts). - To allow for `.()`, add it as well to [`src/tensor.ts`](src/tensor.ts) as a `tensor` method. ## Testing @@ -53,4 +53,4 @@ To create a new test: To see docs, run `yarn docs` to build, and run `yarn serve docs` to serve docs on http://localhost:8080/. -To ensure familiarity with PyTorch, docs should be derived from the PyTorch docs, as mentioned in [`NOTICE`](NOTICE). \ No newline at end of file +To ensure familiarity with PyTorch, docs should be derived from the PyTorch docs, as mentioned in [`NOTICE`](NOTICE). diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2 index cb47b274..3c358bc9 100644 --- a/scripts/macros.ts.j2 +++ b/scripts/macros.ts.j2 @@ -13,7 +13,7 @@ const _{{ name }}_kernel = function (a: number[], as: number[], b: number[], bs: return res; }; -function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -40,7 +40,7 @@ const _{{ name }}_kernel = function (a: number[], output: number) { return res; }; -function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _{{ name }}_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _{{ name }}_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -54,7 +54,7 @@ function _{{ name }}_tensor(a: Tensor, operation: Operation | null = null): Tens {% macro binary_op_class(classname, opname, backward_operations) -%} // class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations) -export class {{ classname }} extends BinaryOperation { +export class {{ classname }} extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -76,7 +76,7 @@ registerOperation('{{ opname }}', {{ classname }}); {% macro unary_op_class(classname, opname, backward_operations) -%} // class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations) -export class {{ classname }} extends UnaryOperation { +export class {{ classname }} extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -96,7 +96,7 @@ registerOperation('{{ opname }}', {{ classname }}); {%- endmacro %} {% macro powint_op_base() -%} -function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor { +function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = null): Tensor { const data = new Array(a.dataLength()); for (let i = 0; i < data.length; i++) { data[i] = Math.pow(a.data[i], n); @@ -110,7 +110,7 @@ function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null {%- endmacro %} {% macro powint_op_class() -%} -export class PowInt extends Operation { +export class PowInt extends TorchFunction { private n: number; protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { @@ -138,7 +138,7 @@ function _transpose_tensor( a: Tensor, dim0: number, dim1: number, - operation: Operation | null = null + operation: TorchFunction | null = null ): Tensor { if(a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); @@ -188,7 +188,7 @@ function _transpose_tensor( {%- endmacro %} {% macro transpose_op_class() -%} -export class Transpose extends Operation { +export class Transpose extends TorchFunction { private dim0: number; private dim1: number; protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { @@ -214,7 +214,7 @@ registerOperation('transpose', Transpose); {%- endmacro %} {% macro matmul_op_base() -%} -function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { if (a.shape.length == 1 && b.shape.length == 1) { return a.mul(b).sum(); } @@ -281,7 +281,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null {% macro matmul_op_class() -%} // class generated from matmul_op_class() -export class Matmul extends BinaryOperation { +export class Matmul extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -316,10 +316,10 @@ export class Matmul extends BinaryOperation { bFn.backward(a.transpose(-2, -1).matmul(dz1)); return; } - + aFn.backward(dz.matmul(b.transpose(-2, -1))); bFn.backward(a.transpose(-2, -1).matmul(dz)); } } registerOperation('matmul', Matmul); -{%- endmacro %} \ No newline at end of file +{%- endmacro %} diff --git a/src/operations/base.ts b/src/functions/base.ts similarity index 83% rename from src/operations/base.ts rename to src/functions/base.ts index b412fcde..bb6944df 100644 --- a/src/operations/base.ts +++ b/src/functions/base.ts @@ -11,9 +11,9 @@ function resultRequiresGrad(...args: (Tensor | number | number[])[]): boolean { return false; } -abstract class Operation { +abstract class TorchFunction { public id: number = getNextId(); - public next_functions: Operation[] = []; + public next_functions: TorchFunction[] = []; public saved_tensors: Tensor[] = []; public _retained_tensors: Tensor[] = []; @@ -54,7 +54,7 @@ abstract class Operation { } } -class NullOp extends Operation { +class NullOp extends TorchFunction { protected _forward(...args: (Tensor | number | number[])[]): Tensor { throw new Error('NullOp should not be called'); } @@ -65,23 +65,23 @@ class NullOp extends Operation { export const nullOp = new NullOp(); -abstract class UnaryOperation extends Operation { +abstract class UnaryFunction extends TorchFunction { protected abstract _forward(a: Tensor): Tensor; protected abstract _backward(dz: Tensor): void; } -abstract class BinaryOperation extends Operation { +abstract class BinaryFunction extends TorchFunction { protected abstract _forward(a: Tensor, b: Tensor): Tensor; protected abstract _backward(dz: Tensor): void; } -export type OperationConstructor = new () => Operation; -export type UnaryOperationConstructor = new () => UnaryOperation; -export type BinaryOperationConstructor = new () => BinaryOperation; +export type TorchFunctionConstructor = new () => TorchFunction; +export type UnaryFunctionConstructor = new () => UnaryFunction; +export type BinaryFunctionConstructor = new () => BinaryFunction; -export { Operation, UnaryOperation, BinaryOperation }; +export { TorchFunction, UnaryFunction, BinaryFunction }; -export class AccumulateGrad extends UnaryOperation { +export class AccumulateGrad extends UnaryFunction { public variable: Tensor; protected _forward(variable: Tensor): Tensor { diff --git a/src/operations/functional.ts b/src/functions/functional.ts similarity index 100% rename from src/operations/functional.ts rename to src/functions/functional.ts diff --git a/src/operations/ops.gen.ts b/src/functions/ops.gen.ts similarity index 91% rename from src/operations/ops.gen.ts rename to src/functions/ops.gen.ts index 5106dbbf..134c939b 100644 --- a/src/operations/ops.gen.ts +++ b/src/functions/ops.gen.ts @@ -1,4 +1,4 @@ -// This file is generated by scripts/generate_script.py from src/operations/ops.ts.j2 +// This file is generated by scripts/generate_script.py from src/functions/ops.ts.j2 import { Tensor } from '../tensor'; import { _broadcast_shape, @@ -7,7 +7,7 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from './base'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; import { zeros_like } from '../creation'; @@ -24,7 +24,7 @@ const ___left_index___kernel = function (a: number[], as: number[], b: number[], return res; }; -function ___left_index___tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function ___left_index___tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -39,7 +39,7 @@ function ___left_index___tensor(a: Tensor, b: Tensor, operation: Operation | nul ); } // class generated from binary_op_class("__Left_index__", "__left_index__", backward_operations) -export class __Left_index__ extends BinaryOperation { +export class __Left_index__ extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -68,7 +68,7 @@ const ___right_index___kernel = function (a: number[], as: number[], b: number[] return res; }; -function ___right_index___tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function ___right_index___tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -83,7 +83,7 @@ function ___right_index___tensor(a: Tensor, b: Tensor, operation: Operation | nu ); } // class generated from binary_op_class("__Right_index__", "__right_index__", backward_operations) -export class __Right_index__ extends BinaryOperation { +export class __Right_index__ extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -114,7 +114,7 @@ const _add_kernel = function (a: number[], as: number[], b: number[], bs: number return res; }; -function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _add_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -129,7 +129,7 @@ function _add_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): ); } // class generated from binary_op_class("Add", "add", backward_operations) -export class Add extends BinaryOperation { +export class Add extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -159,7 +159,7 @@ const _sub_kernel = function (a: number[], as: number[], b: number[], bs: number return res; }; -function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _sub_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -174,7 +174,7 @@ function _sub_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): ); } // class generated from binary_op_class("Sub", "sub", backward_operations) -export class Sub extends BinaryOperation { +export class Sub extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -204,7 +204,7 @@ const _mul_kernel = function (a: number[], as: number[], b: number[], bs: number return res; }; -function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _mul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -219,7 +219,7 @@ function _mul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): ); } // class generated from binary_op_class("Mul", "mul", backward_operations) -export class Mul extends BinaryOperation { +export class Mul extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -249,7 +249,7 @@ const _div_kernel = function (a: number[], as: number[], b: number[], bs: number return res; }; -function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _div_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -264,7 +264,7 @@ function _div_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): ); } // class generated from binary_op_class("Div", "div", backward_operations) -export class Div extends BinaryOperation { +export class Div extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -294,7 +294,7 @@ const _pow_kernel = function (a: number[], as: number[], b: number[], bs: number return res; }; -function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _pow_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -309,7 +309,7 @@ function _pow_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): ); } // class generated from binary_op_class("Pow", "pow", backward_operations) -export class Pow extends BinaryOperation { +export class Pow extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -339,7 +339,7 @@ const _fmod_kernel = function (a: number[], as: number[], b: number[], bs: numbe return res; }; -function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _fmod_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -354,7 +354,7 @@ function _fmod_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): ); } // class generated from binary_op_class("Fmod", "fmod", backward_operations) -export class Fmod extends BinaryOperation { +export class Fmod extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -383,7 +383,7 @@ const _maximum_kernel = function (a: number[], as: number[], b: number[], bs: nu return res; }; -function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _maximum_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -398,7 +398,7 @@ function _maximum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul ); } // class generated from binary_op_class("Maximum", "maximum", backward_operations) -export class Maximum extends BinaryOperation { +export class Maximum extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -428,7 +428,7 @@ const _minimum_kernel = function (a: number[], as: number[], b: number[], bs: nu return res; }; -function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _minimum_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -443,7 +443,7 @@ function _minimum_tensor(a: Tensor, b: Tensor, operation: Operation | null = nul ); } // class generated from binary_op_class("Minimum", "minimum", backward_operations) -export class Minimum extends BinaryOperation { +export class Minimum extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -464,7 +464,7 @@ export class Minimum extends BinaryOperation { registerOperation('minimum', Minimum); -function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null): Tensor { +function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = null): Tensor { const data = new Array(a.dataLength()); for (let i = 0; i < data.length; i++) { data[i] = Math.pow(a.data[i], n); @@ -475,7 +475,7 @@ function _powint_tensor(a: Tensor, n: number, operation: Operation | null = null { operation: operation, shape: a.shape } ); } -export class PowInt extends Operation { +export class PowInt extends TorchFunction { private n: number; protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { @@ -509,7 +509,7 @@ const _log_kernel = function (a: number[], output: number) { return res; }; -function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _log_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _log_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -520,7 +520,7 @@ function _log_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Log", "log", backward_operations) -export class Log extends UnaryOperation { +export class Log extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -548,7 +548,7 @@ const _sqrt_kernel = function (a: number[], output: number) { return res; }; -function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _sqrt_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _sqrt_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -559,7 +559,7 @@ function _sqrt_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Sqrt", "sqrt", backward_operations) -export class Sqrt extends UnaryOperation { +export class Sqrt extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -587,7 +587,7 @@ const _exp_kernel = function (a: number[], output: number) { return res; }; -function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _exp_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _exp_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -598,7 +598,7 @@ function _exp_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Exp", "exp", backward_operations) -export class Exp extends UnaryOperation { +export class Exp extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -626,7 +626,7 @@ const _square_kernel = function (a: number[], output: number) { return res; }; -function _square_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _square_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _square_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -637,7 +637,7 @@ function _square_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Square", "square", backward_operations) -export class Square extends UnaryOperation { +export class Square extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -665,7 +665,7 @@ const _abs_kernel = function (a: number[], output: number) { return res; }; -function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _abs_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _abs_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -676,7 +676,7 @@ function _abs_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Abs", "abs", backward_operations) -export class Abs extends UnaryOperation { +export class Abs extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -704,7 +704,7 @@ const _sign_kernel = function (a: number[], output: number) { return res; }; -function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _sign_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _sign_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -715,7 +715,7 @@ function _sign_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Sign", "sign", backward_operations) -export class Sign extends UnaryOperation { +export class Sign extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -743,7 +743,7 @@ const _neg_kernel = function (a: number[], output: number) { return res; }; -function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _neg_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _neg_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -754,7 +754,7 @@ function _neg_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Neg", "neg", backward_operations) -export class Neg extends UnaryOperation { +export class Neg extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -782,7 +782,7 @@ const _reciprocal_kernel = function (a: number[], output: number) { return res; }; -function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _reciprocal_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _reciprocal_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -793,7 +793,7 @@ function _reciprocal_tensor(a: Tensor, operation: Operation | null = null): Tens ); } // class generated from unary_op_class("Reciprocal", "reciprocal", backward_operations) -export class Reciprocal extends UnaryOperation { +export class Reciprocal extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -811,7 +811,7 @@ export class Reciprocal extends UnaryOperation { } registerOperation('reciprocal', Reciprocal); -export class Reshape extends Operation { +export class Reshape extends TorchFunction { protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -849,7 +849,7 @@ export class Reshape extends Operation { } registerOperation('reshape', Reshape); -export class Unsqueeze extends Operation { +export class Unsqueeze extends TorchFunction { protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { this.saved_tensors = [a]; @@ -899,7 +899,7 @@ const _sin_kernel = function (a: number[], output: number) { return res; }; -function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _sin_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _sin_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -910,7 +910,7 @@ function _sin_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Sin", "sin", backward_operations) -export class Sin extends UnaryOperation { +export class Sin extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -938,7 +938,7 @@ const _cos_kernel = function (a: number[], output: number) { return res; }; -function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _cos_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _cos_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -949,7 +949,7 @@ function _cos_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Cos", "cos", backward_operations) -export class Cos extends UnaryOperation { +export class Cos extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -977,7 +977,7 @@ const _tan_kernel = function (a: number[], output: number) { return res; }; -function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _tan_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _tan_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -988,7 +988,7 @@ function _tan_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Tan", "tan", backward_operations) -export class Tan extends UnaryOperation { +export class Tan extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -1008,7 +1008,7 @@ registerOperation('tan', Tan); // reduction -function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { return new Tensor( a.toArray().reduce((acc, val) => acc + val, 0), { requires_grad: a.requires_grad }, @@ -1017,7 +1017,7 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Sum", "sum", backward_operations) -export class Sum extends UnaryOperation { +export class Sum extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -1035,7 +1035,7 @@ export class Sum extends UnaryOperation { } registerOperation('sum', Sum); -function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { return new Tensor( a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), { requires_grad: a.requires_grad }, @@ -1044,7 +1044,7 @@ function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { } // class generated from unary_op_class("Mean", "mean", backward_operations) -export class Mean extends UnaryOperation { +export class Mean extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -1068,7 +1068,7 @@ function _transpose_tensor( a: Tensor, dim0: number, dim1: number, - operation: Operation | null = null + operation: TorchFunction | null = null ): Tensor { if(a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); @@ -1115,7 +1115,7 @@ function _transpose_tensor( { operation: operation, shape: output_shape } ); } -export class Transpose extends Operation { +export class Transpose extends TorchFunction { private dim0: number; private dim1: number; protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { @@ -1139,7 +1139,7 @@ export class Transpose extends Operation { } registerOperation('transpose', Transpose); -function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { if (a.shape.length == 1 && b.shape.length == 1) { return a.mul(b).sum(); } @@ -1203,7 +1203,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: Operation | null = null ); } // class generated from matmul_op_class() -export class Matmul extends BinaryOperation { +export class Matmul extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -1238,7 +1238,7 @@ export class Matmul extends BinaryOperation { bFn.backward(a.transpose(-2, -1).matmul(dz1)); return; } - + aFn.backward(dz.matmul(b.transpose(-2, -1))); bFn.backward(a.transpose(-2, -1).matmul(dz)); } @@ -1257,7 +1257,7 @@ const _lt_kernel = function (a: number[], as: number[], b: number[], bs: number[ return res; }; -function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _lt_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -1272,7 +1272,7 @@ function _lt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T ); } // class generated from binary_op_class("Lt", "lt", backward_operations) -export class Lt extends BinaryOperation { +export class Lt extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -1301,7 +1301,7 @@ const _gt_kernel = function (a: number[], as: number[], b: number[], bs: number[ return res; }; -function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _gt_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -1316,7 +1316,7 @@ function _gt_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T ); } // class generated from binary_op_class("Gt", "gt", backward_operations) -export class Gt extends BinaryOperation { +export class Gt extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -1345,7 +1345,7 @@ const _le_kernel = function (a: number[], as: number[], b: number[], bs: number[ return res; }; -function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _le_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -1360,7 +1360,7 @@ function _le_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T ); } // class generated from binary_op_class("Le", "le", backward_operations) -export class Le extends BinaryOperation { +export class Le extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -1389,7 +1389,7 @@ const _ge_kernel = function (a: number[], as: number[], b: number[], bs: number[ return res; }; -function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _ge_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -1404,7 +1404,7 @@ function _ge_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T ); } // class generated from binary_op_class("Ge", "ge", backward_operations) -export class Ge extends BinaryOperation { +export class Ge extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -1433,7 +1433,7 @@ const _eq_kernel = function (a: number[], as: number[], b: number[], bs: number[ return res; }; -function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _eq_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -1448,7 +1448,7 @@ function _eq_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T ); } // class generated from binary_op_class("Eq", "eq", backward_operations) -export class Eq extends BinaryOperation { +export class Eq extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; @@ -1477,7 +1477,7 @@ const _ne_kernel = function (a: number[], as: number[], b: number[], bs: number[ return res; }; -function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): Tensor { +function _ne_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { const broadcast_shape = _broadcast_shape(a.shape, b.shape); const padded_a_shape = _pad_shape(a.shape, broadcast_shape); const padded_b_shape = _pad_shape(b.shape, broadcast_shape); @@ -1492,7 +1492,7 @@ function _ne_tensor(a: Tensor, b: Tensor, operation: Operation | null = null): T ); } // class generated from binary_op_class("Ne", "ne", backward_operations) -export class Ne extends BinaryOperation { +export class Ne extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; diff --git a/src/operations/ops.ts.j2 b/src/functions/ops.ts.j2 similarity index 95% rename from src/operations/ops.ts.j2 rename to src/functions/ops.ts.j2 index ef5934b6..0d855fb8 100644 --- a/src/operations/ops.ts.j2 +++ b/src/functions/ops.ts.j2 @@ -7,7 +7,7 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from './base'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; import { zeros_like } from '../creation'; @@ -79,7 +79,7 @@ import { zeros_like } from '../creation'; {{ unary_op_base("reciprocal", "1 / a[x]") }} {{ unary_op_class("Reciprocal", "reciprocal", ["aFn.backward(dz.mul(a.pow(-2)));"]) }} -export class Reshape extends Operation { +export class Reshape extends TorchFunction { protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -117,7 +117,7 @@ export class Reshape extends Operation { } registerOperation('reshape', Reshape); -export class Unsqueeze extends Operation { +export class Unsqueeze extends TorchFunction { protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { this.saved_tensors = [a]; @@ -168,7 +168,7 @@ registerOperation('unsqueeze', Unsqueeze); // reduction -function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { return new Tensor( a.toArray().reduce((acc, val) => acc + val, 0), { requires_grad: a.requires_grad }, @@ -178,7 +178,7 @@ function _sum_tensor(a: Tensor, operation: Operation | null = null): Tensor { {{ unary_op_class("Sum", "sum", ["aFn.backward(zeros_like(a).add(dz.item()));"]) }} -function _mean_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { return new Tensor( a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), { requires_grad: a.requires_grad }, diff --git a/src/operations/registry.ts b/src/functions/registry.ts similarity index 51% rename from src/operations/registry.ts rename to src/functions/registry.ts index 99f39445..dd93e95a 100644 --- a/src/operations/registry.ts +++ b/src/functions/registry.ts @@ -1,14 +1,14 @@ -import { Operation, OperationConstructor } from './base'; +import { TorchFunction, TorchFunctionConstructor } from './base'; // Only allow registering concrete, constructible Operation classes -const operations = new Map(); -const operations_cache = new Map(); +const operations = new Map(); +const operations_cache = new Map(); -export function registerOperation(name: string, func: OperationConstructor) { +export function registerOperation(name: string, func: TorchFunctionConstructor) { operations.set(name, func); } -export function getOperation(name: string): OperationConstructor { +export function getOperation(name: string): TorchFunctionConstructor { const func = operations.get(name); if (!func) { throw new Error(`Operation '${name}' is not registered.`); @@ -16,11 +16,11 @@ export function getOperation(name: string): OperationConstructor { return func; } -export function getOperationCache(name: string): Operation { +export function getOperationCache(name: string): TorchFunction { const operation = operations_cache.get(name); if (!operation) { operations_cache.set(name, new (getOperation(name))()); return operations_cache.get(name)!; } return operation; -} \ No newline at end of file +} diff --git a/src/index.ts b/src/index.ts index 61ca094d..4b14ba6a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,8 @@ export { Tensor } from './tensor'; -export { Operation, AccumulateGrad } from './operations/base'; -export * from './operations/ops.gen'; -export * from './operations/functional'; +export { TorchFunction, AccumulateGrad } from './functions/base'; +export * from './functions/ops.gen'; +export * from './functions/functional'; export * from './creation/index'; @@ -10,4 +10,4 @@ export * as nn from './nn/index'; export * as optim from './optim/index'; -export { eventBus, events } from './util'; \ No newline at end of file +export { eventBus, events } from './util'; diff --git a/src/nn/functional.ts b/src/nn/functional.ts index bd3fadc5..c24b2d42 100644 --- a/src/nn/functional.ts +++ b/src/nn/functional.ts @@ -1,5 +1,5 @@ import { Tensor } from "../tensor"; -import { getOperation } from "../operations/registry"; +import { getOperation } from "../functions/registry"; function generate_function(opname: string) { return (...args: (Tensor | number)[]) => { diff --git a/src/nn/module.ts b/src/nn/module.ts index b01915b8..9e29151b 100644 --- a/src/nn/module.ts +++ b/src/nn/module.ts @@ -1,6 +1,6 @@ import { Tensor } from '../tensor'; import { NestedNumberArray } from '../tensor'; -import { Operation } from '../operations/base'; +import { TorchFunction } from '../functions/base'; import { rand } from '../creation'; import { functional } from '.'; @@ -11,7 +11,7 @@ export class Parameter extends Tensor { options: { requires_grad?: boolean } = { requires_grad: true }, - internal_options: { operation?: Operation; shape?: number[] } = {} + internal_options: { operation?: TorchFunction; shape?: number[] } = {} ) { if (data instanceof Tensor) { super(data.data, { requires_grad: true }, { shape: data.shape }); diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts index f88ad13b..28b0e849 100644 --- a/src/nn/ops.gen.ts +++ b/src/nn/ops.gen.ts @@ -6,8 +6,8 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from '../operations/base'; -import { registerOperation } from '../operations/registry'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from '../functions/base'; +import { registerOperation } from '../functions/registry'; // function generated from unary_op_base("relu", "Math.max(a[x], 0)") @@ -19,7 +19,7 @@ const _relu_kernel = function (a: number[], output: number) { return res; }; -function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _relu_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _relu_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -30,7 +30,7 @@ function _relu_tensor(a: Tensor, operation: Operation | null = null): Tensor { ); } // class generated from unary_op_class("Relu", "relu", backward_operations) -export class Relu extends UnaryOperation { +export class Relu extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -58,7 +58,7 @@ const _sigmoid_kernel = function (a: number[], output: number) { return res; }; -function _sigmoid_tensor(a: Tensor, operation: Operation | null = null): Tensor { +function _sigmoid_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { const kernel = _sigmoid_kernel; const output = a.shape.reduce((acc, val) => acc * val, 1); @@ -69,7 +69,7 @@ function _sigmoid_tensor(a: Tensor, operation: Operation | null = null): Tensor ); } // class generated from unary_op_class("Sigmoid", "sigmoid", backward_operations) -export class Sigmoid extends UnaryOperation { +export class Sigmoid extends UnaryFunction { protected _forward(a: Tensor): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2 index d0289518..8ac2d1d6 100644 --- a/src/nn/ops.ts.j2 +++ b/src/nn/ops.ts.j2 @@ -6,8 +6,8 @@ import { _get_original_index_kernel, _pad_shape } from '../broadcasting'; -import { Operation, BinaryOperation, UnaryOperation, nullOp, AccumulateGrad } from '../operations/base'; -import { registerOperation } from '../operations/registry'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from '../functions/base'; +import { registerOperation } from '../functions/registry'; {{ unary_op_base("relu", "Math.max(a[x], 0)") }} {{ unary_op_class("Relu", "relu", ["aFn.backward(dz.mul(a.gt(0)));"]) }} diff --git a/src/tensor.ts b/src/tensor.ts index d060b455..27e859a8 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,6 +1,6 @@ import { _get_original_index } from './broadcasting'; -import { AccumulateGrad, Operation } from './operations/base'; -import { getOperation, getOperationCache } from './operations/registry'; +import { AccumulateGrad, TorchFunction } from './functions/base'; +import { getOperation, getOperationCache } from './functions/registry'; import { getNextId, eventBus, events } from './util'; /* @@ -48,7 +48,7 @@ export class Tensor { public id: number = getNextId(); data: number[]; _shape: number[]; - grad_fn: Operation | null = null; + grad_fn: TorchFunction | null = null; public grad: Tensor | null = null; requires_grad: boolean; @@ -56,7 +56,7 @@ export class Tensor { constructor( data: NestedNumberArray, options: { requires_grad?: boolean } = {}, - internal_options: { operation?: Operation; shape?: number[] } = {} + internal_options: { operation?: TorchFunction; shape?: number[] } = {} ) { this.data = _flatten(data); this.requires_grad = options.requires_grad ?? false; From e9d287cd6634b9426229451d68daf28441cd0f98 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 3 Mar 2026 18:42:43 +0800 Subject: [PATCH 071/128] fix: browser test --- test/{eventListener.test.js => event_listener.test.js} | 0 test/index.html | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename test/{eventListener.test.js => event_listener.test.js} (100%) diff --git a/test/eventListener.test.js b/test/event_listener.test.js similarity index 100% rename from test/eventListener.test.js rename to test/event_listener.test.js diff --git a/test/index.html b/test/index.html index 06bbb5f9..2f9b5f1d 100644 --- a/test/index.html +++ b/test/index.html @@ -30,6 +30,7 @@ import "./backward.test.js"; import "./broadcast.test.js" import "./custom_operations.test.js" + import "./event_listener.test.js" import "./functional.test.js"; import "./loss.test.js"; import "./module.test.js"; @@ -40,4 +41,4 @@ - \ No newline at end of file + From 714485ec59d4aa90fc2171aef1234330216aaec1 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 6 Mar 2026 20:24:34 +0800 Subject: [PATCH 072/128] feat: optional name for tensor --- src/tensor.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/tensor.ts b/src/tensor.ts index 27e859a8..a6bf79b4 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -45,7 +45,12 @@ function _flatten(data: NestedNumberArray): number[] { } export class Tensor { + // Auto-generated ID public id: number = getNextId(); + + // Optional user-defined name + public name: string | null = null; + data: number[]; _shape: number[]; grad_fn: TorchFunction | null = null; @@ -55,12 +60,16 @@ export class Tensor { constructor( data: NestedNumberArray, - options: { requires_grad?: boolean } = {}, + options: { requires_grad?: boolean, name?: string } = {}, internal_options: { operation?: TorchFunction; shape?: number[] } = {} ) { this.data = _flatten(data); this.requires_grad = options.requires_grad ?? false; + if (options.name) { + this.name = options.name; + } + this._shape = internal_options.shape ?? _get_shape(data); this.grad_fn = internal_options.operation ?? null; From 47a597daa59e18128d29bdece6f6247f7da1acde Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 6 Mar 2026 21:09:05 +0800 Subject: [PATCH 073/128] feat: use lambda and remove jinja2 --- CONTRIBUTING.md | 20 +- scripts/.gitignore | 1 - scripts/generate.py | 72 -- scripts/macros.ts.j2 | 325 -------- scripts/requirements.txt | 1 - src/functions/mixin.ts | 106 +++ src/functions/ops.gen.ts | 1512 -------------------------------------- src/functions/ops.ts | 578 +++++++++++++++ src/functions/ops.ts.j2 | 217 ------ src/index.ts | 2 +- src/nn/index.ts | 2 +- src/nn/ops.gen.ts | 88 --- src/nn/ops.ts | 17 + src/nn/ops.ts.j2 | 16 - test.py | 12 + 15 files changed, 717 insertions(+), 2252 deletions(-) delete mode 100644 scripts/.gitignore delete mode 100644 scripts/generate.py delete mode 100644 scripts/macros.ts.j2 delete mode 100644 scripts/requirements.txt create mode 100644 src/functions/mixin.ts delete mode 100644 src/functions/ops.gen.ts create mode 100644 src/functions/ops.ts delete mode 100644 src/functions/ops.ts.j2 delete mode 100644 src/nn/ops.gen.ts create mode 100644 src/nn/ops.ts delete mode 100644 src/nn/ops.ts.j2 create mode 100644 test.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 28a8bf80..cf153fe9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,31 +10,15 @@ - [`examples`](examples) contains example usages of the library, including on node, on the browser, and using pyodide on the browser. - [`test`](test) contains the test cases of the library, including on node and on the browser. See [Testing](#testing). -## Development Notes - -Files ending with `.ts.j2` are generated by jinja to `.gen.ts`, using [`scripts/generate.py`](scripts/generate.py). - -Thus, Python is required to run [`scripts/generate.py`](scripts/generate.py), -which also requires `Jinja2` (see [`scripts/requirements.txt`](scripts/requirements.txt)). - -Do not edit `.gen.ts` directly, instead edit the `.ts.j2` files. - ### Development Scripts You can use `yarn watch` to automatically test after each edit. -Note that it does not automatically regenerate `.gen.ts` files when editing `.ts.j2` files. -You will have to run `yarn generate` or `python3 scripts/generate.py`. - -This is to allow for testing in `.gen.ts` files before moving the edits to `.ts.j2`. - ### Adding a new Function -To add a new function, add it to [`src/function/ops.ts.j2`](src/function/ops.ts.j2). - -You may see the macros at [`scripts/macros.ts.j2`](scripts/macros.ts.j2) and the output at [`src/function/ops.gen.ts`](src/function/ops.gen.ts) (you need to run `yarn generate` to regenerate it) to see how it works. +To add a new function, add it to [`src/functions/ops.ts`](src/functions/ops.ts). -- To allow for `torch.(, )`, add it as well to [`src/function/functional.ts`](src/function/functional.ts). +- To allow for `torch.(, )`, add it as well to [`src/functions/functional.ts`](src/functions/functional.ts). - To allow for `.()`, add it as well to [`src/tensor.ts`](src/tensor.ts) as a `tensor` method. ## Testing diff --git a/scripts/.gitignore b/scripts/.gitignore deleted file mode 100644 index 21c55e20..00000000 --- a/scripts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.gen.ts \ No newline at end of file diff --git a/scripts/generate.py b/scripts/generate.py deleted file mode 100644 index 2f5607b7..00000000 --- a/scripts/generate.py +++ /dev/null @@ -1,72 +0,0 @@ -import os -import jinja2 -from pathlib import Path - -def find_template_files(root_dir): - """Find all .ts.j2 files in the project""" - template_files = [] - for root, dirs, files in os.walk(root_dir): - for file in files: - if file.endswith('.ts.j2'): - template_files.append(os.path.join(root, file)) - return template_files - -def compile_template(template_path, output_path, env): - """Compile a single template file to .gen.ts""" - try: - # Get relative path for template loading - project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - rel_path = os.path.relpath(template_path, project_root) - - # Use the FileSystemLoader to load the template - template = env.get_template(rel_path) - - # Render the template - output = template.render({}) - - output = f"// This file is generated by scripts/generate_script.py from {rel_path}\n" + output - - # Write to .gen.ts file - with open(output_path, 'w') as f: - f.write(output) - - print(f"Generated: {output_path}") - return True - except Exception as e: - print(f"Error compiling {template_path}: {e}") - return False - -def main(): - # Setup Jinja2 environment - point to project root so it can find both src and scripts - project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - env = jinja2.Environment( - loader=jinja2.FileSystemLoader(project_root), - trim_blocks=True, - lstrip_blocks=True - ) - - # Find all template files - project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - template_files = find_template_files(project_root) - - if not template_files: - print("No .ts.j2 files found") - return - - print(f"Found {len(template_files)} template files:") - for template_file in template_files: - print(f" - {template_file}") - - # Compile each template - success_count = 0 - for template_file in template_files: - # Generate output filename - output_file = template_file.replace('.ts.j2', '.gen.ts') - - if compile_template(template_file, output_file, env): - success_count += 1 - - print(f"\nCompilation complete: {success_count}/{len(template_files)} files generated successfully") - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/scripts/macros.ts.j2 b/scripts/macros.ts.j2 deleted file mode 100644 index 3c358bc9..00000000 --- a/scripts/macros.ts.j2 +++ /dev/null @@ -1,325 +0,0 @@ -{% macro kernel_options() -%} - {} -{%- endmacro %} - -{% macro binary_op_base(name, operation) -%} -const _{{ name }}_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = {{ operation }}; - } - return res; -}; - -function _{{ name }}_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _{{ name }}_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -{%- endmacro %} - -{% macro unary_op_base(name, operation) -%} -// function generated from unary_op_base("{{ name }}", "{{ operation }}") - -const _{{ name }}_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = {{ operation }}; - } - return res; -}; - -function _{{ name }}_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _{{ name }}_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -{%- endmacro %} - -{% macro binary_op_class(classname, opname, backward_operations) -%} -// class generated from binary_op_class("{{ classname }}", "{{ opname }}", backward_operations) -export class {{ classname }} extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _{{ opname }}_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - {{ backward_operations | join("\n ") }} - } -} -registerOperation('{{ opname }}', {{ classname }}); -{%- endmacro %} - -{% macro unary_op_class(classname, opname, backward_operations) -%} -// class generated from unary_op_class("{{ classname }}", "{{ opname }}", backward_operations) -export class {{ classname }} extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _{{ opname }}_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - {{ backward_operations | join("\n ") }} - } -} -registerOperation('{{ opname }}', {{ classname }}); -{%- endmacro %} - -{% macro powint_op_base() -%} -function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = null): Tensor { - const data = new Array(a.dataLength()); - for (let i = 0; i < data.length; i++) { - data[i] = Math.pow(a.data[i], n); - } - return new Tensor( - data, - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -{%- endmacro %} - -{% macro powint_op_class() -%} -export class PowInt extends TorchFunction { - private n: number; - protected _forward(a: Tensor, n: number): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - this.n = n; - } - - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _powint_tensor(a, n, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const n = this.n; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(n).mul(a.pow(n - 1))); - } -} -registerOperation('powint', PowInt); -{%- endmacro %} - -{% macro transpose_op_base() -%} -function _transpose_tensor( - a: Tensor, - dim0: number, - dim1: number, - operation: TorchFunction | null = null -): Tensor { - if(a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { - throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); - } - dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; - dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; - - const output_shape = [...a.shape]; - [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]]; - const size = a.dataLength(); - const data = new Array(size); - - const a_strides = new Array(a.shape.length); - const out_strides = new Array(output_shape.length); - for (let i = a.shape.length - 1, s = 1; i >= 0; i--) { - a_strides[i] = s; - s *= a.shape[i]; - } - for (let i = output_shape.length - 1, s = 1; i >= 0; i--) { - out_strides[i] = s; - s *= output_shape[i]; - } - - for(let i=0; i acc * val, 1); - const data = new Array(output_size).fill(0); - - const padded_a_shape = _pad_shape(a_shape, broadcast_shape); - const padded_b_shape = _pad_shape(b_shape, broadcast_shape); - - const dim_M = broadcast_shape[broadcast_shape.length - 2]; - const dim_N = broadcast_shape[broadcast_shape.length - 1]; - const dim_K = a_shape[a_shape.length - 1]; // or b_shape[b_shape.length - 2] - - for (let i = 0; i < output_size; i++) { - const mn_idx = i % (dim_M * dim_N); - const m = Math.floor(mn_idx / dim_N); - const n = mn_idx % dim_N; - - let base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n); - let base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N); - - let sum = 0; - for(let k=0; k < dim_K; k++) { - sum += a.data[base_a + k] * b.data[base_b + k * dim_N]; - } - data[i] = sum; - } - - let shape_after_removing_extra_dims = [...broadcast_shape]; - - if (a_1d) { - shape_after_removing_extra_dims = shape_after_removing_extra_dims - .slice(0, -2) - .concat([broadcast_shape[broadcast_shape.length - 1]]); - } - - if (b_1d) { - shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1); - } - - return new Tensor( - data, - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: shape_after_removing_extra_dims } - ); -} -{%- endmacro %} - -{% macro matmul_op_class() -%} -// class generated from matmul_op_class() -export class Matmul extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - if(a.shape.length == 1 && b.shape.length == 1) { - aFn.backward(dz); - bFn.backward(dz); - return; - } - - if(a.shape.length == 1) { - const dz1 = dz.unsqueeze(0); - const a1 = a.unsqueeze(0); - aFn.backward(dz1.matmul(b.transpose(-2, -1))); - bFn.backward(a1.transpose(0, 1).matmul(dz1)); - return; - } - - if(b.shape.length == 1) { - const dz1 = dz.unsqueeze(0); - const b1 = b.unsqueeze(1); - aFn.backward(dz1.matmul(b1.transpose(0, 1))); - bFn.backward(a.transpose(-2, -1).matmul(dz1)); - return; - } - - aFn.backward(dz.matmul(b.transpose(-2, -1))); - bFn.backward(a.transpose(-2, -1).matmul(dz)); - } -} -registerOperation('matmul', Matmul); -{%- endmacro %} diff --git a/scripts/requirements.txt b/scripts/requirements.txt deleted file mode 100644 index bb0794f9..00000000 --- a/scripts/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -Jinja2==3.1.2 \ No newline at end of file diff --git a/src/functions/mixin.ts b/src/functions/mixin.ts new file mode 100644 index 00000000..02a2e790 --- /dev/null +++ b/src/functions/mixin.ts @@ -0,0 +1,106 @@ +import { Tensor } from '../tensor'; +import { + _broadcast_shape, + _get_original_index_from_transposed_index, + _get_original_index, + _get_original_index_kernel, + _pad_shape +} from '../broadcasting'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp } from './base'; +import { registerOperation } from './registry'; + +export function BinaryFunctionMixin( + operation: (a: number[], b: number[], a_index: number, b_index: number) => number, + backward_operations: (a, b, aFn, bFn, dz) => void, + opName: string | null = null +): typeof BinaryFunction { + const kernel = (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) => { + const res = Array(output_size); + for (let x = 0; x < output_size; x++) { + const a_index = _get_original_index(as, bcs, x); + const b_index = _get_original_index(bs, bcs, x); + res[x] = operation(a, b, a_index, b_index); + } + return res; + } + + const forward_tensor = (a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor => { + const broadcast_shape = _broadcast_shape(a.shape, b.shape); + const padded_a_shape = _pad_shape(a.shape, broadcast_shape); + const padded_b_shape = _pad_shape(b.shape, broadcast_shape); + + const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); + + return new Tensor( + kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], + { requires_grad: a.requires_grad || b.requires_grad }, + { operation: operation, shape: broadcast_shape } + ); + } + + const result = class extends BinaryFunction { + protected _forward(a: Tensor, b: Tensor): Tensor { + if (a.requires_grad || b.requires_grad) { + this.saved_tensors = [a, b]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); + return forward_tensor(a, b, a.requires_grad || b.requires_grad ? this : null) + } + + protected _backward(dz: Tensor): void { + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; + + backward_operations(a, b, aFn, bFn, dz); + } + } + if (opName) { + registerOperation(opName, result); + } + return result; +} + +export function UnaryFunctionMixin( + operation: (a: number[], x: number) => number, + backward_operations: (a, aFn, dz) => void, + opName: string | null = null +): typeof UnaryFunction { + const kernel = (a: number[], output_size: number) => { + const res = Array(output_size); + for (let x = 0; x < output_size; x++) { + res[x] = operation(a, x); + } + return res; + }; + const forward_tensor = (a: Tensor, operation: TorchFunction | null = null): Tensor => { + const output_size = a.dataLength(); + + return new Tensor( + kernel(a.data, output_size) as number[], + { requires_grad: a.requires_grad }, + { operation: operation, shape: a.shape } + ); + } + + const result = class extends UnaryFunction { + protected _forward(a: Tensor): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + return forward_tensor(a, a.requires_grad ? this : null) + } + + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + backward_operations(a, aFn, dz); + } + } + if (opName) { + registerOperation(opName, result); + } + return result; +} diff --git a/src/functions/ops.gen.ts b/src/functions/ops.gen.ts deleted file mode 100644 index 134c939b..00000000 --- a/src/functions/ops.gen.ts +++ /dev/null @@ -1,1512 +0,0 @@ -// This file is generated by scripts/generate_script.py from src/functions/ops.ts.j2 -import { Tensor } from '../tensor'; -import { - _broadcast_shape, - _get_original_index_from_transposed_index, - _get_original_index, - _get_original_index_kernel, - _pad_shape -} from '../broadcasting'; -import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; -import * as functional from './functional'; -import { registerOperation } from './registry'; -import { zeros_like } from '../creation'; - -// debug operations - -const ___left_index___kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = a_index; - } - return res; -}; - -function ___left_index___tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = ___left_index___kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("__Left_index__", "__left_index__", backward_operations) -export class __Left_index__ extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return ___left_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('__left_index__', __Left_index__); - -const ___right_index___kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = b_index; - } - return res; -}; - -function ___right_index___tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = ___right_index___kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("__Right_index__", "__right_index__", backward_operations) -export class __Right_index__ extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return ___right_index___tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('__right_index__', __Right_index__); - -// binary pointwise - -const _add_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = a[a_index] + b[b_index]; - } - return res; -}; - -function _add_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _add_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Add", "add", backward_operations) -export class Add extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _add_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz); - bFn.backward(dz); - } -} -registerOperation('add', Add); - -const _sub_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = a[a_index] - b[b_index]; - } - return res; -}; - -function _sub_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _sub_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Sub", "sub", backward_operations) -export class Sub extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _sub_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz); - bFn.backward(dz.mul(new Tensor(-1))); - } -} -registerOperation('sub', Sub); - -const _mul_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = a[a_index] * b[b_index]; - } - return res; -}; - -function _mul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _mul_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Mul", "mul", backward_operations) -export class Mul extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _mul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(b)); - bFn.backward(dz.mul(a)); - } -} -registerOperation('mul', Mul); - -const _div_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = a[a_index] / b[b_index]; - } - return res; -}; - -function _div_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _div_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Div", "div", backward_operations) -export class Div extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _div_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.div(b)); - bFn.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b)); - } -} -registerOperation('div', Div); - -const _pow_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = Math.pow(a[a_index], b[b_index]); - } - return res; -}; - -function _pow_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _pow_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Pow", "pow", backward_operations) -export class Pow extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _pow_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1))))); - bFn.backward(dz.mul(a.pow(b)).mul(a.log())); - } -} -registerOperation('pow', Pow); - -const _fmod_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = a[a_index] % b[b_index]; - } - return res; -}; - -function _fmod_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _fmod_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Fmod", "fmod", backward_operations) -export class Fmod extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _fmod_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz); - } -} -registerOperation('fmod', Fmod); - -const _maximum_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = Math.max(a[a_index], b[b_index]); - } - return res; -}; - -function _maximum_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _maximum_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Maximum", "maximum", backward_operations) -export class Maximum extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _maximum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.ge(b))); - bFn.backward(dz.mul(b.gt(a))); - } -} -registerOperation('maximum', Maximum); - -const _minimum_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = Math.min(a[a_index], b[b_index]); - } - return res; -}; - -function _minimum_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _minimum_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Minimum", "minimum", backward_operations) -export class Minimum extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _minimum_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.le(b))); - bFn.backward(dz.mul(b.lt(a))); - } -} -registerOperation('minimum', Minimum); - - -function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = null): Tensor { - const data = new Array(a.dataLength()); - for (let i = 0; i < data.length; i++) { - data[i] = Math.pow(a.data[i], n); - } - return new Tensor( - data, - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -export class PowInt extends TorchFunction { - private n: number; - protected _forward(a: Tensor, n: number): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - this.n = n; - } - - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _powint_tensor(a, n, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const n = this.n; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(n).mul(a.pow(n - 1))); - } -} -registerOperation('powint', PowInt); - -// unary pointwise - -// function generated from unary_op_base("log", "Math.log(a[x])") - -const _log_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.log(a[x]); - } - return res; -}; - -function _log_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _log_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Log", "log", backward_operations) -export class Log extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _log_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(new Tensor(1).div(a)); - } -} -registerOperation('log', Log); - -// function generated from unary_op_base("sqrt", "Math.sqrt(a[x])") - -const _sqrt_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.sqrt(a[x]); - } - return res; -}; - -function _sqrt_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _sqrt_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Sqrt", "sqrt", backward_operations) -export class Sqrt extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _sqrt_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(new Tensor(1).div(a.sqrt()).div(2)); - } -} -registerOperation('sqrt', Sqrt); - -// function generated from unary_op_base("exp", "Math.exp(a[x])") - -const _exp_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.exp(a[x]); - } - return res; -}; - -function _exp_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _exp_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Exp", "exp", backward_operations) -export class Exp extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _exp_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.exp())); - } -} -registerOperation('exp', Exp); - -// function generated from unary_op_base("square", "a[x] * a[x]") - -const _square_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = a[x] * a[x]; - } - return res; -}; - -function _square_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _square_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Square", "square", backward_operations) -export class Square extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _square_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a).mul(new Tensor(2))); - } -} -registerOperation('square', Square); - -// function generated from unary_op_base("abs", "Math.abs(a[x])") - -const _abs_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.abs(a[x]); - } - return res; -}; - -function _abs_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _abs_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Abs", "abs", backward_operations) -export class Abs extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _abs_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(functional.sign(a))); - } -} -registerOperation('abs', Abs); - -// function generated from unary_op_base("sign", "Math.sign(a[x])") - -const _sign_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.sign(a[x]); - } - return res; -}; - -function _sign_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _sign_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Sign", "sign", backward_operations) -export class Sign extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _sign_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('sign', Sign); - -// function generated from unary_op_base("neg", "-a[x]") - -const _neg_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = -a[x]; - } - return res; -}; - -function _neg_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _neg_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Neg", "neg", backward_operations) -export class Neg extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _neg_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(new Tensor(-1))); - } -} -registerOperation('neg', Neg); - -// function generated from unary_op_base("reciprocal", "1 / a[x]") - -const _reciprocal_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = 1 / a[x]; - } - return res; -}; - -function _reciprocal_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _reciprocal_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Reciprocal", "reciprocal", backward_operations) -export class Reciprocal extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _reciprocal_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.pow(-2))); - } -} -registerOperation('reciprocal', Reciprocal); - -export class Reshape extends TorchFunction { - protected _forward(a: Tensor, shape: number[]) { - const previous_length = a.dataLength(); - const target_length = shape.reduce((acc, val) => acc * val, 1); - - if (previous_length !== target_length) { - throw new Error('Shape mismatch: ' + a.shape + ' and ' + shape); - } - - if (a.requires_grad) { - this.saved_tensors = [a]; - } - if (a.grad_fn) { - this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); - } else { - this.next_functions.push(nullOp); - } - - return new Tensor( - a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } - ); - } - protected _backward(dz: Tensor) { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.reshape(a.shape)); - } -} -registerOperation('reshape', Reshape); - -export class Unsqueeze extends TorchFunction { - protected _forward(a: Tensor, dim: number) { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - if (a.grad_fn) { - this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); - } else { - this.next_functions.push(nullOp); - } - - if (dim < 0) { - dim += a.shape.length + 1; - } - - const shape = [...a.shape]; - shape.splice(dim, 0, 1); - - return new Tensor( - a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } - ); - } - protected _backward(dz: Tensor) { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.reshape(a.shape)); - } -} -registerOperation('unsqueeze', Unsqueeze); - -// trigonometric - -// function generated from unary_op_base("sin", "Math.sin(a[x])") - -const _sin_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.sin(a[x]); - } - return res; -}; - -function _sin_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _sin_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Sin", "sin", backward_operations) -export class Sin extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _sin_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.cos())); - } -} -registerOperation('sin', Sin); - -// function generated from unary_op_base("cos", "Math.cos(a[x])") - -const _cos_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.cos(a[x]); - } - return res; -}; - -function _cos_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _cos_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Cos", "cos", backward_operations) -export class Cos extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _cos_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.sin().neg())); - } -} -registerOperation('cos', Cos); - -// function generated from unary_op_base("tan", "Math.tan(a[x])") - -const _tan_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.tan(a[x]); - } - return res; -}; - -function _tan_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _tan_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Tan", "tan", backward_operations) -export class Tan extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _tan_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.cos().pow(-2))); - } -} -registerOperation('tan', Tan); - -// reduction - -function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - return new Tensor( - a.toArray().reduce((acc, val) => acc + val, 0), - { requires_grad: a.requires_grad }, - { operation: operation } - ); -} - -// class generated from unary_op_class("Sum", "sum", backward_operations) -export class Sum extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _sum_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(zeros_like(a).add(dz.item())); - } -} -registerOperation('sum', Sum); - -function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - return new Tensor( - a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), - { requires_grad: a.requires_grad }, - { operation: operation } - ); -} - -// class generated from unary_op_class("Mean", "mean", backward_operations) -export class Mean extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _mean_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(zeros_like(a).add(dz.item() / a.dataLength())); - } -} -registerOperation('mean', Mean); - -// linalg - -function _transpose_tensor( - a: Tensor, - dim0: number, - dim1: number, - operation: TorchFunction | null = null -): Tensor { - if(a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { - throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); - } - dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; - dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; - - const output_shape = [...a.shape]; - [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]]; - const size = a.dataLength(); - const data = new Array(size); - - const a_strides = new Array(a.shape.length); - const out_strides = new Array(output_shape.length); - for (let i = a.shape.length - 1, s = 1; i >= 0; i--) { - a_strides[i] = s; - s *= a.shape[i]; - } - for (let i = output_shape.length - 1, s = 1; i >= 0; i--) { - out_strides[i] = s; - s *= output_shape[i]; - } - - for(let i=0; i acc * val, 1); - const data = new Array(output_size).fill(0); - - const padded_a_shape = _pad_shape(a_shape, broadcast_shape); - const padded_b_shape = _pad_shape(b_shape, broadcast_shape); - - const dim_M = broadcast_shape[broadcast_shape.length - 2]; - const dim_N = broadcast_shape[broadcast_shape.length - 1]; - const dim_K = a_shape[a_shape.length - 1]; // or b_shape[b_shape.length - 2] - - for (let i = 0; i < output_size; i++) { - const mn_idx = i % (dim_M * dim_N); - const m = Math.floor(mn_idx / dim_N); - const n = mn_idx % dim_N; - - let base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n); - let base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N); - - let sum = 0; - for(let k=0; k < dim_K; k++) { - sum += a.data[base_a + k] * b.data[base_b + k * dim_N]; - } - data[i] = sum; - } - - let shape_after_removing_extra_dims = [...broadcast_shape]; - - if (a_1d) { - shape_after_removing_extra_dims = shape_after_removing_extra_dims - .slice(0, -2) - .concat([broadcast_shape[broadcast_shape.length - 1]]); - } - - if (b_1d) { - shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1); - } - - return new Tensor( - data, - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: shape_after_removing_extra_dims } - ); -} -// class generated from matmul_op_class() -export class Matmul extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - if(a.shape.length == 1 && b.shape.length == 1) { - aFn.backward(dz); - bFn.backward(dz); - return; - } - - if(a.shape.length == 1) { - const dz1 = dz.unsqueeze(0); - const a1 = a.unsqueeze(0); - aFn.backward(dz1.matmul(b.transpose(-2, -1))); - bFn.backward(a1.transpose(0, 1).matmul(dz1)); - return; - } - - if(b.shape.length == 1) { - const dz1 = dz.unsqueeze(0); - const b1 = b.unsqueeze(1); - aFn.backward(dz1.matmul(b1.transpose(0, 1))); - bFn.backward(a.transpose(-2, -1).matmul(dz1)); - return; - } - - aFn.backward(dz.matmul(b.transpose(-2, -1))); - bFn.backward(a.transpose(-2, -1).matmul(dz)); - } -} -registerOperation('matmul', Matmul); - -// comparison - -const _lt_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = (a[a_index] < b[b_index]) ? 1 : 0; - } - return res; -}; - -function _lt_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _lt_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Lt", "lt", backward_operations) -export class Lt extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _lt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('lt', Lt); - -const _gt_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = (a[a_index] > b[b_index]) ? 1 : 0; - } - return res; -}; - -function _gt_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _gt_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Gt", "gt", backward_operations) -export class Gt extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _gt_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('gt', Gt); - -const _le_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = (a[a_index] <= b[b_index]) ? 1 : 0; - } - return res; -}; - -function _le_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _le_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Le", "le", backward_operations) -export class Le extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _le_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('le', Le); - -const _ge_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = (a[a_index] >= b[b_index]) ? 1 : 0; - } - return res; -}; - -function _ge_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _ge_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Ge", "ge", backward_operations) -export class Ge extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _ge_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('ge', Ge); - -const _eq_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = (a[a_index] == b[b_index]) ? 1 : 0; - } - return res; -}; - -function _eq_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _eq_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Eq", "eq", backward_operations) -export class Eq extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _eq_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('eq', Eq); - -const _ne_kernel = function (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) { - const res = Array(output_size); - for(let x = 0; x < output_size; x++) { - const a_index = _get_original_index(as, bcs, x); - const b_index = _get_original_index(bs, bcs, x); - res[x] = (a[a_index] != b[b_index]) ? 1 : 0; - } - return res; -}; - -function _ne_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { - const broadcast_shape = _broadcast_shape(a.shape, b.shape); - const padded_a_shape = _pad_shape(a.shape, broadcast_shape); - const padded_b_shape = _pad_shape(b.shape, broadcast_shape); - - const kernel = _ne_kernel; - const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, - { operation: operation, shape: broadcast_shape } - ); -} -// class generated from binary_op_class("Ne", "ne", backward_operations) -export class Ne extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _ne_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; - - // backward_operations: - - } -} -registerOperation('ne', Ne); \ No newline at end of file diff --git a/src/functions/ops.ts b/src/functions/ops.ts new file mode 100644 index 00000000..58926cbb --- /dev/null +++ b/src/functions/ops.ts @@ -0,0 +1,578 @@ +import { Tensor } from '../tensor'; +import { + _broadcast_shape, + _get_original_index_from_transposed_index, + _get_original_index, + _get_original_index_kernel, + _pad_shape +} from '../broadcasting'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; +import * as functional from './functional'; +import { registerOperation } from './registry'; +import { zeros_like } from '../creation'; +import { UnaryFunctionMixin, BinaryFunctionMixin } from './mixin'; + +// debug operations + +const __Left_index__ = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => a_index, + (a, b, aFn, bFn, dz) => { }, + "__left_index__" +); + +const __Right_index__ = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => b_index, + (a, b, aFn, bFn, dz) => { }, + "__right_index__" +); + +// binary pointwise + +const Add = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] + b[b_index], + (a, b, aFn, bFn, dz) => { + aFn.backward(dz); + bFn.backward(dz); + }, + "add" +); + +const Sub = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] - b[b_index], + (a, b, aFn, bFn, dz) => { + aFn.backward(dz); + bFn.backward(dz.mul(new Tensor(-1))); + }, + "sub" +); + +const Mul = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] * b[b_index], + (a, b, aFn, bFn, dz) => { + aFn.backward(dz.mul(b)); + bFn.backward(dz.mul(a)); + }, + "mul" +); + +const Div = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] / b[b_index], + (a, b, aFn, bFn, dz) => { + aFn.backward(dz.div(b)); + bFn.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b)); + }, + "div" +); + +const Pow = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => Math.pow(a[a_index], b[b_index]), + (a, b, aFn, bFn, dz) => { + aFn.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1))))); + bFn.backward(dz.mul(a.pow(b)).mul(a.log())); + }, + "pow" +); + +const Fmod = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] % b[b_index], + (a, b, aFn, bFn, dz) => { + aFn.backward(dz); + }, + "fmod" +); + +const Maximum = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => Math.max(a[a_index], b[b_index]), + (a, b, aFn, bFn, dz) => { + aFn.backward(dz.mul(a.ge(b))); + bFn.backward(dz.mul(b.gt(a))); + }, + "maximum" +); + +const Minimum = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => Math.min(a[a_index], b[b_index]), + (a, b, aFn, bFn, dz) => { + aFn.backward(dz.mul(a.le(b))); + bFn.backward(dz.mul(b.lt(a))); + }, + "minimum" +); + +function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = null): Tensor { + const data = new Array(a.dataLength()); + for (let i = 0; i < data.length; i++) { + data[i] = Math.pow(a.data[i], n); + } + return new Tensor( + data, + { requires_grad: a.requires_grad }, + { operation: operation, shape: a.shape } + ); +} + +export class PowInt extends TorchFunction { + private n: number; + protected _forward(a: Tensor, n: number): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + this.n = n; + } + + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + return _powint_tensor(a, n, a.requires_grad ? this : null); + } + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const n = this.n; + const [aFn] = this.next_functions; + + // backward_operations: + aFn.backward(dz.mul(n).mul(a.pow(n - 1))); + } +} +registerOperation("powint", PowInt); + +// unary pointwise + +const Log = UnaryFunctionMixin( + (a: number[], a_index: number) => Math.log(a[a_index]), + (a, aFn, dz) => { + aFn.backward(dz.mul(new Tensor(1).div(a))); + }, + "log" +); + +const Sqrt = UnaryFunctionMixin( + (a: number[], x: number) => Math.sqrt(a[x]), + (a, aFn, dz) => { + aFn.backward(dz.mul(new Tensor(1).div(a.sqrt()).div(2))); + }, + "sqrt" +); + +const Exp = UnaryFunctionMixin( + (a: number[], x: number) => Math.exp(a[x]), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.exp()))); + }, + "exp" +); + +const Square = UnaryFunctionMixin( + (a: number[], x: number) => a[x] * a[x], + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a).mul(new Tensor(2)))); + }, + "square" +); + +const Abs = UnaryFunctionMixin( + (a: number[], x: number) => Math.abs(a[x]), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(functional.sign(a)))); + }, + "abs" +); + +const Sign = UnaryFunctionMixin( + (a: number[], x: number) => Math.sign(a[x]), + (a, aFn, dz) => { + // TODO: check + aFn.backward(dz.mul(dz.mul(functional.sign(a)))); + }, + "sign" +); + +const Neg = UnaryFunctionMixin( + (a: number[], x: number) => -a[x], + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(new Tensor(-1)))); + }, + "neg" +); + +const Reciprocal = UnaryFunctionMixin( + (a: number[], x: number) => 1 / a[x], + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.pow(-2)))); + }, + "reciprocal" +); + +export class Reshape extends TorchFunction { + protected _forward(a: Tensor, shape: number[]) { + const previous_length = a.dataLength(); + const target_length = shape.reduce((acc, val) => acc * val, 1); + + if (previous_length !== target_length) { + throw new Error('Shape mismatch: ' + a.shape + ' and ' + shape); + } + + if (a.requires_grad) { + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); + } + + return new Tensor( + a.data, + { requires_grad: a.requires_grad }, + { operation: a.requires_grad ? this : null, shape } + ); + } + protected _backward(dz: Tensor) { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + // backward_operations: + aFn.backward(dz.reshape(a.shape)); + } +} +registerOperation('reshape', Reshape); + +export class Unsqueeze extends TorchFunction { + protected _forward(a: Tensor, dim: number) { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); + } + + if (dim < 0) { + dim += a.shape.length + 1; + } + + const shape = [...a.shape]; + shape.splice(dim, 0, 1); + + return new Tensor( + a.data, + { requires_grad: a.requires_grad }, + { operation: a.requires_grad ? this : null, shape } + ); + } + protected _backward(dz: Tensor) { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + // backward_operations: + aFn.backward(dz.reshape(a.shape)); + } +} +registerOperation('unsqueeze', Unsqueeze); + +// trigonometric + +const Sin = UnaryFunctionMixin( + (a: number[], x: number) => Math.sin(a[x]), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.cos()))); + }, + "sin" +); + +const Cos = UnaryFunctionMixin( + (a: number[], x: number) => Math.cos(a[x]), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.sin().neg()))); + }, + "cos" +); + +const Tan = UnaryFunctionMixin( + (a: number[], x: number) => Math.tan(a[x]), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.cos().pow(-2)))); + }, + "tan" +); + +// reduction + +function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { + return new Tensor( + a.toArray().reduce((acc, val) => acc + val, 0), + { requires_grad: a.requires_grad }, + { operation: operation } + ); +} + +export class Sum extends UnaryFunction { + protected _forward(a: Tensor): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + return _sum_tensor(a, a.requires_grad ? this : null); + } + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + // backward_operations: + aFn.backward(zeros_like(a).add(dz.item())); + } +} +registerOperation('sum', Sum); + +function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { + return new Tensor( + a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), + { requires_grad: a.requires_grad }, + { operation: operation } + ); +} + +export class Mean extends UnaryFunction { + protected _forward(a: Tensor): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + return _mean_tensor(a, a.requires_grad ? this : null); + } + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + // backward_operations: + aFn.backward(zeros_like(a).add(dz.item() / a.dataLength())); + } +} +registerOperation('mean', Mean); + +// linalg + +function _transpose_tensor( + a: Tensor, + dim0: number, + dim1: number, + operation: TorchFunction | null = null +): Tensor { + if (a.shape.length + dim0 < 0 || a.shape.length + dim1 < 0) { + throw new Error(`Transpose: Dimension out of range (${dim0} and ${dim1})`); + } + dim0 = dim0 < 0 ? a.shape.length + dim0 : dim0; + dim1 = dim1 < 0 ? a.shape.length + dim1 : dim1; + + const output_shape = [...a.shape]; + [output_shape[dim0], output_shape[dim1]] = [output_shape[dim1], output_shape[dim0]]; + const size = a.dataLength(); + const data = new Array(size); + + const a_strides = new Array(a.shape.length); + const out_strides = new Array(output_shape.length); + for (let i = a.shape.length - 1, s = 1; i >= 0; i--) { + a_strides[i] = s; + s *= a.shape[i]; + } + for (let i = output_shape.length - 1, s = 1; i >= 0; i--) { + out_strides[i] = s; + s *= output_shape[i]; + } + + for (let i = 0; i < size; i++) { + let idx = i; + let input_idx = 0; + for (let d = 0; d < output_shape.length; d++) { + const stride = out_strides[d]; + const coord = Math.floor(idx / stride); + idx %= stride; + + let input_d = d; + if (d === dim0) input_d = dim1; + else if (d === dim1) input_d = dim0; + + input_idx += coord * a_strides[input_d]; + } + data[i] = a.data[input_idx]; + } + + return new Tensor( + data, + { requires_grad: a.requires_grad }, + { operation: operation, shape: output_shape } + ); +} +export class Transpose extends TorchFunction { + private dim0: number; + private dim1: number; + protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + this.dim0 = dim0; + this.dim1 = dim1; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + return _transpose_tensor(a, dim0, dim1, this); + } + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const dim0 = this.dim0; + const dim1 = this.dim1; + const [aFn] = this.next_functions; + + // backward_operations: + aFn.backward(dz.transpose(dim0, dim1)); + } +} +registerOperation('transpose', Transpose); + +function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { + if (a.shape.length == 1 && b.shape.length == 1) { + return a.mul(b).sum(); + } + + const a_1d = a.shape.length == 1; + const b_1d = b.shape.length == 1; + + const a_shape = a_1d ? [1, a.shape[0]] : a.shape; + const b_shape = b_1d ? [b.shape[0], 1] : b.shape; + + if (a_shape[a_shape.length - 1] != b_shape[b_shape.length - 2]) { + throw new Error('Shape mismatch: ' + a.shape + ' and ' + b.shape); + } + + const broadcast_shape = _broadcast_shape(a_shape.slice(0, -2), b_shape.slice(0, -2)).concat([ + a_shape[a_shape.length - 2], + b_shape[b_shape.length - 1] + ]); + + const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); + const data = new Array(output_size).fill(0); + + const padded_a_shape = _pad_shape(a_shape, broadcast_shape); + const padded_b_shape = _pad_shape(b_shape, broadcast_shape); + + const dim_M = broadcast_shape[broadcast_shape.length - 2]; + const dim_N = broadcast_shape[broadcast_shape.length - 1]; + const dim_K = a_shape[a_shape.length - 1]; // or b_shape[b_shape.length - 2] + + for (let i = 0; i < output_size; i++) { + const mn_idx = i % (dim_M * dim_N); + const m = Math.floor(mn_idx / dim_N); + const n = mn_idx % dim_N; + + let base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n); + let base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N); + + let sum = 0; + for (let k = 0; k < dim_K; k++) { + sum += a.data[base_a + k] * b.data[base_b + k * dim_N]; + } + data[i] = sum; + } + + let shape_after_removing_extra_dims = [...broadcast_shape]; + + if (a_1d) { + shape_after_removing_extra_dims = shape_after_removing_extra_dims + .slice(0, -2) + .concat([broadcast_shape[broadcast_shape.length - 1]]); + } + + if (b_1d) { + shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1); + } + + return new Tensor( + data, + { requires_grad: a.requires_grad || b.requires_grad }, + { operation: operation, shape: shape_after_removing_extra_dims } + ); +} +// class generated from matmul_op_class() +export class Matmul extends BinaryFunction { + protected _forward(a: Tensor, b: Tensor): Tensor { + if (a.requires_grad || b.requires_grad) { + this.saved_tensors = [a, b]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); + return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); + } + protected _backward(dz: Tensor): void { + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; + + // backward_operations: + if (a.shape.length == 1 && b.shape.length == 1) { + aFn.backward(dz); + bFn.backward(dz); + return; + } + + if (a.shape.length == 1) { + const dz1 = dz.unsqueeze(0); + const a1 = a.unsqueeze(0); + aFn.backward(dz1.matmul(b.transpose(-2, -1))); + bFn.backward(a1.transpose(0, 1).matmul(dz1)); + return; + } + + if (b.shape.length == 1) { + const dz1 = dz.unsqueeze(0); + const b1 = b.unsqueeze(1); + aFn.backward(dz1.matmul(b1.transpose(0, 1))); + bFn.backward(a.transpose(-2, -1).matmul(dz1)); + return; + } + + aFn.backward(dz.matmul(b.transpose(-2, -1))); + bFn.backward(a.transpose(-2, -1).matmul(dz)); + } +} +registerOperation('matmul', Matmul); + +// comparison + +const Lt = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] < b[b_index]) ? 1 : 0, + (a, b, aFn, bFn) => {}, + "lt" +); + +const Gt = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] > b[b_index]) ? 1 : 0, + (a, b, aFn, bFn) => {}, + "gt" +); + +const Le = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] <= b[b_index]) ? 1 : 0, + (a, b, aFn, bFn) => {}, + "le" +); + +const Ge = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] >= b[b_index]) ? 1 : 0, + (a, b, aFn, bFn) => {}, + "ge" +); + +const Eq = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] == b[b_index]) ? 1 : 0, + (a, b, aFn, bFn) => {}, + "eq" +); + +const Ne = BinaryFunctionMixin( + (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] != b[b_index]) ? 1 : 0, + (a, b, aFn, bFn) => {}, + "ne" +); diff --git a/src/functions/ops.ts.j2 b/src/functions/ops.ts.j2 deleted file mode 100644 index 0d855fb8..00000000 --- a/src/functions/ops.ts.j2 +++ /dev/null @@ -1,217 +0,0 @@ -{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class, kernel_options, powint_op_base, powint_op_class, transpose_op_base, transpose_op_class, matmul_op_base, matmul_op_class %} -import { Tensor } from '../tensor'; -import { - _broadcast_shape, - _get_original_index_from_transposed_index, - _get_original_index, - _get_original_index_kernel, - _pad_shape -} from '../broadcasting'; -import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; -import * as functional from './functional'; -import { registerOperation } from './registry'; -import { zeros_like } from '../creation'; - -// debug operations - -{{ binary_op_base("__left_index__", "a_index") }} -{{ binary_op_class("__Left_index__", "__left_index__", []) }} - -{{ binary_op_base("__right_index__", "b_index") }} -{{ binary_op_class("__Right_index__", "__right_index__", []) }} - -// binary pointwise - -{{ binary_op_base("add", "a[a_index] + b[b_index]") }} -{{ binary_op_class("Add", "add", ["aFn.backward(dz);", "bFn.backward(dz);"]) }} - -{{ binary_op_base("sub", "a[a_index] - b[b_index]") }} -{{ binary_op_class("Sub", "sub", ["aFn.backward(dz);", "bFn.backward(dz.mul(new Tensor(-1)));"]) }} - -{{ binary_op_base("mul", "a[a_index] * b[b_index]") }} -{{ binary_op_class("Mul", "mul", ["aFn.backward(dz.mul(b));", "bFn.backward(dz.mul(a));"]) }} - -{{ binary_op_base("div", "a[a_index] / b[b_index]") }} -{{ binary_op_class("Div", "div", ["aFn.backward(dz.div(b));", "bFn.backward(dz.mul(a).mul(new Tensor(-1)).div(b).div(b));"]) }} - -{{ binary_op_base("pow", "Math.pow(a[a_index], b[b_index])") }} -{{ binary_op_class("Pow", "pow", [ - "aFn.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))));", - "bFn.backward(dz.mul(a.pow(b)).mul(a.log()));" -])}} - -{{ binary_op_base("fmod", "a[a_index] % b[b_index]") }} -{{ binary_op_class("Fmod", "fmod", ["aFn.backward(dz);"]) }} - -{{ binary_op_base("maximum", "Math.max(a[a_index], b[b_index])") }} -{{ binary_op_class("Maximum", "maximum", ["aFn.backward(dz.mul(a.ge(b)));", "bFn.backward(dz.mul(b.gt(a)));"]) }} - -{{ binary_op_base("minimum", "Math.min(a[a_index], b[b_index])") }} -{{ binary_op_class("Minimum", "minimum", ["aFn.backward(dz.mul(a.le(b)));", "bFn.backward(dz.mul(b.lt(a)));"]) }} - - -{{ powint_op_base() }} -{{ powint_op_class() }} - -// unary pointwise - -{{ unary_op_base("log", "Math.log(a[x])") }} -{{ unary_op_class("Log", "log", ["aFn.backward(new Tensor(1).div(a));"]) }} - -{{ unary_op_base("sqrt", "Math.sqrt(a[x])") }} -{{ unary_op_class("Sqrt", "sqrt", ["aFn.backward(new Tensor(1).div(a.sqrt()).div(2));"]) }} - -{{ unary_op_base("exp", "Math.exp(a[x])") }} -{{ unary_op_class("Exp", "exp", ["aFn.backward(dz.mul(a.exp()));"]) }} - -{{ unary_op_base("square", "a[x] * a[x]") }} -{{ unary_op_class("Square", "square", ["aFn.backward(dz.mul(a).mul(new Tensor(2)));"]) }} - -{{ unary_op_base("abs", "Math.abs(a[x])") }} -{{ unary_op_class("Abs", "abs", ["aFn.backward(dz.mul(functional.sign(a)));"]) }} - -{{ unary_op_base("sign", "Math.sign(a[x])") }} -{{ unary_op_class("Sign", "sign", []) }} - -{{ unary_op_base("neg", "-a[x]") }} -{{ unary_op_class("Neg", "neg", ["aFn.backward(dz.mul(new Tensor(-1)));"]) }} - -{{ unary_op_base("reciprocal", "1 / a[x]") }} -{{ unary_op_class("Reciprocal", "reciprocal", ["aFn.backward(dz.mul(a.pow(-2)));"]) }} - -export class Reshape extends TorchFunction { - protected _forward(a: Tensor, shape: number[]) { - const previous_length = a.dataLength(); - const target_length = shape.reduce((acc, val) => acc * val, 1); - - if (previous_length !== target_length) { - throw new Error('Shape mismatch: ' + a.shape + ' and ' + shape); - } - - if (a.requires_grad) { - this.saved_tensors = [a]; - } - if (a.grad_fn) { - this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); - } else { - this.next_functions.push(nullOp); - } - - return new Tensor( - a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } - ); - } - protected _backward(dz: Tensor) { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.reshape(a.shape)); - } -} -registerOperation('reshape', Reshape); - -export class Unsqueeze extends TorchFunction { - protected _forward(a: Tensor, dim: number) { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - if (a.grad_fn) { - this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); - } else { - this.next_functions.push(nullOp); - } - - if (dim < 0) { - dim += a.shape.length + 1; - } - - const shape = [...a.shape]; - shape.splice(dim, 0, 1); - - return new Tensor( - a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } - ); - } - protected _backward(dz: Tensor) { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.reshape(a.shape)); - } -} -registerOperation('unsqueeze', Unsqueeze); - -// trigonometric - -{{ unary_op_base("sin", "Math.sin(a[x])") }} -{{ unary_op_class("Sin", "sin", ["aFn.backward(dz.mul(a.cos()));"]) }} - -{{ unary_op_base("cos", "Math.cos(a[x])") }} -{{ unary_op_class("Cos", "cos", ["aFn.backward(dz.mul(a.sin().neg()));"]) }} - -{{ unary_op_base("tan", "Math.tan(a[x])") }} -{{ unary_op_class("Tan", "tan", ["aFn.backward(dz.mul(a.cos().pow(-2)));"]) }} - -// reduction - -function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - return new Tensor( - a.toArray().reduce((acc, val) => acc + val, 0), - { requires_grad: a.requires_grad }, - { operation: operation } - ); -} - -{{ unary_op_class("Sum", "sum", ["aFn.backward(zeros_like(a).add(dz.item()));"]) }} - -function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - return new Tensor( - a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), - { requires_grad: a.requires_grad }, - { operation: operation } - ); -} - -{{ unary_op_class("Mean", "mean", ["aFn.backward(zeros_like(a).add(dz.item() / a.dataLength()));"]) }} - -// linalg - -{{ transpose_op_base() }} -{{ transpose_op_class() }} - -{{ matmul_op_base() }} -{{ matmul_op_class() }} - -// comparison - -{{ binary_op_base("lt", "(a[a_index] < b[b_index]) ? 1 : 0") }} -{{ binary_op_class("Lt", "lt", []) }} - -{{ binary_op_base("gt", "(a[a_index] > b[b_index]) ? 1 : 0") }} -{{ binary_op_class("Gt", "gt", []) }} - -{{ binary_op_base("le", "(a[a_index] <= b[b_index]) ? 1 : 0") }} -{{ binary_op_class("Le", "le", []) }} - -{{ binary_op_base("ge", "(a[a_index] >= b[b_index]) ? 1 : 0") }} -{{ binary_op_class("Ge", "ge", []) }} - -{{ binary_op_base("eq", "(a[a_index] == b[b_index]) ? 1 : 0") }} -{{ binary_op_class("Eq", "eq", []) }} - -{{ binary_op_base("ne", "(a[a_index] != b[b_index]) ? 1 : 0") }} -{{ binary_op_class("Ne", "ne", []) }} diff --git a/src/index.ts b/src/index.ts index 4b14ba6a..33e11617 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ export { Tensor } from './tensor'; export { TorchFunction, AccumulateGrad } from './functions/base'; -export * from './functions/ops.gen'; +export * from './functions/ops'; export * from './functions/functional'; export * from './creation/index'; diff --git a/src/nn/index.ts b/src/nn/index.ts index 20331f75..d30c86cd 100644 --- a/src/nn/index.ts +++ b/src/nn/index.ts @@ -1,4 +1,4 @@ -import './ops.gen'; +import './ops'; export * from './module'; export * from './loss'; diff --git a/src/nn/ops.gen.ts b/src/nn/ops.gen.ts deleted file mode 100644 index 28b0e849..00000000 --- a/src/nn/ops.gen.ts +++ /dev/null @@ -1,88 +0,0 @@ -// This file is generated by scripts/generate_script.py from src/nn/ops.ts.j2 -import { Tensor } from '../tensor'; -import { - _broadcast_shape, - _get_original_index_from_transposed_index, - _get_original_index_kernel, - _pad_shape -} from '../broadcasting'; -import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from '../functions/base'; -import { registerOperation } from '../functions/registry'; - -// function generated from unary_op_base("relu", "Math.max(a[x], 0)") - -const _relu_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = Math.max(a[x], 0); - } - return res; -}; - -function _relu_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _relu_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Relu", "relu", backward_operations) -export class Relu extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _relu_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.gt(0))); - } -} -registerOperation('relu', Relu); - -// function generated from unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[x]))") - -const _sigmoid_kernel = function (a: number[], output: number) { - const res = new Array(output); - for (let x = 0; x < output; x++) { - res[x] = 1 / (1 + Math.exp(-a[x])); - } - return res; -}; - -function _sigmoid_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - const kernel = _sigmoid_kernel; - const output = a.shape.reduce((acc, val) => acc * val, 1); - - return new Tensor( - kernel(a.data, output) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); -} -// class generated from unary_op_class("Sigmoid", "sigmoid", backward_operations) -export class Sigmoid extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _sigmoid_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; - - // backward_operations: - aFn.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1))); - } -} -registerOperation('sigmoid', Sigmoid); \ No newline at end of file diff --git a/src/nn/ops.ts b/src/nn/ops.ts new file mode 100644 index 00000000..c2c042b3 --- /dev/null +++ b/src/nn/ops.ts @@ -0,0 +1,17 @@ +import { UnaryFunctionMixin } from '../functions/mixin'; + +const Relu = UnaryFunctionMixin( + (a: number[], x: number) => Math.max(a[x], 0), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.gt(0)))); + }, + "relu" +); + +const Sigmoid = UnaryFunctionMixin( + (a: number[], x: number) => 1 / (1 + Math.exp(-a[x])), + (a, aFn, dz) => { + aFn.backward(dz.mul(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)))); + }, + "sigmoid" +); diff --git a/src/nn/ops.ts.j2 b/src/nn/ops.ts.j2 deleted file mode 100644 index 8ac2d1d6..00000000 --- a/src/nn/ops.ts.j2 +++ /dev/null @@ -1,16 +0,0 @@ -{% from 'scripts/macros.ts.j2' import binary_op_base, unary_op_base, binary_op_class, unary_op_class %} -import { Tensor } from '../tensor'; -import { - _broadcast_shape, - _get_original_index_from_transposed_index, - _get_original_index_kernel, - _pad_shape -} from '../broadcasting'; -import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from '../functions/base'; -import { registerOperation } from '../functions/registry'; - -{{ unary_op_base("relu", "Math.max(a[x], 0)") }} -{{ unary_op_class("Relu", "relu", ["aFn.backward(dz.mul(a.gt(0)));"]) }} - -{{ unary_op_base("sigmoid", "1 / (1 + Math.exp(-a[x]))") }} -{{ unary_op_class("Sigmoid", "sigmoid", ["aFn.backward(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)));"]) }} diff --git a/test.py b/test.py new file mode 100644 index 00000000..e17ff8c3 --- /dev/null +++ b/test.py @@ -0,0 +1,12 @@ +import torch + +x = torch.nn.Linear(2, 3) +with torch.no_grad(): + x.weight.copy_(torch.tensor([[1, 2], [3, 4], [5, 6]], dtype=torch.float32)) + x.bias.copy_(torch.tensor([1, 2, 3], dtype=torch.float32)) + +input = torch.tensor([1, 2], dtype=torch.float32) +output = x(input).sum() +output.backward() +print(x.weight.grad) +print(x.bias.grad) \ No newline at end of file From af152f7a05d960f1cee6b6afa3f02c49ffc0a859 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sun, 8 Mar 2026 16:59:57 +0800 Subject: [PATCH 074/128] feat: automated testing --- package.json | 1 + scripts/generate_tests.py | 50 + scripts/requirements.txt | 1 + src/functions/ops.ts | 9 +- src/nn/ops.ts | 3 +- src/tensor.ts | 35 +- test/broadcast.test.js | 8 +- test/custom_operations.test.js | 16 +- test/functional.test.js | 18 +- test/generated.test.js | 50 + test/nn_functional.test.js | 2 +- test/tensor.test.js | 40 +- test/tensor_ops_data.gen.js | 3033 ++++++++++++++++++++++++++++++++ vite.config.node.ts | 2 +- 14 files changed, 3218 insertions(+), 50 deletions(-) create mode 100644 scripts/generate_tests.py create mode 100644 scripts/requirements.txt create mode 100644 test/generated.test.js create mode 100644 test/tensor_ops_data.gen.js diff --git a/package.json b/package.json index 66ca86c4..72e264fe 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "serve": "http-server -p 8080 -c-1", "test": "mocha test/**/*.test.ts test/**/*.test.js", "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js", + "update-tests": "python3 scripts/generate_tests.py > test/tensor_ops_data.gen.js", "watch": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\"" }, "devDependencies": { diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py new file mode 100644 index 00000000..e29e5f9e --- /dev/null +++ b/scripts/generate_tests.py @@ -0,0 +1,50 @@ +import torch +import json + +UNARY_OPS = ['exp', 'square', 'abs', 'sign', 'neg', 'reciprocal', 'sin', 'cos', 'tan'] +BINARY_OPS = ['add', 'sub', 'mul', 'div', 'maximum', 'minimum'] + +torch.manual_seed(42) + +def generate_unary_tests(op_name, num_tests=3): + tests = [] + for i in range(num_tests): + x = torch.randn(3, 3, requires_grad=True) + torch_op = getattr(torch, op_name) + y = torch_op(x) + y.sum().backward() + + tests.append({ + "input": x.detach().numpy().tolist(), + "expected_output": y.detach().numpy().tolist(), + "expected_grad": x.grad.numpy().tolist() + }) + return tests + +def generate_binary_tests(op_name, num_tests=3): + tests = [] + for i in range(num_tests): + x = torch.randn(3, 3, requires_grad=True) + y = torch.randn(3, 3, requires_grad=True) + + torch_op = getattr(torch, op_name) + out = torch_op(x, y) + out.sum().backward() + + tests.append({ + "input_x": x.detach().numpy().tolist(), + "input_y": y.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_x": x.grad.numpy().tolist(), + "expected_grad_y": y.grad.numpy().tolist() + }) + return tests + +if __name__ == "__main__": + suite = { + "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, + "binary": {op: generate_binary_tests(op) for op in BINARY_OPS} + } + + print("export const testData = ", end="") + print(json.dumps(suite, indent=2), end=";\n") \ No newline at end of file diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 00000000..f60a2ca9 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1 @@ +torch==2.10.0 \ No newline at end of file diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 58926cbb..1149b63a 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -178,8 +178,7 @@ const Abs = UnaryFunctionMixin( const Sign = UnaryFunctionMixin( (a: number[], x: number) => Math.sign(a[x]), (a, aFn, dz) => { - // TODO: check - aFn.backward(dz.mul(dz.mul(functional.sign(a)))); + aFn.backward(0); }, "sign" ); @@ -195,7 +194,7 @@ const Neg = UnaryFunctionMixin( const Reciprocal = UnaryFunctionMixin( (a: number[], x: number) => 1 / a[x], (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.pow(-2)))); + aFn.backward(dz.mul(dz.mul(a.pow(-2))).neg()); }, "reciprocal" ); @@ -306,7 +305,7 @@ const Tan = UnaryFunctionMixin( function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { return new Tensor( - a.toArray().reduce((acc, val) => acc + val, 0), + a.toFlatArray().reduce((acc, val) => acc + val, 0), { requires_grad: a.requires_grad }, { operation: operation } ); @@ -332,7 +331,7 @@ registerOperation('sum', Sum); function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { return new Tensor( - a.toArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), + a.toFlatArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), { requires_grad: a.requires_grad }, { operation: operation } ); diff --git a/src/nn/ops.ts b/src/nn/ops.ts index c2c042b3..a0d1bc76 100644 --- a/src/nn/ops.ts +++ b/src/nn/ops.ts @@ -11,7 +11,8 @@ const Relu = UnaryFunctionMixin( const Sigmoid = UnaryFunctionMixin( (a: number[], x: number) => 1 / (1 + Math.exp(-a[x])), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.exp().add(1).pow(-2).reciprocal().mul(a.exp()).mul(-1)))); + const res = a.sigmoid(); + aFn.backward(res.mul(res.mul(-1).add(1)).mul(dz)); }, "sigmoid" ); diff --git a/src/tensor.ts b/src/tensor.ts index a6bf79b4..872695b9 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -93,10 +93,37 @@ export class Tensor { return; } - toArray(): number[] { + toFlatArray(): number[] { return this.data; } + toArray(): NestedNumberArray { + if (this.shape.length === 0) { + return this.data[0]; + } + + let flatIndex = 0; + const flatData = this.data; + + const buildDimension = (currentDim: number): any[] => { + const size = this.shape[currentDim]; + const result = new Array(size); + const isLastDimension = currentDim === this.shape.length - 1; + + for (let i = 0; i < size; i++) { + if (isLastDimension) { + result[i] = flatData[flatIndex++]; + } else { + result[i] = buildDimension(currentDim + 1); + } + } + + return result; + }; + + return buildDimension(0); + } + dataLength(): number { return this.data.length; } @@ -317,4 +344,10 @@ export class Tensor { ne(other: Tensor | number): Tensor { return this._executeBinaryOp('ne', other); } + + // other + + sigmoid(): Tensor { + return this._executeUnaryOp('sigmoid'); + } } diff --git a/test/broadcast.test.js b/test/broadcast.test.js index 0d8033ab..359bae58 100644 --- a/test/broadcast.test.js +++ b/test/broadcast.test.js @@ -9,8 +9,8 @@ describe('Broadcast Index', () => { [0, 0] ]); - assert.deepStrictEqual(__left_index__(arr, arr).toArray(), [0, 1, 2, 3, 4, 5]); - assert.deepStrictEqual(__right_index__(arr, arr).toArray(), [0, 1, 2, 3, 4, 5]); + assert.deepStrictEqual(__left_index__(arr, arr).toFlatArray(), [0, 1, 2, 3, 4, 5]); + assert.deepStrictEqual(__right_index__(arr, arr).toFlatArray(), [0, 1, 2, 3, 4, 5]); }); it('Should get correct value of left and right index', () => { @@ -26,7 +26,7 @@ describe('Broadcast Index', () => { [0, 0] ]) - assert.deepStrictEqual(add(arr, zeros).toArray(), [1, 2, 3, 4, 5, 6]); - assert.deepStrictEqual(add(zeros, arr).toArray(), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(add(arr, zeros).toFlatArray(), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(add(zeros, arr).toFlatArray(), [1, 2, 3, 4, 5, 6]); }); }); \ No newline at end of file diff --git a/test/custom_operations.test.js b/test/custom_operations.test.js index 6b74fecc..409be47b 100644 --- a/test/custom_operations.test.js +++ b/test/custom_operations.test.js @@ -17,7 +17,7 @@ describe('Custom Operations', () => { const result = t1.matmul(t2); assert.deepStrictEqual(result.shape, [2, 2]); - assert.deepStrictEqual(Array.from(result.toArray()), [31, 19, 85, 55]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [31, 19, 85, 55]); }); it('should perform matrix multiplication on 2D tensors (2)', () => { @@ -36,7 +36,7 @@ describe('Custom Operations', () => { const expected = [36, 32, 25, 96, 86, 55]; - assert.deepStrictEqual(Array.from(result.toArray()), expected); + assert.deepStrictEqual(Array.from(result.toFlatArray()), expected); assert.deepStrictEqual(result.shape, [2, 3]); }); @@ -46,7 +46,7 @@ describe('Custom Operations', () => { const result = t1.matmul(t2); assert.deepStrictEqual(result.shape, [1]); - assert.deepStrictEqual(Array.from(result.toArray()), [32]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [32]); }); it('should handle batch matrix multiplication', () => { @@ -62,7 +62,7 @@ describe('Custom Operations', () => { const result = t1.matmul(t2); assert.deepStrictEqual(result.shape, [2, 2, 2]); - const data = Array.from(result.toArray()); + const data = Array.from(result.toFlatArray()); assert.deepStrictEqual(data, [9026, 4236, 3813, 4314, 2363, 5074, 8831, 13874]); }); @@ -80,10 +80,10 @@ describe('Custom Operations', () => { const result = t1.matmul(t2); result.sum().backward(); - const t1Grad = Array.from(t1.grad.toArray()); + const t1Grad = Array.from(t1.grad.toFlatArray()); assert.deepStrictEqual(t1Grad, [11, 15, 11, 15]); - const t2Grad = Array.from(t2.grad.toArray()); + const t2Grad = Array.from(t2.grad.toFlatArray()); assert.deepStrictEqual(t2Grad, [4, 4, 6, 6]); }); }); @@ -97,7 +97,7 @@ describe('Custom Operations', () => { const result = t.transpose(0, 1); assert.deepStrictEqual(result.shape, [3, 2]); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 4, 2, 5, 3, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 4, 2, 5, 3, 6]); }); it('should transpose dimensions in a 3D tensor', () => { @@ -108,7 +108,7 @@ describe('Custom Operations', () => { const result = t.transpose(1, 2); assert.deepStrictEqual(result.shape, [2, 2, 2]); - const data = Array.from(result.toArray()); + const data = Array.from(result.toFlatArray()); assert.deepStrictEqual(data, [1, 3, 2, 4, 5, 7, 6, 8]); }); diff --git a/test/functional.test.js b/test/functional.test.js index 1c1ab178..754e2003 100644 --- a/test/functional.test.js +++ b/test/functional.test.js @@ -9,7 +9,7 @@ describe('Functional', () => { const t2 = new Tensor([20]); const result = torch.add(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [30]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [30]); assert.deepStrictEqual(result.shape, [1]); }); @@ -18,7 +18,7 @@ describe('Functional', () => { const t2 = new Tensor([1]); const result = torch.add(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [11, 21, 31]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [11, 21, 31]); assert.deepStrictEqual(result.shape, [3]); }); @@ -27,7 +27,7 @@ describe('Functional', () => { const t2 = new Tensor([4, 5, 6]); const result = torch.add(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [5, 7, 9]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [5, 7, 9]); assert.deepStrictEqual(result.shape, [3]); }); }); @@ -38,7 +38,7 @@ describe('Functional', () => { const t2 = new Tensor([20]); const result = torch.mul(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [200]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [200]); assert.deepStrictEqual(result.shape, [1]); }); }); @@ -49,7 +49,7 @@ describe('Functional', () => { const t2 = new Tensor([1]); const result = torch.mul(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [10, 20, 30]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [10, 20, 30]); assert.deepStrictEqual(result.shape, [3]); }); }); @@ -60,7 +60,7 @@ describe('Functional', () => { const t2 = new Tensor([20]); const result = torch.matmul(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [200]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [200]); assert.deepStrictEqual(result.shape, [1]); }); @@ -69,7 +69,7 @@ describe('Functional', () => { const t2 = new Tensor([5, 6, 7, 8]); const result = torch.matmul(t1, t2); - assert.deepStrictEqual(Array.from(result.toArray()), [70]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [70]); assert.deepStrictEqual(result.shape, [1]); }); @@ -89,7 +89,7 @@ describe('Functional', () => { const expected = [36, 32, 25, 96, 86, 55]; - assert.deepStrictEqual(Array.from(result.toArray()), expected); + assert.deepStrictEqual(Array.from(result.toFlatArray()), expected); assert.deepStrictEqual(result.shape, [2, 3]); }); @@ -116,7 +116,7 @@ describe('Functional', () => { [3, 4] ]); const result = t.transpose(0, 1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 3, 2, 4]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 3, 2, 4]); assert.deepStrictEqual(result.shape, [2, 2]); }); }); diff --git a/test/generated.test.js b/test/generated.test.js new file mode 100644 index 00000000..d4eef78a --- /dev/null +++ b/test/generated.test.js @@ -0,0 +1,50 @@ +import { Tensor } from 'torch'; +import { assert } from 'chai'; +import { testData } from './tensor_ops_data.gen'; + +function assertDeepCloseTo(actual, expected, delta = 1e-3) { + if (Array.isArray(expected)) { + assert.lengthOf(actual, expected.length, 'Array lengths do not match'); + for (let i = 0; i < expected.length; i++) { + assertDeepCloseTo(actual[i], expected[i], delta); + } + } else { + assert.closeTo(actual, expected, delta); + } +} + +describe('Automated Tests', () => { + describe('Unary Operations', () => { + for (const [opName, tests] of Object.entries(testData.unary)) { + describe(`.${opName}()`, () => { + tests.forEach((test, idx) => { + it(`case ${idx + 1}`, () => { + const x = new Tensor(test.input, { requires_grad: true }); + const y = (x)[opName](); + assertDeepCloseTo(y.toArray(), test.expected_output); + y.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + }); + }); + }); + } + }); + + describe('Binary Operations', () => { + for (const [opName, tests] of Object.entries(testData.binary)) { + describe(`.${opName}()`, () => { + tests.forEach((test, idx) => { + it(`case ${idx + 1}`, () => { + const x = new Tensor(test.input_x, { requires_grad: true }); + const y = new Tensor(test.input_y, { requires_grad: true }); + const out = (x)[opName](y); + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + }); + }); + }); + } + }); +}); \ No newline at end of file diff --git a/test/nn_functional.test.js b/test/nn_functional.test.js index 2dbdf18a..df21a8d5 100644 --- a/test/nn_functional.test.js +++ b/test/nn_functional.test.js @@ -6,7 +6,7 @@ describe('NN Functional', () => { it('should forward a tensor', () => { const x = new torch.Tensor([1, -2, 3, -4, 5]); const result = torch.nn.functional.relu(x); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 0, 3, 0, 5]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 0, 3, 0, 5]); assert.deepStrictEqual(result.shape, [5]); }); }); diff --git a/test/tensor.test.js b/test/tensor.test.js index 8353279b..7640e456 100644 --- a/test/tensor.test.js +++ b/test/tensor.test.js @@ -37,7 +37,7 @@ describe('Tensor', () => { it('should reshape a tensor', () => { const t = new Tensor([1, 2, 3, 4]); const result = t.reshape([2, 2]); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4]); assert.deepStrictEqual(result.shape, [2, 2]); }); @@ -49,19 +49,19 @@ describe('Tensor', () => { it('should reshape a tensor with different dimensions', () => { const t = new Tensor([1, 2, 3, 4, 5, 6]); const result = t.reshape([2, 3]); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [2, 3]); const result2 = t.reshape([3, 2]); - assert.deepStrictEqual(Array.from(result2.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result2.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result2.shape, [3, 2]); const result3 = t.reshape([6]); - assert.deepStrictEqual(Array.from(result3.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result3.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result3.shape, [6]); const result4 = t.reshape([1, 2, 3]); - assert.deepStrictEqual(Array.from(result4.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result4.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result4.shape, [1, 2, 3]); }); }); @@ -70,44 +70,44 @@ describe('Tensor', () => { it('should unsqueeze a tensor', () => { const t = new Tensor([1, 2, 3]); let result = t.unsqueeze(0); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3]); assert.deepStrictEqual(result.shape, [1, 3]); let s = new Tensor([1, 2, 3, 4, 5, 6]); s = s.reshape([2, 3]); result = s.unsqueeze(0); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [1, 2, 3]); result = s.unsqueeze(1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [2, 1, 3]); result = s.unsqueeze(2); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [2, 3, 1]); }); it('should unsqueeze a tensor with negative dimension', () => { const t = new Tensor([1, 2, 3]); let result = t.unsqueeze(-1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3]); assert.deepStrictEqual(result.shape, [3, 1]); let s = new Tensor([1, 2, 3, 4, 5, 6]); s = s.reshape([2, 3]); result = s.unsqueeze(-3); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [1, 2, 3]); result = s.unsqueeze(-2); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [2, 1, 3]); result = s.unsqueeze(-1); - assert.deepStrictEqual(Array.from(result.toArray()), [1, 2, 3, 4, 5, 6]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [1, 2, 3, 4, 5, 6]); assert.deepStrictEqual(result.shape, [2, 3, 1]); }); }); @@ -122,7 +122,7 @@ describe('Operations', () => { const t2 = new Tensor([20]); const result = t1.add(t2); - assert.deepStrictEqual(Array.from(result.toArray()), [30]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [30]); assert.deepStrictEqual(result.shape, [1]); }); @@ -131,7 +131,7 @@ describe('Operations', () => { const t2 = new Tensor([4, 5, 6]); const result = t1.add(t2); - assert.deepStrictEqual(Array.from(result.toArray()), [5, 7, 9]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [5, 7, 9]); assert.deepStrictEqual(result.shape, [3]); }); }); @@ -142,7 +142,7 @@ describe('Operations', () => { const t2 = new Tensor([20]); const result = t1.mul(t2); - assert.deepStrictEqual(Array.from(result.toArray()), [200]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [200]); assert.deepStrictEqual(result.shape, [1]); }); @@ -151,7 +151,7 @@ describe('Operations', () => { const t2 = new Tensor([0.756]); const result = t1.mul(t2); - assert.closeTo(Array.from(result.toArray())[0], -0.8016, 0.001); + assert.closeTo(Array.from(result.toFlatArray())[0], -0.8016, 0.001); assert.deepStrictEqual(result.shape, [1]); }); @@ -223,7 +223,7 @@ describe('Operations', () => { const t2 = new Tensor([1]); const result = t1.mul(t2); - assert.deepStrictEqual(Array.from(result.toArray()), [10, 20, 30]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [10, 20, 30]); assert.deepStrictEqual(result.shape, [3]); }); it('should add tensors with different shapes (broadcasting)', () => { @@ -231,7 +231,7 @@ describe('Operations', () => { const t2 = new Tensor([1]); const result = t1.add(t2); - assert.deepStrictEqual(Array.from(result.toArray()), [11, 21, 31]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [11, 21, 31]); assert.deepStrictEqual(result.shape, [3]); }); }); @@ -241,7 +241,7 @@ describe('Operations', () => { it('should negate a tensor', () => { const t = new Tensor([1, 2, 3, -4]); const result = t.neg(); - assert.deepStrictEqual(Array.from(result.toArray()), [-1, -2, -3, 4]); + assert.deepStrictEqual(Array.from(result.toFlatArray()), [-1, -2, -3, 4]); assert.deepStrictEqual(result.shape, [4]); }); }); diff --git a/test/tensor_ops_data.gen.js b/test/tensor_ops_data.gen.js new file mode 100644 index 00000000..43d9fa22 --- /dev/null +++ b/test/tensor_ops_data.gen.js @@ -0,0 +1,3033 @@ +export const testData = { + "unary": { + "exp": [ + { + "input": [ + [ + 0.33669036626815796, + 0.12880940735340118, + 0.23446236550807953 + ], + [ + 0.23033303022384644, + -1.1228563785552979, + -0.18632829189300537 + ], + [ + 2.2082014083862305, + -0.637997031211853, + 0.46165722608566284 + ] + ], + "expected_output": [ + [ + 1.4003053903579712, + 1.1374733448028564, + 1.2642289400100708 + ], + [ + 1.2590192556381226, + 0.3253491520881653, + 0.8300010561943054 + ], + [ + 9.099335670471191, + 0.5283496379852295, + 1.5867012739181519 + ] + ], + "expected_grad": [ + [ + 1.4003053903579712, + 1.1374733448028564, + 1.2642289400100708 + ], + [ + 1.2590192556381226, + 0.3253491520881653, + 0.8300010561943054 + ], + [ + 9.099335670471191, + 0.5283496379852295, + 1.5867012739181519 + ] + ] + }, + { + "input": [ + [ + 0.2673508822917938, + 0.5349046587944031, + 0.809357225894928 + ], + [ + 1.110290288925171, + -1.6897989511489868, + -0.9889599084854126 + ], + [ + 0.9579718112945557, + 1.322135090827942, + 0.8171897530555725 + ] + ], + "expected_output": [ + [ + 1.3064987659454346, + 1.7072854042053223, + 2.2464635372161865 + ], + [ + 3.0352394580841064, + 0.18455661833286285, + 0.37196338176727295 + ], + [ + 2.6064047813415527, + 3.75142240524292, + 2.2641282081604004 + ] + ], + "expected_grad": [ + [ + 1.3064987659454346, + 1.7072854042053223, + 2.2464635372161865 + ], + [ + 3.0352394580841064, + 0.18455661833286285, + 0.37196338176727295 + ], + [ + 2.6064047813415527, + 3.75142240524292, + 2.2641282081604004 + ] + ] + }, + { + "input": [ + [ + -0.765838623046875, + -0.7506223320960999, + 1.3525477647781372 + ], + [ + 0.6863219141960144, + -0.32775864005088806, + 0.7949687242507935 + ], + [ + 0.2815195620059967, + 0.056163541972637177, + 0.5227160453796387 + ] + ], + "expected_output": [ + [ + 0.46494385600090027, + 0.47207266092300415, + 3.8672659397125244 + ], + [ + 1.9863959550857544, + 0.7205368876457214, + 2.214371681213379 + ], + [ + 1.3251419067382812, + 1.0577706098556519, + 1.6866023540496826 + ] + ], + "expected_grad": [ + [ + 0.46494385600090027, + 0.47207266092300415, + 3.8672659397125244 + ], + [ + 1.9863959550857544, + 0.7205368876457214, + 2.214371681213379 + ], + [ + 1.3251419067382812, + 1.0577706098556519, + 1.6866023540496826 + ] + ] + } + ], + "square": [ + { + "input": [ + [ + -0.23835687339305878, + -0.049903348088264465, + 0.5263369679450989 + ], + [ + -0.008498823270201683, + 0.7290605902671814, + 0.13314196467399597 + ], + [ + 0.8639776706695557, + -1.0156747102737427, + -0.8887485265731812 + ] + ], + "expected_output": [ + [ + 0.05681400001049042, + 0.002490344224497676, + 0.2770306169986725 + ], + [ + 7.222999556688592e-05, + 0.5315293669700623, + 0.017726782709360123 + ], + [ + 0.7464573979377747, + 1.0315951108932495, + 0.7898739576339722 + ] + ], + "expected_grad": [ + [ + -0.47671374678611755, + -0.09980669617652893, + 1.0526739358901978 + ], + [ + -0.016997646540403366, + 1.4581211805343628, + 0.26628392934799194 + ], + [ + 1.7279553413391113, + -2.0313494205474854, + -1.7774970531463623 + ] + ] + }, + { + "input": [ + [ + 0.14977970719337463, + -0.20889392495155334, + -0.38702094554901123 + ], + [ + 0.9912377595901489, + 0.4679030478000641, + -0.20493191480636597 + ], + [ + -0.7409071326255798, + 0.3618396520614624, + 1.9198992252349854 + ] + ], + "expected_output": [ + [ + 0.022433960810303688, + 0.04363667219877243, + 0.14978520572185516 + ], + [ + 0.9825522899627686, + 0.21893326938152313, + 0.041997089982032776 + ], + [ + 0.5489434003829956, + 0.1309279352426529, + 3.6860129833221436 + ] + ], + "expected_grad": [ + [ + 0.29955941438674927, + -0.4177878499031067, + -0.7740418910980225 + ], + [ + 1.9824755191802979, + 0.9358060956001282, + -0.40986382961273193 + ], + [ + -1.4818142652511597, + 0.7236793041229248, + 3.8397984504699707 + ] + ] + }, + { + "input": [ + [ + -0.2253875583410263, + -0.34169748425483704, + 0.3040127456188202 + ], + [ + -0.6890136003494263, + -1.1267184019088745, + -0.2857550382614136 + ], + [ + -1.0935109853744507, + 1.1351022720336914, + 0.7592452168464661 + ] + ], + "expected_output": [ + [ + 0.05079955235123634, + 0.11675716936588287, + 0.09242375195026398 + ], + [ + 0.4747397303581238, + 1.2694944143295288, + 0.08165594190359116 + ], + [ + 1.1957663297653198, + 1.2884571552276611, + 0.5764533281326294 + ] + ], + "expected_grad": [ + [ + -0.4507751166820526, + -0.6833949685096741, + 0.6080254912376404 + ], + [ + -1.3780272006988525, + -2.253436803817749, + -0.5715100765228271 + ], + [ + -2.1870219707489014, + 2.270204544067383, + 1.5184904336929321 + ] + ] + } + ], + "abs": [ + { + "input": [ + [ + -3.594468832015991, + 0.019150810316205025, + 0.1051730141043663 + ], + [ + 0.960340142250061, + -0.5671805739402771, + -0.5706474184989929 + ], + [ + 1.5980384349822998, + 0.11148621141910553, + -0.03919669985771179 + ] + ], + "expected_output": [ + [ + 3.594468832015991, + 0.019150810316205025, + 0.1051730141043663 + ], + [ + 0.960340142250061, + 0.5671805739402771, + 0.5706474184989929 + ], + [ + 1.5980384349822998, + 0.11148621141910553, + 0.03919669985771179 + ] + ], + "expected_grad": [ + [ + -1.0, + 1.0, + 1.0 + ], + [ + 1.0, + -1.0, + -1.0 + ], + [ + 1.0, + 1.0, + -1.0 + ] + ] + }, + { + "input": [ + [ + 1.4111539125442505, + -0.655610978603363, + 0.8576056957244873 + ], + [ + -1.6270242929458618, + -1.3951387405395508, + -0.23872417211532593 + ], + [ + -0.5049903988838196, + -2.475163221359253, + -0.931602954864502 + ] + ], + "expected_output": [ + [ + 1.4111539125442505, + 0.655610978603363, + 0.8576056957244873 + ], + [ + 1.6270242929458618, + 1.3951387405395508, + 0.23872417211532593 + ], + [ + 0.5049903988838196, + 2.475163221359253, + 0.931602954864502 + ] + ], + "expected_grad": [ + [ + 1.0, + -1.0, + 1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + }, + { + "input": [ + [ + -0.13348686695098877, + 0.34148848056793213, + -0.07157137989997864 + ], + [ + -0.09089037775993347, + -1.3296922445297241, + -0.542582631111145 + ], + [ + 0.5470984578132629, + 0.6430637240409851, + -0.7904810905456543 + ] + ], + "expected_output": [ + [ + 0.13348686695098877, + 0.34148848056793213, + 0.07157137989997864 + ], + [ + 0.09089037775993347, + 1.3296922445297241, + 0.542582631111145 + ], + [ + 0.5470984578132629, + 0.6430637240409851, + 0.7904810905456543 + ] + ], + "expected_grad": [ + [ + -1.0, + 1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + 1.0, + 1.0, + -1.0 + ] + ] + } + ], + "sign": [ + { + "input": [ + [ + -0.9058369994163513, + -0.26072561740875244, + -0.5465103983879089 + ], + [ + 2.117400646209717, + -1.711801528930664, + 0.16513441503047943 + ], + [ + 1.5818675756454468, + 0.44846096634864807, + 0.033029891550540924 + ] + ], + "expected_output": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + 1.0, + -1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad": [ + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ] + }, + { + "input": [ + [ + 1.450257658958435, + -0.6935664415359497, + 0.9966652989387512 + ], + [ + 0.6130759119987488, + 0.7763870358467102, + -0.3029157221317291 + ], + [ + -1.2753024101257324, + -0.47575175762176514, + 2.383944511413574 + ] + ], + "expected_output": [ + [ + 1.0, + -1.0, + 1.0 + ], + [ + 1.0, + 1.0, + -1.0 + ], + [ + -1.0, + -1.0, + 1.0 + ] + ], + "expected_grad": [ + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ] + }, + { + "input": [ + [ + 0.9157298803329468, + -0.6429603099822998, + 0.7113185524940491 + ], + [ + 0.39997783303260803, + -1.2039215564727783, + -0.41975241899490356 + ], + [ + -1.1928907632827759, + -0.9350629448890686, + 0.2138027846813202 + ] + ], + "expected_output": [ + [ + 1.0, + -1.0, + 1.0 + ], + [ + 1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + 1.0 + ] + ], + "expected_grad": [ + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ] + } + ], + "neg": [ + { + "input": [ + [ + -1.2842116355895996, + -0.6916776895523071, + -0.5359472632408142 + ], + [ + 0.33552202582359314, + 0.2469366192817688, + 0.03243076428771019 + ], + [ + 0.40568798780441284, + 1.618118405342102, + 0.39315488934516907 + ] + ], + "expected_output": [ + [ + 1.2842116355895996, + 0.6916776895523071, + 0.5359472632408142 + ], + [ + -0.33552202582359314, + -0.2469366192817688, + -0.03243076428771019 + ], + [ + -0.40568798780441284, + -1.618118405342102, + -0.39315488934516907 + ] + ], + "expected_grad": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + }, + { + "input": [ + [ + -0.2147795557975769, + 1.265119194984436, + -0.31780683994293213 + ], + [ + -0.42791351675987244, + -0.5006903409957886, + -0.1306709349155426 + ], + [ + 0.9795637726783752, + 0.5959771871566772, + -1.4723340272903442 + ] + ], + "expected_output": [ + [ + 0.2147795557975769, + -1.265119194984436, + 0.31780683994293213 + ], + [ + 0.42791351675987244, + 0.5006903409957886, + 0.1306709349155426 + ], + [ + -0.9795637726783752, + -0.5959771871566772, + 1.4723340272903442 + ] + ], + "expected_grad": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + }, + { + "input": [ + [ + -0.47487422823905945, + 1.6639716625213623, + 0.01096251793205738 + ], + [ + 0.14468061923980713, + 1.2818045616149902, + -1.5952012538909912 + ], + [ + -1.064806342124939, + 0.10553700476884842, + 1.9738837480545044 + ] + ], + "expected_output": [ + [ + 0.47487422823905945, + -1.6639716625213623, + -0.01096251793205738 + ], + [ + -0.14468061923980713, + -1.2818045616149902, + 1.5952012538909912 + ], + [ + 1.064806342124939, + -0.10553700476884842, + -1.9738837480545044 + ] + ], + "expected_grad": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + } + ], + "reciprocal": [ + { + "input": [ + [ + 1.0703048706054688, + -1.7378737926483154, + 0.18413154780864716 + ], + [ + -0.1562519073486328, + -0.6680524945259094, + 1.2135050296783447 + ], + [ + 0.7923893332481384, + -0.4400617480278015, + 0.4995947778224945 + ] + ], + "expected_output": [ + [ + 0.9343132376670837, + -0.5754157900810242, + 5.4309000968933105 + ], + [ + -6.399921894073486, + -1.4968883991241455, + 0.8240591883659363 + ], + [ + 1.2620059251785278, + -2.2724084854125977, + 2.001622200012207 + ] + ], + "expected_grad": [ + [ + -0.872941255569458, + -0.3311033248901367, + -29.49467658996582 + ], + [ + -40.95899963378906, + -2.2406749725341797, + -0.6790735721588135 + ], + [ + -1.5926589965820312, + -5.163840293884277, + -4.006491661071777 + ] + ] + }, + { + "input": [ + [ + -0.7581364512443542, + 0.9989117383956909, + -0.8792798519134521 + ], + [ + 0.7485982179641724, + -1.3375409841537476, + 0.6449474096298218 + ], + [ + 0.9652354717254639, + 1.0089688301086426, + -0.033671289682388306 + ] + ], + "expected_output": [ + [ + -1.3190237283706665, + 1.0010894536972046, + -1.1372942924499512 + ], + [ + 1.3358300924301147, + -0.7476406693458557, + 1.5505139827728271 + ], + [ + 1.036016583442688, + 0.9911109209060669, + -29.69889259338379 + ] + ], + "expected_grad": [ + [ + -1.739823579788208, + -1.0021800994873047, + -1.2934383153915405 + ], + [ + -1.7844420671463013, + -0.5589665770530701, + -2.4040935039520264 + ], + [ + -1.0733304023742676, + -0.982300877571106, + -882.0242309570312 + ] + ] + }, + { + "input": [ + [ + -1.0089720487594604, + -1.2315175533294678, + -1.046962022781372 + ], + [ + -1.7460761070251465, + -0.37421396374702454, + -0.41171613335609436 + ], + [ + -0.8997476696968079, + 0.48207539319992065, + 2.5150909423828125 + ] + ], + "expected_output": [ + [ + -0.9911077618598938, + -0.8120062947273254, + -0.955144464969635 + ], + [ + -0.5727127194404602, + -2.6722679138183594, + -2.4288580417633057 + ], + [ + -1.1114226579666138, + 2.074364423751831, + 0.3975999355316162 + ] + ], + "expected_grad": [ + [ + -0.9822946190834045, + -0.6593542098999023, + -0.9123009443283081 + ], + [ + -0.32799986004829407, + -7.141016006469727, + -5.899351596832275 + ], + [ + -1.2352603673934937, + -4.302987575531006, + -0.15808570384979248 + ] + ] + } + ], + "sin": [ + { + "input": [ + [ + -0.7723492980003357, + 0.15315502882003784, + 1.3269745111465454 + ], + [ + -0.8023788928985596, + 2.924564838409424, + -0.7985216975212097 + ], + [ + -0.5669130086898804, + -0.026701264083385468, + -1.5459672212600708 + ] + ], + "expected_output": [ + [ + -0.6978198885917664, + 0.15255698561668396, + 0.9704224467277527 + ], + [ + -0.7190114259719849, + 0.21532811224460602, + -0.7163253426551819 + ], + [ + -0.5370305180549622, + -0.026698091998696327, + -0.9996917843818665 + ] + ], + "expected_grad": [ + [ + 0.7162732481956482, + 0.9882946610450745, + 0.2414131611585617 + ], + [ + 0.6949982047080994, + -0.9765417575836182, + 0.6977664232254028 + ], + [ + 0.8435627818107605, + 0.9996435642242432, + 0.02482655458152294 + ] + ] + }, + { + "input": [ + [ + -2.1798956394195557, + 0.20737595856189728, + -1.9843575954437256 + ], + [ + -0.1816582977771759, + 0.4279658794403076, + 0.25454989075660706 + ], + [ + 0.06617925316095352, + -1.2704100608825684, + 0.667417049407959 + ] + ], + "expected_output": [ + [ + -0.8201636672019958, + 0.20589278638362885, + -0.9156954288482666 + ], + [ + -0.18066082894802094, + 0.41502100229263306, + 0.25180983543395996 + ], + [ + 0.06613095849752426, + -0.9552222490310669, + 0.618959367275238 + ] + ], + "expected_grad": [ + [ + -0.5721290111541748, + 0.9785745739936829, + -0.4018729031085968 + ], + [ + 0.9835454821586609, + 0.9098118543624878, + 0.9677767157554626 + ], + [ + 0.997810959815979, + 0.2958891987800598, + 0.7854230403900146 + ] + ] + }, + { + "input": [ + [ + -1.0002132654190063, + -0.024445118382573128, + 0.24967312812805176 + ], + [ + -1.7517130374908447, + -0.1309133768081665, + 1.437826156616211 + ], + [ + -0.154391348361969, + -0.2853364050388336, + -0.1389411836862564 + ] + ], + "expected_output": [ + [ + -0.841586172580719, + -0.024442683905363083, + 0.2470872402191162 + ], + [ + -0.9836791753768921, + -0.13053975999355316, + 0.9911724925041199 + ], + [ + -0.15377871692180634, + -0.2814802825450897, + -0.1384945809841156 + ] + ], + "expected_grad": [ + [ + 0.5401228666305542, + 0.999701201915741, + 0.9689932465553284 + ], + [ + -0.1799314022064209, + 0.9914430975914001, + 0.13257867097854614 + ], + [ + 0.988105297088623, + 0.9595670104026794, + 0.9903631806373596 + ] + ] + } + ], + "cos": [ + { + "input": [ + [ + -0.8561121225357056, + -0.53642737865448, + -1.0440475940704346 + ], + [ + 1.2561368942260742, + 0.46269556879997253, + -0.315053254365921 + ], + [ + 0.5482434034347534, + 0.03692331537604332, + -0.8128055930137634 + ] + ], + "expected_output": [ + [ + 0.6553789377212524, + 0.8595399856567383, + 0.5027254819869995 + ], + [ + 0.30949264764785767, + 0.8948525786399841, + 0.9507798552513123 + ], + [ + 0.8534413576126099, + 0.9993184208869934, + 0.687463641166687 + ] + ], + "expected_grad": [ + [ + 0.7553002238273621, + 0.5110684633255005, + 0.8644461035728455 + ], + [ + -0.9509018659591675, + -0.44636186957359314, + 0.30986711382865906 + ], + [ + -0.5211888551712036, + -0.036914926022291183, + 0.7262187600135803 + ] + ] + }, + { + "input": [ + [ + 0.012067895382642746, + -0.6397443413734436, + 0.6415984630584717 + ], + [ + -0.5963875651359558, + 0.7354843616485596, + 0.0723138153553009 + ], + [ + 1.8586984872817993, + -0.3944927752017975, + 0.7613471746444702 + ] + ], + "expected_output": [ + [ + 0.9999271631240845, + 0.8022484183311462, + 0.8011401295661926 + ], + [ + 0.8273699283599854, + 0.7415058612823486, + 0.9973865151405334 + ], + [ + -0.2839413583278656, + 0.9231916069984436, + 0.7239072322845459 + ] + ], + "expected_grad": [ + [ + -0.012067602016031742, + 0.5969903469085693, + -0.5984768271446228 + ], + [ + 0.5616573095321655, + -0.6709464192390442, + -0.07225080579519272 + ], + [ + -0.9588416814804077, + 0.38433998823165894, + -0.6898972988128662 + ] + ] + }, + { + "input": [ + [ + -1.7989355325698853, + -0.6020540595054626, + 0.673175573348999 + ], + [ + 0.018282217904925346, + -0.049032170325517654, + 0.17692552506923676 + ], + [ + 0.8319899439811707, + -2.008758783340454, + -0.5569353103637695 + ] + ], + "expected_output": [ + [ + -0.22616533935070038, + 0.8241740465164185, + 0.78184574842453 + ], + [ + 0.9998328685760498, + 0.998798131942749, + 0.9843894839286804 + ], + [ + 0.6734060049057007, + -0.42409512400627136, + 0.8488790392875671 + ] + ], + "expected_grad": [ + [ + 0.9740889072418213, + 0.5663365721702576, + -0.6234719157218933 + ], + [ + -0.018281199038028717, + 0.049012526869773865, + -0.17600393295288086 + ], + [ + -0.7392728924751282, + 0.9056176543235779, + 0.5285871624946594 + ] + ] + } + ], + "tan": [ + { + "input": [ + [ + -1.600385069847107, + 0.8983902335166931, + -0.6497360467910767 + ], + [ + 0.21935275197029114, + 0.5447354912757874, + -2.056748628616333 + ], + [ + 0.23443682491779327, + -0.34069985151290894, + 1.0171456336975098 + ] + ], + "expected_output": [ + [ + 33.786773681640625, + 1.2560005187988281, + -0.7597879767417908 + ], + [ + 0.22293990850448608, + 0.6058850288391113, + 1.8932220935821533 + ], + [ + 0.23882833123207092, + -0.35452449321746826, + 1.617757797241211 + ] + ], + "expected_grad": [ + [ + 1142.5460205078125, + 2.5775372982025146, + 1.5772777795791626 + ], + [ + 1.0497021675109863, + 1.3670966625213623, + 4.58428955078125 + ], + [ + 1.0570390224456787, + 1.125687599182129, + 3.617140293121338 + ] + ] + }, + { + "input": [ + [ + 1.1458033323287964, + -0.05559399351477623, + -0.3598405122756958 + ], + [ + 1.1056941747665405, + -0.6886897087097168, + 0.1491728127002716 + ], + [ + -1.0009846687316895, + -1.501810908317566, + 0.00793869886547327 + ] + ], + "expected_output": [ + [ + 2.2095799446105957, + -0.05565134063363075, + -0.37622079253196716 + ], + [ + 1.9927483797073364, + -0.8231356739997864, + 0.15028923749923706 + ], + [ + -1.5607858896255493, + -14.472814559936523, + 0.007938865572214127 + ] + ], + "expected_grad": [ + [ + 5.882243633270264, + 1.0030970573425293, + 1.1415420770645142 + ], + [ + 4.971046447753906, + 1.677552342414856, + 1.0225868225097656 + ], + [ + 3.4360525608062744, + 210.4623565673828, + 1.0000630617141724 + ] + ] + }, + { + "input": [ + [ + 0.8266488909721375, + -1.0300014019012451, + 1.7748093605041504 + ], + [ + 0.24461546540260315, + 1.4372375011444092, + -0.706683874130249 + ], + [ + 1.3421580791473389, + 0.5234800577163696, + -0.26403290033340454 + ] + ], + "expected_output": [ + [ + 1.0861021280288696, + -1.665249228477478, + -4.83345365524292 + ], + [ + 0.24961413443088531, + 7.442764759063721, + -0.8537789583206177 + ], + [ + 4.297241687774658, + 0.5771920084953308, + -0.27034449577331543 + ] + ], + "expected_grad": [ + [ + 2.1796178817749023, + 3.773055076599121, + 24.362274169921875 + ], + [ + 1.0623072385787964, + 56.39474868774414, + 1.7289385795593262 + ], + [ + 19.466285705566406, + 1.3331506252288818, + 1.073086142539978 + ] + ] + } + ] + }, + "binary": { + "add": [ + { + "input_x": [ + [ + -0.3285827040672302, + -0.3712422847747803, + -0.5473041534423828 + ], + [ + 1.3824070692062378, + -0.7471941709518433, + -2.5696442127227783 + ], + [ + 0.10177755355834961, + 1.4807320833206177, + 0.29541370272636414 + ] + ], + "input_y": [ + [ + 0.23622490465641022, + 0.2450244277715683, + 0.6467189788818359 + ], + [ + 0.6161983609199524, + 0.0354895144701004, + 1.124637246131897 + ], + [ + -0.18692852556705475, + 0.017339814454317093, + -1.3771003484725952 + ] + ], + "expected_output": [ + [ + -0.09235779941082001, + -0.12621785700321198, + 0.09941482543945312 + ], + [ + 1.998605489730835, + -0.711704671382904, + -1.4450069665908813 + ], + [ + -0.08515097200870514, + 1.4980719089508057, + -1.0816866159439087 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + }, + { + "input_x": [ + [ + -0.3060486316680908, + 0.9692544937133789, + -0.7809293270111084 + ], + [ + 0.2835264801979065, + -0.34251856803894043, + -1.5208441019058228 + ], + [ + 0.11262339353561401, + 0.061174698173999786, + 0.8015474677085876 + ] + ], + "input_y": [ + [ + -0.43932145833969116, + -0.212321937084198, + 0.07726861536502838 + ], + [ + -0.8692201972007751, + 0.06136707961559296, + 0.46790215373039246 + ], + [ + 0.43584781885147095, + -0.28228023648262024, + -1.2118933200836182 + ] + ], + "expected_output": [ + [ + -0.745370090007782, + 0.7569325566291809, + -0.7036607265472412 + ], + [ + -0.5856937170028687, + -0.2811514735221863, + -1.052941918373108 + ], + [ + 0.548471212387085, + -0.22110554575920105, + -0.4103458523750305 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + }, + { + "input_x": [ + [ + -1.2612135410308838, + -0.08296369016170502, + -0.6891635060310364 + ], + [ + 0.391975462436676, + 1.06540846824646, + -0.5663558840751648 + ], + [ + 1.2495359182357788, + -0.8697574734687805, + -0.25120875239372253 + ] + ], + "input_y": [ + [ + 0.1198730394244194, + -0.19844388961791992, + -1.130265712738037 + ], + [ + 0.2562393546104431, + -0.5835933685302734, + -1.3709070682525635 + ], + [ + 0.23866742849349976, + 1.248494029045105, + 0.05098257213830948 + ] + ], + "expected_output": [ + [ + -1.1413404941558838, + -0.28140759468078613, + -1.8194291591644287 + ], + [ + 0.6482148170471191, + 0.4818150997161865, + -1.937263011932373 + ], + [ + 1.4882032871246338, + 0.37873655557632446, + -0.20022618770599365 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + } + ], + "sub": [ + { + "input_x": [ + [ + -0.017705317586660385, + -0.7571937441825867, + -1.6010069847106934 + ], + [ + 0.3873583972454071, + -0.57644122838974, + 0.20196054875850677 + ], + [ + 1.0855722427368164, + 1.2247178554534912, + 0.27423009276390076 + ] + ], + "input_y": [ + [ + -0.7684280276298523, + 0.6938012838363647, + -1.428295612335205 + ], + [ + -0.37946099042892456, + 1.5014593601226807, + 0.12739363312721252 + ], + [ + 1.0316026210784912, + -0.5813775658607483, + 0.7993662357330322 + ] + ], + "expected_output": [ + [ + 0.7507227063179016, + -1.4509949684143066, + -0.17271137237548828 + ], + [ + 0.7668193578720093, + -2.0779006481170654, + 0.07456691563129425 + ], + [ + 0.053969621658325195, + 1.8060953617095947, + -0.5251361131668091 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + }, + { + "input_x": [ + [ + 0.4884093105792999, + -2.1239805221557617, + -0.4837254583835602 + ], + [ + -0.8704075217247009, + 0.7864606976509094, + 0.47071704268455505 + ], + [ + -1.0652520656585693, + 0.7358277440071106, + 0.43029549717903137 + ] + ], + "input_y": [ + [ + -0.6365610361099243, + -0.2711743116378784, + -0.7389668226242065 + ], + [ + 1.6474533081054688, + -0.5047107338905334, + 0.7850356101989746 + ], + [ + 0.3700398802757263, + 0.07554273307323456, + -1.5730698108673096 + ] + ], + "expected_output": [ + [ + 1.1249703168869019, + -1.8528062105178833, + 0.25524136424064636 + ], + [ + -2.5178608894348145, + 1.2911714315414429, + -0.31431856751441956 + ], + [ + -1.4352920055389404, + 0.6602849960327148, + 2.0033652782440186 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + }, + { + "input_x": [ + [ + 0.2201399803161621, + 0.23505949974060059, + 1.0043964385986328 + ], + [ + 0.4351750910282135, + -0.0459199883043766, + 0.7410483360290527 + ], + [ + 0.5975771546363831, + 0.7118588089942932, + -1.308319330215454 + ] + ], + "input_y": [ + [ + -0.24913781881332397, + -1.2001056671142578, + 0.5043410658836365 + ], + [ + 0.5920562744140625, + -0.8244076371192932, + -1.5402805805206299 + ], + [ + 0.4552428424358368, + 1.629791498184204, + -0.3871910572052002 + ] + ], + "expected_output": [ + [ + 0.4692777991294861, + 1.4351651668548584, + 0.5000553727149963 + ], + [ + -0.156881183385849, + 0.7784876227378845, + 2.2813289165496826 + ], + [ + 0.14233431220054626, + -0.9179326891899109, + -0.9211282730102539 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, + -1.0, + -1.0 + ] + ] + } + ], + "mul": [ + { + "input_x": [ + [ + 0.20325958728790283, + 1.5292197465896606, + 0.04372377693653107 + ], + [ + -1.480481505393982, + -0.23249931633472443, + -0.415950745344162 + ], + [ + 1.4263980388641357, + -1.0918711423873901, + -0.7077858448028564 + ] + ], + "input_y": [ + [ + 1.0836158990859985, + -0.19257144629955292, + -1.0489495992660522 + ], + [ + -0.012573999352753162, + 1.1939914226531982, + 1.120118260383606 + ], + [ + -0.5828483700752258, + -0.06718457490205765, + 0.3241202235221863 + ] + ], + "expected_output": [ + [ + 0.2202553153038025, + -0.29448404908180237, + -0.045864038169384 + ], + [ + 0.01861557364463806, + -0.2776021957397461, + -0.4659140110015869 + ], + [ + -0.8313737511634827, + 0.07335689663887024, + -0.22940771281719208 + ] + ], + "expected_grad_x": [ + [ + 1.0836158990859985, + -0.19257144629955292, + -1.0489495992660522 + ], + [ + -0.012573999352753162, + 1.1939914226531982, + 1.120118260383606 + ], + [ + -0.5828483700752258, + -0.06718457490205765, + 0.3241202235221863 + ] + ], + "expected_grad_y": [ + [ + 0.20325958728790283, + 1.5292197465896606, + 0.04372377693653107 + ], + [ + -1.480481505393982, + -0.23249931633472443, + -0.415950745344162 + ], + [ + 1.4263980388641357, + -1.0918711423873901, + -0.7077858448028564 + ] + ] + }, + { + "input_x": [ + [ + -0.04043859243392944, + -0.6861222982406616, + 0.5436578989028931 + ], + [ + -1.5625712871551514, + 0.8695050477981567, + 0.21445733308792114 + ], + [ + -0.7495803833007812, + -0.49505615234375, + 1.38492751121521 + ] + ], + "input_y": [ + [ + 0.723960280418396, + 0.14494575560092926, + 2.234894275665283 + ], + [ + 0.02188074216246605, + 0.32069334387779236, + 0.16325443983078003 + ], + [ + -1.0949900150299072, + 0.5536599159240723, + -0.7866464257240295 + ] + ], + "expected_output": [ + [ + -0.029275935143232346, + -0.09945051372051239, + 1.2150179147720337 + ], + [ + -0.03419021889567375, + 0.2788444757461548, + 0.035011112689971924 + ], + [ + 0.8207830190658569, + -0.27409273386001587, + -1.08944833278656 + ] + ], + "expected_grad_x": [ + [ + 0.723960280418396, + 0.14494575560092926, + 2.234894275665283 + ], + [ + 0.02188074216246605, + 0.32069334387779236, + 0.16325443983078003 + ], + [ + -1.0949900150299072, + 0.5536599159240723, + -0.7866464257240295 + ] + ], + "expected_grad_y": [ + [ + -0.04043859243392944, + -0.6861222982406616, + 0.5436578989028931 + ], + [ + -1.5625712871551514, + 0.8695050477981567, + 0.21445733308792114 + ], + [ + -0.7495803833007812, + -0.49505615234375, + 1.38492751121521 + ] + ] + }, + { + "input_x": [ + [ + -0.6246262192726135, + -0.056941766291856766, + 1.0051201581954956 + ], + [ + -0.27256739139556885, + -0.09721744060516357, + 0.34720900654792786 + ], + [ + -0.2762232720851898, + 0.635994553565979, + -0.1394427865743637 + ] + ], + "input_y": [ + [ + 1.2944984436035156, + 0.24116213619709015, + 0.18012243509292603 + ], + [ + -0.8317649364471436, + 0.34142518043518066, + 1.0009468793869019 + ], + [ + 0.05718276649713516, + -1.3248257637023926, + -0.24600434303283691 + ] + ], + "expected_output": [ + [ + -0.8085776567459106, + -0.01373219769448042, + 0.18104469776153564 + ], + [ + 0.22671200335025787, + -0.033192481845617294, + 0.3475377857685089 + ], + [ + -0.015795210376381874, + -0.8425819873809814, + 0.03430353105068207 + ] + ], + "expected_grad_x": [ + [ + 1.2944984436035156, + 0.24116213619709015, + 0.18012243509292603 + ], + [ + -0.8317649364471436, + 0.34142518043518066, + 1.0009468793869019 + ], + [ + 0.05718276649713516, + -1.3248257637023926, + -0.24600434303283691 + ] + ], + "expected_grad_y": [ + [ + -0.6246262192726135, + -0.056941766291856766, + 1.0051201581954956 + ], + [ + -0.27256739139556885, + -0.09721744060516357, + 0.34720900654792786 + ], + [ + -0.2762232720851898, + 0.635994553565979, + -0.1394427865743637 + ] + ] + } + ], + "div": [ + { + "input_x": [ + [ + 0.06055254861712456, + 0.567650556564331, + 0.3359237015247345 + ], + [ + 0.4317582845687866, + 2.4537413120269775, + 1.545257568359375 + ], + [ + -0.456123024225235, + 0.5606658458709717, + -0.8425916433334351 + ] + ], + "input_y": [ + [ + 1.0377453565597534, + 0.01705855503678322, + -0.47082921862602234 + ], + [ + 0.012864481657743454, + -0.8240524530410767, + 1.8157182931900024 + ], + [ + 0.3094446361064911, + 0.4485149085521698, + 0.3250584602355957 + ] + ], + "expected_output": [ + [ + 0.058350104838609695, + 33.27659225463867, + -0.7134724855422974 + ], + [ + 33.562042236328125, + -2.977651834487915, + 0.851044774055481 + ], + [ + -1.4740052223205566, + 1.2500494718551636, + -2.592123508453369 + ] + ], + "expected_grad_x": [ + [ + 0.9636275172233582, + 58.621612548828125, + -2.1239123344421387 + ], + [ + 77.73340606689453, + -1.213515043258667, + 0.5507462024688721 + ], + [ + 3.231595754623413, + 2.2295804023742676, + 3.0763697624206543 + ] + ], + "expected_grad_y": [ + [ + -0.05622776597738266, + -1950.7275390625, + -1.5153530836105347 + ], + [ + -2608.891845703125, + -3.6134250164031982, + -0.46870970726013184 + ], + [ + 4.7633891105651855, + -2.787085771560669, + 7.974330425262451 + ] + ] + }, + { + "input_x": [ + [ + -1.2630205154418945, + 0.7806677222251892, + -0.730068027973175 + ], + [ + -0.005363038275390863, + 0.19142311811447144, + -0.7694061398506165 + ], + [ + -1.4855033159255981, + 0.7473039031028748, + -1.07101309299469 + ] + ], + "input_y": [ + [ + 0.3512069880962372, + 0.29272884130477905, + -0.006127047352492809 + ], + [ + 1.3258482217788696, + 0.6050942540168762, + 0.07117609679698944 + ], + [ + -1.0134872198104858, + 0.9038492441177368, + -0.02116147242486477 + ] + ], + "expected_output": [ + [ + -3.5962283611297607, + 2.666862964630127, + 119.15495300292969 + ], + [ + -0.004044986795634031, + 0.31635257601737976, + -10.809895515441895 + ], + [ + 1.465734601020813, + 0.8268014788627625, + 50.61146545410156 + ] + ], + "expected_grad_x": [ + [ + 2.8473236560821533, + 3.416130781173706, + -163.21075439453125 + ], + [ + 0.7542341351509094, + 1.652635097503662, + 14.049660682678223 + ], + [ + -0.9866922497749329, + 1.1063791513442993, + -47.25569152832031 + ] + ], + "expected_grad_y": [ + [ + 10.23962688446045, + -9.110352516174316, + 19447.369140625 + ], + [ + 0.003050867235288024, + -0.5228153467178345, + 151.8753662109375 + ], + [ + 1.4462289810180664, + -0.9147559404373169, + 2391.6796875 + ] + ] + }, + { + "input_x": [ + [ + -1.4251255989074707, + -0.3948180079460144, + -0.016342604532837868 + ], + [ + -1.9588884115219116, + -1.6948655843734741, + -1.0810617208480835 + ], + [ + 1.9611457586288452, + -0.12107571214437485, + -0.06618902087211609 + ] + ], + "input_y": [ + [ + -1.128678321838379, + -0.7868197560310364, + 0.2418329268693924 + ], + [ + -0.6500567197799683, + -0.23437145352363586, + -2.115622043609619 + ], + [ + -0.026218075305223465, + 1.8427811861038208, + -0.3302917778491974 + ] + ], + "expected_output": [ + [ + 1.2626498937606812, + 0.5017896294593811, + -0.06757807731628418 + ], + [ + 3.013411521911621, + 7.231535911560059, + 0.5109900236129761 + ], + [ + -74.80128479003906, + -0.06570270657539368, + 0.2003955990076065 + ] + ], + "expected_grad_x": [ + [ + -0.8859920501708984, + -1.2709391117095947, + 4.1350860595703125 + ], + [ + -1.5383273363113403, + -4.266731262207031, + -0.4726742208003998 + ], + [ + -38.141624450683594, + 0.5426580309867859, + -3.0276260375976562 + ] + ], + "expected_grad_y": [ + [ + 1.1186977624893188, + 0.6377440690994263, + 0.2794411778450012 + ], + [ + 4.635613441467285, + 30.85502052307129, + 0.24153180420398712 + ], + [ + -2853.04248046875, + 0.03565410152077675, + 0.6067229509353638 + ] + ] + } + ], + "maximum": [ + { + "input_x": [ + [ + 0.848053514957428, + -0.4575539231300354, + -1.2403643131256104 + ], + [ + 1.325866937637329, + -0.9645381569862366, + -1.6019319295883179 + ], + [ + -0.2991969585418701, + 1.3587521314620972, + 1.6083942651748657 + ] + ], + "input_y": [ + [ + 1.341455340385437, + -0.6912397742271423, + 0.6742424964904785 + ], + [ + -0.5411797165870667, + -0.27575162053108215, + 0.22375407814979553 + ], + [ + -0.1522003561258316, + -1.3301465511322021, + 0.5499060750007629 + ] + ], + "expected_output": [ + [ + 1.341455340385437, + -0.4575539231300354, + 0.6742424964904785 + ], + [ + 1.325866937637329, + -0.27575162053108215, + 0.22375407814979553 + ], + [ + -0.1522003561258316, + 1.3587521314620972, + 1.6083942651748657 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 1.0 + ], + [ + 1.0, + 0.0, + 0.0 + ] + ] + }, + { + "input_x": [ + [ + 0.6266193389892578, + 0.5769692659378052, + 0.6269291639328003 + ], + [ + 2.1126511096954346, + 0.1117599681019783, + 0.5981283187866211 + ], + [ + -0.4339904189109802, + -0.5859114527702332, + -1.1628034114837646 + ] + ], + "input_y": [ + [ + 0.9215105772018433, + 0.46360349655151367, + -0.7266963124275208 + ], + [ + 0.2733789086341858, + 0.10054377466440201, + 0.23247668147087097 + ], + [ + 0.7063558101654053, + 0.3692564070224762, + -0.8367782831192017 + ] + ], + "expected_output": [ + [ + 0.9215105772018433, + 0.5769692659378052, + 0.6269291639328003 + ], + [ + 2.1126511096954346, + 0.1117599681019783, + 0.5981283187866211 + ], + [ + 0.7063558101654053, + 0.3692564070224762, + -0.8367782831192017 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + }, + { + "input_x": [ + [ + -1.220356822013855, + -0.313897043466568, + 0.5908606648445129 + ], + [ + -1.5677003860473633, + -0.6271555423736572, + 1.1621606349945068 + ], + [ + -1.959486484527588, + 1.2394423484802246, + -0.7589735388755798 + ] + ], + "input_y": [ + [ + -0.13591812551021576, + 0.24926981329917908, + -1.121405839920044 + ], + [ + -0.606251060962677, + 0.2932665944099426, + 0.7437686324119568 + ], + [ + -0.19546888768672943, + 1.2695143222808838, + 0.21413196623325348 + ] + ], + "expected_output": [ + [ + -0.13591812551021576, + 0.24926981329917908, + 0.5908606648445129 + ], + [ + -0.606251060962677, + 0.2932665944099426, + 1.1621606349945068 + ], + [ + -0.19546888768672943, + 1.2695143222808838, + 0.21413196623325348 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 1.0, + 0.0 + ], + [ + 1.0, + 1.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + } + ], + "minimum": [ + { + "input_x": [ + [ + 1.5344094038009644, + -3.066803455352783, + -2.4677371978759766 + ], + [ + 0.16308026015758514, + -0.0031113873701542616, + 0.3103507161140442 + ], + [ + -0.11947628855705261, + 0.06774814426898956, + -0.3587782680988312 + ] + ], + "input_y": [ + [ + -1.0992363691329956, + 0.9729869961738586, + 1.6560982465744019 + ], + [ + -1.2484521865844727, + -2.239192247390747, + -0.732846200466156 + ], + [ + -2.3703532218933105, + 0.656094491481781, + 0.45320239663124084 + ] + ], + "expected_output": [ + [ + -1.0992363691329956, + -3.066803455352783, + -2.4677371978759766 + ], + [ + -1.2484521865844727, + -2.239192247390747, + -0.732846200466156 + ], + [ + -2.3703532218933105, + 0.06774814426898956, + -0.3587782680988312 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 0.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 0.0, + 0.0 + ] + ] + }, + { + "input_x": [ + [ + -0.9435422420501709, + 0.9280446171760559, + 0.7899183034896851 + ], + [ + 1.5556696653366089, + -1.350498914718628, + 1.1451255083084106 + ], + [ + 0.6095852255821228, + -0.2682342529296875, + -1.1788489818572998 + ] + ], + "input_y": [ + [ + 0.8645744919776917, + -0.6576043367385864, + -0.0943203940987587 + ], + [ + 1.4321774244308472, + 1.0809533596038818, + -0.5367263555526733 + ], + [ + -0.8979145288467407, + -0.3949545621871948, + -1.3240617513656616 + ] + ], + "expected_output": [ + [ + -0.9435422420501709, + -0.6576043367385864, + -0.0943203940987587 + ], + [ + 1.4321774244308472, + -1.350498914718628, + -0.5367263555526733 + ], + [ + -0.8979145288467407, + -0.3949545621871948, + -1.3240617513656616 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ], + "expected_grad_y": [ + [ + 0.0, + 1.0, + 1.0 + ], + [ + 1.0, + 0.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + }, + { + "input_x": [ + [ + -0.8422006368637085, + -0.21955861151218414, + 0.758247971534729 + ], + [ + -0.6107911467552185, + 1.689821481704712, + -0.6808373332023621 + ], + [ + 0.5883275866508484, + -2.3586840629577637, + 0.5554983615875244 + ] + ], + "input_y": [ + [ + -0.9920331239700317, + -0.13226133584976196, + 0.549020528793335 + ], + [ + -0.15818315744400024, + -0.42454805970191956, + 1.707962989807129 + ], + [ + 0.5729089975357056, + 0.011930502019822598, + -0.9791588187217712 + ] + ], + "expected_output": [ + [ + -0.9920331239700317, + -0.21955861151218414, + 0.549020528793335 + ], + [ + -0.6107911467552185, + -0.42454805970191956, + -0.6808373332023621 + ], + [ + 0.5729089975357056, + -2.3586840629577637, + -0.9791588187217712 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 0.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 1.0 + ] + ] + } + ] + } +}; diff --git a/vite.config.node.ts b/vite.config.node.ts index 9e31fe3b..4d071889 100644 --- a/vite.config.node.ts +++ b/vite.config.node.ts @@ -10,6 +10,6 @@ export default defineConfig({ }, outDir: 'build/node', target: 'node20', - minify: false, + minify: true, }, }); From f5fe9c7f5f4c67885c6a5ad1df27c66cb8317bc3 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sun, 8 Mar 2026 17:16:47 +0800 Subject: [PATCH 075/128] feat: compare NaN in generated tests --- scripts/generate_tests.py | 4 +- test/generated.test.js | 6 +- test/tensor_ops_data.gen.js | 2503 +++++++++++++++++++++-------------- 3 files changed, 1551 insertions(+), 962 deletions(-) diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index e29e5f9e..bc2f9fae 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -1,8 +1,8 @@ import torch import json -UNARY_OPS = ['exp', 'square', 'abs', 'sign', 'neg', 'reciprocal', 'sin', 'cos', 'tan'] -BINARY_OPS = ['add', 'sub', 'mul', 'div', 'maximum', 'minimum'] +UNARY_OPS = ['log', 'sqrt', 'exp', 'square', 'abs', 'sign', 'neg', 'reciprocal', 'sin', 'cos', 'tan'] +BINARY_OPS = ['add', 'sub', 'mul', 'div', 'pow', 'maximum', 'minimum'] torch.manual_seed(42) diff --git a/test/generated.test.js b/test/generated.test.js index d4eef78a..49160088 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -9,7 +9,11 @@ function assertDeepCloseTo(actual, expected, delta = 1e-3) { assertDeepCloseTo(actual[i], expected[i], delta); } } else { - assert.closeTo(actual, expected, delta); + if (Number.isNaN(expected)) { + assert.isTrue(Number.isNaN(actual), `Expected NaN but got ${actual}`); + } else { + assert.closeTo(actual, expected, delta); + } } } diff --git a/test/tensor_ops_data.gen.js b/test/tensor_ops_data.gen.js index 43d9fa22..79b115b8 100644 --- a/test/tensor_ops_data.gen.js +++ b/test/tensor_ops_data.gen.js @@ -1,6 +1,6 @@ export const testData = { "unary": { - "exp": [ + "log": [ { "input": [ [ @@ -21,36 +21,36 @@ export const testData = { ], "expected_output": [ [ - 1.4003053903579712, - 1.1374733448028564, - 1.2642289400100708 + -1.0885915756225586, + -2.0494213104248047, + -1.4504601955413818 ], [ - 1.2590192556381226, - 0.3253491520881653, - 0.8300010561943054 + -1.468229055404663, + NaN, + NaN ], [ - 9.099335670471191, - 0.5283496379852295, - 1.5867012739181519 + 0.7921783328056335, + NaN, + -0.7729325890541077 ] ], "expected_grad": [ [ - 1.4003053903579712, - 1.1374733448028564, - 1.2642289400100708 + 2.970088005065918, + 7.763408184051514, + 4.265076637268066 ], [ - 1.2590192556381226, - 0.3253491520881653, - 0.8300010561943054 + 4.3415398597717285, + -0.8905858397483826, + -5.366871356964111 ], [ - 9.099335670471191, - 0.5283496379852295, - 1.5867012739181519 + 0.45285725593566895, + -1.5674054622650146, + 2.166109323501587 ] ] }, @@ -74,36 +74,36 @@ export const testData = { ], "expected_output": [ [ - 1.3064987659454346, - 1.7072854042053223, - 2.2464635372161865 + -1.3191933631896973, + -0.6256667375564575, + -0.2115148901939392 ], [ - 3.0352394580841064, - 0.18455661833286285, - 0.37196338176727295 + 0.10462149977684021, + NaN, + NaN ], [ - 2.6064047813415527, - 3.75142240524292, - 2.2641282081604004 + -0.04293692484498024, + 0.279247909784317, + -0.2018839567899704 ] ], "expected_grad": [ [ - 1.3064987659454346, - 1.7072854042053223, - 2.2464635372161865 + 3.740402936935425, + 1.8694920539855957, + 1.2355483770370483 ], [ - 3.0352394580841064, - 0.18455661833286285, - 0.37196338176727295 + 0.9006653428077698, + -0.5917863845825195, + -1.011163353919983 ], [ - 2.6064047813415527, - 3.75142240524292, - 2.2641282081604004 + 1.0438719987869263, + 0.7563523650169373, + 1.2237060070037842 ] ] }, @@ -127,41 +127,41 @@ export const testData = { ], "expected_output": [ [ - 0.46494385600090027, - 0.47207266092300415, - 3.8672659397125244 + NaN, + NaN, + 0.3019900321960449 ], [ - 1.9863959550857544, - 0.7205368876457214, - 2.214371681213379 + -0.37640848755836487, + NaN, + -0.22945250570774078 ], [ - 1.3251419067382812, - 1.0577706098556519, - 1.6866023540496826 + -1.2675533294677734, + -2.8794875144958496, + -0.6487168669700623 ] ], "expected_grad": [ [ - 0.46494385600090027, - 0.47207266092300415, - 3.8672659397125244 + -1.3057581186294556, + -1.3322278261184692, + 0.7393454313278198 ], [ - 1.9863959550857544, - 0.7205368876457214, - 2.214371681213379 + 1.4570422172546387, + -3.051025629043579, + 1.2579110860824585 ], [ - 1.3251419067382812, - 1.0577706098556519, - 1.6866023540496826 + 3.5521509647369385, + 17.805145263671875, + 1.913084626197815 ] ] } ], - "square": [ + "sqrt": [ { "input": [ [ @@ -182,36 +182,36 @@ export const testData = { ], "expected_output": [ [ - 0.05681400001049042, - 0.002490344224497676, - 0.2770306169986725 + NaN, + NaN, + 0.7254908680915833 ], [ - 7.222999556688592e-05, - 0.5315293669700623, - 0.017726782709360123 + NaN, + 0.8538504242897034, + 0.36488622426986694 ], [ - 0.7464573979377747, - 1.0315951108932495, - 0.7898739576339722 + 0.9295039772987366, + NaN, + NaN ] ], "expected_grad": [ [ - -0.47671374678611755, - -0.09980669617652893, - 1.0526739358901978 + NaN, + NaN, + 0.689188539981842 ], [ - -0.016997646540403366, - 1.4581211805343628, - 0.26628392934799194 + NaN, + 0.5855826735496521, + 1.3702901601791382 ], [ - 1.7279553413391113, - -2.0313494205474854, - -1.7774970531463623 + 0.5379213094711304, + NaN, + NaN ] ] }, @@ -235,36 +235,36 @@ export const testData = { ], "expected_output": [ [ - 0.022433960810303688, - 0.04363667219877243, - 0.14978520572185516 + 0.38701382279396057, + NaN, + NaN ], [ - 0.9825522899627686, - 0.21893326938152313, - 0.041997089982032776 + 0.9956092238426208, + 0.6840344071388245, + NaN ], [ - 0.5489434003829956, - 0.1309279352426529, - 3.6860129833221436 + NaN, + 0.6015310883522034, + 1.3856042623519897 ] ], "expected_grad": [ [ - 0.29955941438674927, - -0.4177878499031067, - -0.7740418910980225 + 1.2919435501098633, + NaN, + NaN ], [ - 1.9824755191802979, - 0.9358060956001282, - -0.40986382961273193 + 0.5022050738334656, + 0.7309573888778687, + NaN ], [ - -1.4818142652511597, - 0.7236793041229248, - 3.8397984504699707 + NaN, + 0.8312122225761414, + 0.3608534038066864 ] ] }, @@ -288,41 +288,41 @@ export const testData = { ], "expected_output": [ [ - 0.05079955235123634, - 0.11675716936588287, - 0.09242375195026398 + NaN, + NaN, + 0.5513734817504883 ], [ - 0.4747397303581238, - 1.2694944143295288, - 0.08165594190359116 + NaN, + NaN, + NaN ], [ - 1.1957663297653198, - 1.2884571552276611, - 0.5764533281326294 + NaN, + 1.0654118061065674, + 0.8713467717170715 ] ], "expected_grad": [ [ - -0.4507751166820526, - -0.6833949685096741, - 0.6080254912376404 + NaN, + NaN, + 0.9068263173103333 ], [ - -1.3780272006988525, - -2.253436803817749, - -0.5715100765228271 + NaN, + NaN, + NaN ], [ - -2.1870219707489014, - 2.270204544067383, - 1.5184904336929321 + NaN, + 0.46930208802223206, + 0.5738243460655212 ] ] } ], - "abs": [ + "exp": [ { "input": [ [ @@ -343,36 +343,36 @@ export const testData = { ], "expected_output": [ [ - 3.594468832015991, - 0.019150810316205025, - 0.1051730141043663 + 0.027475273236632347, + 1.019335389137268, + 1.1109027862548828 ], [ - 0.960340142250061, - 0.5671805739402771, - 0.5706474184989929 + 2.6125850677490234, + 0.5671221613883972, + 0.5651594400405884 ], [ - 1.5980384349822998, - 0.11148621141910553, - 0.03919669985771179 + 4.943326473236084, + 1.1179382801055908, + 0.9615615606307983 ] ], "expected_grad": [ [ - -1.0, - 1.0, - 1.0 + 0.027475273236632347, + 1.019335389137268, + 1.1109027862548828 ], [ - 1.0, - -1.0, - -1.0 + 2.6125850677490234, + 0.5671221613883972, + 0.5651594400405884 ], [ - 1.0, - 1.0, - -1.0 + 4.943326473236084, + 1.1179382801055908, + 0.9615615606307983 ] ] }, @@ -396,36 +396,36 @@ export const testData = { ], "expected_output": [ [ - 1.4111539125442505, - 0.655610978603363, - 0.8576056957244873 + 4.100684642791748, + 0.5191248059272766, + 2.3575093746185303 ], [ - 1.6270242929458618, - 1.3951387405395508, - 0.23872417211532593 + 0.19651347398757935, + 0.24779865145683289, + 0.7876321077346802 ], [ - 0.5049903988838196, - 2.475163221359253, - 0.931602954864502 + 0.603511393070221, + 0.08414925634860992, + 0.39392176270484924 ] ], "expected_grad": [ [ - 1.0, - -1.0, - 1.0 + 4.100684642791748, + 0.5191248059272766, + 2.3575093746185303 ], [ - -1.0, - -1.0, - -1.0 + 0.19651347398757935, + 0.24779865145683289, + 0.7876321077346802 ], [ - -1.0, - -1.0, - -1.0 + 0.603511393070221, + 0.08414925634860992, + 0.39392176270484924 ] ] }, @@ -449,41 +449,41 @@ export const testData = { ], "expected_output": [ [ - 0.13348686695098877, - 0.34148848056793213, - 0.07157137989997864 + 0.8750389814376831, + 1.4070403575897217, + 0.9309298396110535 ], [ - 0.09089037775993347, - 1.3296922445297241, - 0.542582631111145 + 0.9131178259849548, + 0.26455867290496826, + 0.5812451839447021 ], [ - 0.5470984578132629, - 0.6430637240409851, - 0.7904810905456543 + 1.7282311916351318, + 1.9023001194000244, + 0.45362651348114014 ] ], "expected_grad": [ [ - -1.0, - 1.0, - -1.0 + 0.8750389814376831, + 1.4070403575897217, + 0.9309298396110535 ], [ - -1.0, - -1.0, - -1.0 + 0.9131178259849548, + 0.26455867290496826, + 0.5812451839447021 ], [ - 1.0, - 1.0, - -1.0 + 1.7282311916351318, + 1.9023001194000244, + 0.45362651348114014 ] ] } ], - "sign": [ + "square": [ { "input": [ [ @@ -504,36 +504,36 @@ export const testData = { ], "expected_output": [ [ - -1.0, - -1.0, - -1.0 + 0.8205406665802002, + 0.06797784566879272, + 0.2986736297607422 ], [ - 1.0, - -1.0, - 1.0 + 4.4833855628967285, + 2.930264472961426, + 0.027269374579191208 ], [ - 1.0, - 1.0, - 1.0 + 2.502305030822754, + 0.20111723244190216, + 0.0010909737320616841 ] ], "expected_grad": [ [ - 0.0, - 0.0, - 0.0 + -1.8116739988327026, + -0.5214512348175049, + -1.0930207967758179 ], [ - 0.0, - 0.0, - 0.0 + 4.234801292419434, + -3.423603057861328, + 0.33026883006095886 ], [ - 0.0, - 0.0, - 0.0 + 3.1637351512908936, + 0.8969219326972961, + 0.06605978310108185 ] ] }, @@ -557,36 +557,36 @@ export const testData = { ], "expected_output": [ [ - 1.0, - -1.0, - 1.0 + 2.1032471656799316, + 0.48103439807891846, + 0.9933417439460754 ], [ - 1.0, - 1.0, - -1.0 + 0.3758620619773865, + 0.602776825428009, + 0.09175793826580048 ], [ - -1.0, - -1.0, - 1.0 + 1.6263961791992188, + 0.22633972764015198, + 5.683191299438477 ] ], "expected_grad": [ [ - 0.0, - 0.0, - 0.0 + 2.90051531791687, + -1.3871328830718994, + 1.9933305978775024 ], [ - 0.0, - 0.0, - 0.0 + 1.2261518239974976, + 1.5527740716934204, + -0.6058314442634583 ], [ - 0.0, - 0.0, - 0.0 + -2.550604820251465, + -0.9515035152435303, + 4.767889022827148 ] ] }, @@ -610,41 +610,41 @@ export const testData = { ], "expected_output": [ [ - 1.0, - -1.0, - 1.0 + 0.8385612368583679, + 0.41339796781539917, + 0.5059740543365479 ], [ - 1.0, - -1.0, - -1.0 + 0.15998226404190063, + 1.4494271278381348, + 0.17619208991527557 ], [ - -1.0, - -1.0, - 1.0 + 1.4229884147644043, + 0.8743427395820618, + 0.04571162909269333 ] ], "expected_grad": [ [ - 0.0, - 0.0, - 0.0 + 1.8314597606658936, + -1.2859206199645996, + 1.4226371049880981 ], [ - 0.0, - 0.0, - 0.0 + 0.7999556660652161, + -2.4078431129455566, + -0.8395048379898071 ], [ - 0.0, - 0.0, - 0.0 + -2.3857815265655518, + -1.8701258897781372, + 0.4276055693626404 ] ] } ], - "neg": [ + "abs": [ { "input": [ [ @@ -670,14 +670,14 @@ export const testData = { 0.5359472632408142 ], [ - -0.33552202582359314, - -0.2469366192817688, - -0.03243076428771019 + 0.33552202582359314, + 0.2469366192817688, + 0.03243076428771019 ], [ - -0.40568798780441284, - -1.618118405342102, - -0.39315488934516907 + 0.40568798780441284, + 1.618118405342102, + 0.39315488934516907 ] ], "expected_grad": [ @@ -687,14 +687,14 @@ export const testData = { -1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ] ] }, @@ -719,7 +719,7 @@ export const testData = { "expected_output": [ [ 0.2147795557975769, - -1.265119194984436, + 1.265119194984436, 0.31780683994293213 ], [ @@ -728,15 +728,15 @@ export const testData = { 0.1306709349155426 ], [ - -0.9795637726783752, - -0.5959771871566772, + 0.9795637726783752, + 0.5959771871566772, 1.4723340272903442 ] ], "expected_grad": [ [ -1.0, - -1.0, + 1.0, -1.0 ], [ @@ -745,8 +745,8 @@ export const testData = { -1.0 ], [ - -1.0, - -1.0, + 1.0, + 1.0, -1.0 ] ] @@ -772,40 +772,40 @@ export const testData = { "expected_output": [ [ 0.47487422823905945, - -1.6639716625213623, - -0.01096251793205738 + 1.6639716625213623, + 0.01096251793205738 ], [ - -0.14468061923980713, - -1.2818045616149902, + 0.14468061923980713, + 1.2818045616149902, 1.5952012538909912 ], [ 1.064806342124939, - -0.10553700476884842, - -1.9738837480545044 + 0.10553700476884842, + 1.9738837480545044 ] ], "expected_grad": [ [ -1.0, - -1.0, - -1.0 + 1.0, + 1.0 ], [ - -1.0, - -1.0, + 1.0, + 1.0, -1.0 ], [ -1.0, - -1.0, - -1.0 + 1.0, + 1.0 ] ] } ], - "reciprocal": [ + "sign": [ { "input": [ [ @@ -826,36 +826,36 @@ export const testData = { ], "expected_output": [ [ - 0.9343132376670837, - -0.5754157900810242, - 5.4309000968933105 + 1.0, + -1.0, + 1.0 ], [ - -6.399921894073486, - -1.4968883991241455, - 0.8240591883659363 + -1.0, + -1.0, + 1.0 ], [ - 1.2620059251785278, - -2.2724084854125977, - 2.001622200012207 + 1.0, + -1.0, + 1.0 ] ], "expected_grad": [ [ - -0.872941255569458, - -0.3311033248901367, - -29.49467658996582 + 0.0, + 0.0, + 0.0 ], [ - -40.95899963378906, - -2.2406749725341797, - -0.6790735721588135 + 0.0, + 0.0, + 0.0 ], [ - -1.5926589965820312, - -5.163840293884277, - -4.006491661071777 + 0.0, + 0.0, + 0.0 ] ] }, @@ -879,36 +879,36 @@ export const testData = { ], "expected_output": [ [ - -1.3190237283706665, - 1.0010894536972046, - -1.1372942924499512 + -1.0, + 1.0, + -1.0 ], [ - 1.3358300924301147, - -0.7476406693458557, - 1.5505139827728271 + 1.0, + -1.0, + 1.0 ], [ - 1.036016583442688, - 0.9911109209060669, - -29.69889259338379 + 1.0, + 1.0, + -1.0 ] ], "expected_grad": [ [ - -1.739823579788208, - -1.0021800994873047, - -1.2934383153915405 + 0.0, + 0.0, + 0.0 ], [ - -1.7844420671463013, - -0.5589665770530701, - -2.4040935039520264 + 0.0, + 0.0, + 0.0 ], [ - -1.0733304023742676, - -0.982300877571106, - -882.0242309570312 + 0.0, + 0.0, + 0.0 ] ] }, @@ -932,41 +932,41 @@ export const testData = { ], "expected_output": [ [ - -0.9911077618598938, - -0.8120062947273254, - -0.955144464969635 + -1.0, + -1.0, + -1.0 ], [ - -0.5727127194404602, - -2.6722679138183594, - -2.4288580417633057 + -1.0, + -1.0, + -1.0 ], [ - -1.1114226579666138, - 2.074364423751831, - 0.3975999355316162 + -1.0, + 1.0, + 1.0 ] ], "expected_grad": [ [ - -0.9822946190834045, - -0.6593542098999023, - -0.9123009443283081 + 0.0, + 0.0, + 0.0 ], [ - -0.32799986004829407, - -7.141016006469727, - -5.899351596832275 + 0.0, + 0.0, + 0.0 ], [ - -1.2352603673934937, - -4.302987575531006, - -0.15808570384979248 + 0.0, + 0.0, + 0.0 ] ] } ], - "sin": [ + "neg": [ { "input": [ [ @@ -987,36 +987,36 @@ export const testData = { ], "expected_output": [ [ - -0.6978198885917664, - 0.15255698561668396, - 0.9704224467277527 + 0.7723492980003357, + -0.15315502882003784, + -1.3269745111465454 ], [ - -0.7190114259719849, - 0.21532811224460602, - -0.7163253426551819 + 0.8023788928985596, + -2.924564838409424, + 0.7985216975212097 ], [ - -0.5370305180549622, - -0.026698091998696327, - -0.9996917843818665 + 0.5669130086898804, + 0.026701264083385468, + 1.5459672212600708 ] ], "expected_grad": [ [ - 0.7162732481956482, - 0.9882946610450745, - 0.2414131611585617 + -1.0, + -1.0, + -1.0 ], [ - 0.6949982047080994, - -0.9765417575836182, - 0.6977664232254028 + -1.0, + -1.0, + -1.0 ], [ - 0.8435627818107605, - 0.9996435642242432, - 0.02482655458152294 + -1.0, + -1.0, + -1.0 ] ] }, @@ -1040,36 +1040,36 @@ export const testData = { ], "expected_output": [ [ - -0.8201636672019958, - 0.20589278638362885, - -0.9156954288482666 + 2.1798956394195557, + -0.20737595856189728, + 1.9843575954437256 ], [ - -0.18066082894802094, - 0.41502100229263306, - 0.25180983543395996 + 0.1816582977771759, + -0.4279658794403076, + -0.25454989075660706 ], [ - 0.06613095849752426, - -0.9552222490310669, - 0.618959367275238 + -0.06617925316095352, + 1.2704100608825684, + -0.667417049407959 ] ], "expected_grad": [ [ - -0.5721290111541748, - 0.9785745739936829, - -0.4018729031085968 + -1.0, + -1.0, + -1.0 ], [ - 0.9835454821586609, - 0.9098118543624878, - 0.9677767157554626 + -1.0, + -1.0, + -1.0 ], [ - 0.997810959815979, - 0.2958891987800598, - 0.7854230403900146 + -1.0, + -1.0, + -1.0 ] ] }, @@ -1093,41 +1093,41 @@ export const testData = { ], "expected_output": [ [ - -0.841586172580719, - -0.024442683905363083, - 0.2470872402191162 + 1.0002132654190063, + 0.024445118382573128, + -0.24967312812805176 ], [ - -0.9836791753768921, - -0.13053975999355316, - 0.9911724925041199 + 1.7517130374908447, + 0.1309133768081665, + -1.437826156616211 ], [ - -0.15377871692180634, - -0.2814802825450897, - -0.1384945809841156 + 0.154391348361969, + 0.2853364050388336, + 0.1389411836862564 ] ], "expected_grad": [ [ - 0.5401228666305542, - 0.999701201915741, - 0.9689932465553284 + -1.0, + -1.0, + -1.0 ], [ - -0.1799314022064209, - 0.9914430975914001, - 0.13257867097854614 + -1.0, + -1.0, + -1.0 ], [ - 0.988105297088623, - 0.9595670104026794, - 0.9903631806373596 + -1.0, + -1.0, + -1.0 ] ] } ], - "cos": [ + "reciprocal": [ { "input": [ [ @@ -1148,36 +1148,36 @@ export const testData = { ], "expected_output": [ [ - 0.6553789377212524, - 0.8595399856567383, - 0.5027254819869995 + -1.1680712699890137, + -1.8641852140426636, + -0.9578107595443726 ], [ - 0.30949264764785767, - 0.8948525786399841, - 0.9507798552513123 + 0.7960915565490723, + 2.161248207092285, + -3.1740665435791016 ], [ - 0.8534413576126099, - 0.9993184208869934, - 0.687463641166687 + 1.8240073919296265, + 27.083158493041992, + -1.2303065061569214 ] ], "expected_grad": [ [ - 0.7553002238273621, - 0.5110684633255005, - 0.8644461035728455 + -1.36439049243927, + -3.475186586380005, + -0.9174014329910278 ], [ - -0.9509018659591675, - -0.44636186957359314, - 0.30986711382865906 + -0.6337617635726929, + -4.670993804931641, + -10.074698448181152 ], [ - -0.5211888551712036, - -0.036914926022291183, - 0.7262187600135803 + -3.327003002166748, + -733.4974975585938, + -1.513654112815857 ] ] }, @@ -1201,36 +1201,36 @@ export const testData = { ], "expected_output": [ [ - 0.9999271631240845, - 0.8022484183311462, - 0.8011401295661926 + 82.86448669433594, + -1.563124418258667, + 1.5586072206497192 ], [ - 0.8273699283599854, - 0.7415058612823486, - 0.9973865151405334 + -1.6767619848251343, + 1.3596482276916504, + 13.82861614227295 ], [ - -0.2839413583278656, - 0.9231916069984436, - 0.7239072322845459 + 0.5380108952522278, + -2.534900665283203, + 1.313461184501648 ] ], "expected_grad": [ [ - -0.012067602016031742, - 0.5969903469085693, - -0.5984768271446228 + -6866.52294921875, + -2.4433579444885254, + -2.4292564392089844 ], [ - 0.5616573095321655, - -0.6709464192390442, - -0.07225080579519272 + -2.811530828475952, + -1.8486433029174805, + -191.23062133789062 ], [ - -0.9588416814804077, - 0.38433998823165894, - -0.6898972988128662 + -0.28945571184158325, + -6.425721168518066, + -1.7251802682876587 ] ] }, @@ -1254,41 +1254,41 @@ export const testData = { ], "expected_output": [ [ - -0.22616533935070038, - 0.8241740465164185, - 0.78184574842453 + -0.5558843016624451, + -1.660980463027954, + 1.4854965209960938 ], [ - 0.9998328685760498, - 0.998798131942749, - 0.9843894839286804 + 54.697959899902344, + -20.394773483276367, + 5.652095794677734 ], [ - 0.6734060049057007, - -0.42409512400627136, - 0.8488790392875671 + 1.2019375562667847, + -0.49781984090805054, + -1.795540690422058 ] ], "expected_grad": [ [ - 0.9740889072418213, - 0.5663365721702576, - -0.6234719157218933 + -0.30900734663009644, + -2.7588560581207275, + -2.206699848175049 ], [ - -0.018281199038028717, - 0.049012526869773865, - -0.17600393295288086 + -2991.86669921875, + -415.94677734375, + -31.946186065673828 ], [ - -0.7392728924751282, - 0.9056176543235779, - 0.5285871624946594 + -1.444653868675232, + -0.24782459437847137, + -3.223966360092163 ] ] } ], - "tan": [ + "sin": [ { "input": [ [ @@ -1309,36 +1309,36 @@ export const testData = { ], "expected_output": [ [ - 33.786773681640625, - 1.2560005187988281, - -0.7597879767417908 + -0.9995622634887695, + 0.782325267791748, + -0.604976236820221 ], [ - 0.22293990850448608, - 0.6058850288391113, - 1.8932220935821533 + 0.21759793162345886, + 0.5181918740272522, + -0.8842305541038513 ], [ - 0.23882833123207092, - -0.35452449321746826, - 1.617757797241211 + 0.23229525983333588, + -0.33414679765701294, + 0.8506106734275818 ] ], "expected_grad": [ [ - 1142.5460205078125, - 2.5775372982025146, - 1.5772777795791626 + -0.029584426432847977, + 0.622870147228241, + 0.7962434887886047 ], [ - 1.0497021675109863, - 1.3670966625213623, - 4.58428955078125 + 0.9760385155677795, + 0.8552643656730652, + -0.4670506417751312 ], [ - 1.0570390224456787, - 1.125687599182129, - 3.617140293121338 + 0.9726453423500061, + 0.9425210356712341, + 0.5257960557937622 ] ] }, @@ -1362,36 +1362,36 @@ export const testData = { ], "expected_output": [ [ - 2.2095799446105957, - -0.05565134063363075, - -0.37622079253196716 + 0.9110416173934937, + -0.05556536093354225, + -0.352124959230423 ], [ - 1.9927483797073364, - -0.8231356739997864, - 0.15028923749923706 + 0.8937757611274719, + -0.6355260610580444, + 0.14862018823623657 ], [ - -1.5607858896255493, - -14.472814559936523, - 0.007938865572214127 + -0.8420025706291199, + -0.9976214170455933, + 0.007938615046441555 ] ], "expected_grad": [ [ - 5.882243633270264, - 1.0030970573425293, - 1.1415420770645142 + 0.41231441497802734, + 0.9984550476074219, + 0.9359530210494995 ], [ - 4.971046447753906, - 1.677552342414856, - 1.0225868225097656 + 0.44851410388946533, + 0.7720794081687927, + 0.9888943433761597 ], [ - 3.4360525608062744, - 210.4623565673828, - 1.0000630617141724 + 0.5394734740257263, + 0.0689307153224945, + 0.9999684691429138 ] ] }, @@ -1415,45 +1415,43 @@ export const testData = { ], "expected_output": [ [ - 1.0861021280288696, - -1.665249228477478, - -4.83345365524292 + 0.7356656193733215, + -0.8572996854782104, + 0.9792613983154297 ], [ - 0.24961413443088531, - 7.442764759063721, - -0.8537789583206177 + 0.24218325316905975, + 0.9910942912101746, + -0.649315357208252 ], [ - 4.297241687774658, - 0.5771920084953308, - -0.27034449577331543 + 0.9739759564399719, + 0.49989718198776245, + -0.26097580790519714 ] ], "expected_grad": [ [ - 2.1796178817749023, - 3.773055076599121, - 24.362274169921875 + 0.6773448586463928, + 0.5148176550865173, + -0.20260076224803925 ], [ - 1.0623072385787964, - 56.39474868774414, - 1.7289385795593262 + 0.9702305197715759, + 0.13316211104393005, + 0.76051926612854 ], [ - 19.466285705566406, - 1.3331506252288818, - 1.073086142539978 + 0.2266514152288437, + 0.8660847544670105, + 0.9653453230857849 ] ] } - ] - }, - "binary": { - "add": [ + ], + "cos": [ { - "input_x": [ + "input": [ [ -0.3285827040672302, -0.3712422847747803, @@ -1470,77 +1468,96 @@ export const testData = { 0.29541370272636414 ] ], - "input_y": [ + "expected_output": [ [ - 0.23622490465641022, - 0.2450244277715683, - 0.6467189788818359 + 0.9465006589889526, + 0.9318773746490479, + 0.8539305329322815 ], [ - 0.6161983609199524, - 0.0354895144701004, - 1.124637246131897 + 0.1872768998146057, + 0.733598530292511, + -0.840847909450531 ], [ - -0.18692852556705475, - 0.017339814454317093, - -1.3771003484725952 + 0.9948251247406006, + 0.08994252979755402, + 0.9566817879676819 ] ], - "expected_output": [ + "expected_grad": [ [ - -0.09235779941082001, - -0.12621785700321198, - 0.09941482543945312 + 0.3227018713951111, + 0.3627733588218689, + 0.5203870534896851 ], [ - 1.998605489730835, - -0.711704671382904, - -1.4450069665908813 + -0.9823071956634521, + 0.6795830726623535, + 0.541271448135376 ], [ - -0.08515097200870514, - 1.4980719089508057, - -1.0816866159439087 + -0.10160192847251892, + -0.9959469437599182, + -0.29113566875457764 ] - ], - "expected_grad_x": [ + ] + }, + { + "input": [ [ - 1.0, - 1.0, - 1.0 + 0.23622490465641022, + 0.2450244277715683, + 0.6467189788818359 ], [ - 1.0, - 1.0, - 1.0 + 0.6161983609199524, + 0.0354895144701004, + 1.124637246131897 ], [ - 1.0, - 1.0, - 1.0 + -0.18692852556705475, + 0.017339814454317093, + -1.3771003484725952 ] ], - "expected_grad_y": [ + "expected_output": [ [ - 1.0, - 1.0, - 1.0 + 0.9722284078598022, + 0.9701313972473145, + 0.7980651259422302 ], [ - 1.0, - 1.0, - 1.0 + 0.8160814642906189, + 0.9993703365325928, + 0.4315038025379181 ], [ - 1.0, - 1.0, - 1.0 + 0.9825797080993652, + 0.9998496770858765, + 0.19248706102371216 + ] + ], + "expected_grad": [ + [ + -0.23403404653072357, + -0.24258002638816833, + -0.6025711894035339 + ], + [ + -0.5779368877410889, + -0.03548206388950348, + -0.9021111130714417 + ], + [ + 0.18584181368350983, + -0.01733894646167755, + 0.9812995195388794 ] ] }, { - "input_x": [ + "input": [ [ -0.3060486316680908, 0.9692544937133789, @@ -1557,7 +1574,45 @@ export const testData = { 0.8015474677085876 ] ], - "input_y": [ + "expected_output": [ + [ + 0.9535315632820129, + 0.5659143328666687, + 0.7102596759796143 + ], + [ + 0.9600749015808105, + 0.9419117569923401, + 0.04993145540356636 + ], + [ + 0.9936646819114685, + 0.9981294274330139, + 0.6955958008766174 + ] + ], + "expected_grad": [ + [ + 0.3012932538986206, + -0.8244640231132507, + 0.7039397954940796 + ], + [ + -0.2797430753707886, + 0.3358604311943054, + 0.9987526535987854 + ], + [ + -0.11238545924425125, + -0.06113654747605324, + -0.7184333801269531 + ] + ] + } + ], + "tan": [ + { + "input": [ [ -0.43932145833969116, -0.212321937084198, @@ -1576,58 +1631,41 @@ export const testData = { ], "expected_output": [ [ - -0.745370090007782, - 0.7569325566291809, - -0.7036607265472412 - ], - [ - -0.5856937170028687, - -0.2811514735221863, - -1.052941918373108 - ], - [ - 0.548471212387085, - -0.22110554575920105, - -0.4103458523750305 - ] - ], - "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0 + -0.469951868057251, + -0.2155710756778717, + 0.07742276042699814 ], [ - 1.0, - 1.0, - 1.0 + -1.1834511756896973, + 0.0614442303776741, + 0.5053295493125916 ], [ - 1.0, - 1.0, - 1.0 + 0.46571794152259827, + -0.2900247275829315, + -2.6655936241149902 ] ], - "expected_grad_y": [ + "expected_grad": [ [ - 1.0, - 1.0, - 1.0 + 1.2208547592163086, + 1.0464708805084229, + 1.0059943199157715 ], [ - 1.0, - 1.0, - 1.0 + 2.4005565643310547, + 1.0037753582000732, + 1.2553579807281494 ], [ - 1.0, - 1.0, - 1.0 + 1.216893196105957, + 1.0841143131256104, + 8.105389595031738 ] ] }, { - "input_x": [ + "input": [ [ -1.2612135410308838, -0.08296369016170502, @@ -1644,7 +1682,43 @@ export const testData = { -0.25120875239372253 ] ], - "input_y": [ + "expected_output": [ + [ + -3.1262941360473633, + -0.08315455913543701, + -0.8239307999610901 + ], + [ + 0.41336604952812195, + 1.8072755336761475, + -0.6358392238616943 + ], + [ + 3.004908561706543, + -1.184741735458374, + -0.2566298842430115 + ] + ], + "expected_grad": [ + [ + 10.773715019226074, + 1.006914734840393, + 1.6788619756698608 + ], + [ + 1.1708714962005615, + 4.266244888305664, + 1.4042915105819702 + ], + [ + 10.029475212097168, + 2.4036130905151367, + 1.0658588409423828 + ] + ] + }, + { + "input": [ [ 0.1198730394244194, -0.19844388961791992, @@ -1663,58 +1737,43 @@ export const testData = { ], "expected_output": [ [ - -1.1413404941558838, - -0.28140759468078613, - -1.8194291591644287 - ], - [ - 0.6482148170471191, - 0.4818150997161865, - -1.937263011932373 - ], - [ - 1.4882032871246338, - 0.37873655557632446, - -0.20022618770599365 - ] - ], - "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0 + 0.12045053392648697, + -0.2010904848575592, + -2.1212105751037598 ], [ - 1.0, - 1.0, - 1.0 + 0.2619987726211548, + -0.6603164076805115, + -4.935962200164795 ], [ - 1.0, - 1.0, - 1.0 + 0.2433047890663147, + 2.9944915771484375, + 0.05102679133415222 ] ], - "expected_grad_y": [ + "expected_grad": [ [ - 1.0, - 1.0, - 1.0 + 1.0145083665847778, + 1.0404373407363892, + 5.4995341300964355 ], [ - 1.0, - 1.0, - 1.0 + 1.06864333152771, + 1.4360177516937256, + 25.363723754882812 ], [ - 1.0, - 1.0, - 1.0 + 1.059197187423706, + 9.96697998046875, + 1.0026037693023682 ] ] } - ], - "sub": [ + ] + }, + "binary": { + "add": [ { "input_x": [ [ @@ -1752,19 +1811,19 @@ export const testData = { ], "expected_output": [ [ - 0.7507227063179016, - -1.4509949684143066, - -0.17271137237548828 + -0.786133348941803, + -0.06339246034622192, + -3.0293025970458984 ], [ - 0.7668193578720093, - -2.0779006481170654, - 0.07456691563129425 + 0.007897406816482544, + 0.9250181317329407, + 0.3293541669845581 ], [ - 0.053969621658325195, - 1.8060953617095947, - -0.5251361131668091 + 2.1171748638153076, + 0.6433402895927429, + 1.0735963582992554 ] ], "expected_grad_x": [ @@ -1786,19 +1845,19 @@ export const testData = { ], "expected_grad_y": [ [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ] ] }, @@ -1839,19 +1898,19 @@ export const testData = { ], "expected_output": [ [ - 1.1249703168869019, - -1.8528062105178833, - 0.25524136424064636 + -0.1481517255306244, + -2.3951549530029297, + -1.2226922512054443 ], [ - -2.5178608894348145, - 1.2911714315414429, - -0.31431856751441956 + 0.7770457863807678, + 0.281749963760376, + 1.255752682685852 ], [ - -1.4352920055389404, - 0.6602849960327148, - 2.0033652782440186 + -0.695212185382843, + 0.8113704919815063, + -1.1427743434906006 ] ], "expected_grad_x": [ @@ -1873,19 +1932,19 @@ export const testData = { ], "expected_grad_y": [ [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ] ] }, @@ -1926,19 +1985,19 @@ export const testData = { ], "expected_output": [ [ - 0.4692777991294861, - 1.4351651668548584, - 0.5000553727149963 + -0.028997838497161865, + -0.9650461673736572, + 1.508737564086914 ], [ - -0.156881183385849, - 0.7784876227378845, - 2.2813289165496826 + 1.0272313356399536, + -0.8703276515007019, + -0.7992322444915771 ], [ - 0.14233431220054626, - -0.9179326891899109, - -0.9211282730102539 + 1.0528199672698975, + 2.3416502475738525, + -1.6955103874206543 ] ], "expected_grad_x": [ @@ -1960,24 +2019,24 @@ export const testData = { ], "expected_grad_y": [ [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ], [ - -1.0, - -1.0, - -1.0 + 1.0, + 1.0, + 1.0 ] ] } ], - "mul": [ + "sub": [ { "input_x": [ [ @@ -2015,53 +2074,53 @@ export const testData = { ], "expected_output": [ [ - 0.2202553153038025, - -0.29448404908180237, - -0.045864038169384 + -0.8803563117980957, + 1.72179114818573, + 1.092673420906067 ], [ - 0.01861557364463806, - -0.2776021957397461, - -0.4659140110015869 + -1.4679075479507446, + -1.4264907836914062, + -1.5360690355300903 ], [ - -0.8313737511634827, - 0.07335689663887024, - -0.22940771281719208 + 2.009246349334717, + -1.024686574935913, + -1.0319061279296875 ] ], "expected_grad_x": [ [ - 1.0836158990859985, - -0.19257144629955292, - -1.0489495992660522 + 1.0, + 1.0, + 1.0 ], [ - -0.012573999352753162, - 1.1939914226531982, - 1.120118260383606 + 1.0, + 1.0, + 1.0 ], [ - -0.5828483700752258, - -0.06718457490205765, - 0.3241202235221863 + 1.0, + 1.0, + 1.0 ] ], "expected_grad_y": [ [ - 0.20325958728790283, - 1.5292197465896606, - 0.04372377693653107 + -1.0, + -1.0, + -1.0 ], [ - -1.480481505393982, - -0.23249931633472443, - -0.415950745344162 + -1.0, + -1.0, + -1.0 ], [ - 1.4263980388641357, - -1.0918711423873901, - -0.7077858448028564 + -1.0, + -1.0, + -1.0 ] ] }, @@ -2102,53 +2161,53 @@ export const testData = { ], "expected_output": [ [ - -0.029275935143232346, - -0.09945051372051239, - 1.2150179147720337 + -0.7643988728523254, + -0.8310680389404297, + -1.6912363767623901 ], [ - -0.03419021889567375, - 0.2788444757461548, - 0.035011112689971924 + -1.5844520330429077, + 0.548811674118042, + 0.05120289325714111 ], [ - 0.8207830190658569, - -0.27409273386001587, - -1.08944833278656 + 0.345409631729126, + -1.0487160682678223, + 2.1715738773345947 ] ], "expected_grad_x": [ [ - 0.723960280418396, - 0.14494575560092926, - 2.234894275665283 + 1.0, + 1.0, + 1.0 ], [ - 0.02188074216246605, - 0.32069334387779236, - 0.16325443983078003 + 1.0, + 1.0, + 1.0 ], [ - -1.0949900150299072, - 0.5536599159240723, - -0.7866464257240295 + 1.0, + 1.0, + 1.0 ] ], "expected_grad_y": [ [ - -0.04043859243392944, - -0.6861222982406616, - 0.5436578989028931 + -1.0, + -1.0, + -1.0 ], [ - -1.5625712871551514, - 0.8695050477981567, - 0.21445733308792114 + -1.0, + -1.0, + -1.0 ], [ - -0.7495803833007812, - -0.49505615234375, - 1.38492751121521 + -1.0, + -1.0, + -1.0 ] ] }, @@ -2189,58 +2248,58 @@ export const testData = { ], "expected_output": [ [ - -0.8085776567459106, - -0.01373219769448042, - 0.18104469776153564 + -1.9191246032714844, + -0.2981038987636566, + 0.8249977231025696 ], [ - 0.22671200335025787, - -0.033192481845617294, - 0.3475377857685089 + 0.5591975450515747, + -0.43864262104034424, + -0.6537379026412964 ], [ - -0.015795210376381874, - -0.8425819873809814, - 0.03430353105068207 + -0.3334060311317444, + 1.9608203172683716, + 0.1065615564584732 ] ], "expected_grad_x": [ [ - 1.2944984436035156, - 0.24116213619709015, - 0.18012243509292603 + 1.0, + 1.0, + 1.0 ], [ - -0.8317649364471436, - 0.34142518043518066, - 1.0009468793869019 + 1.0, + 1.0, + 1.0 ], [ - 0.05718276649713516, - -1.3248257637023926, - -0.24600434303283691 + 1.0, + 1.0, + 1.0 ] ], "expected_grad_y": [ [ - -0.6246262192726135, - -0.056941766291856766, - 1.0051201581954956 + -1.0, + -1.0, + -1.0 ], [ - -0.27256739139556885, - -0.09721744060516357, - 0.34720900654792786 + -1.0, + -1.0, + -1.0 ], [ - -0.2762232720851898, - 0.635994553565979, - -0.1394427865743637 + -1.0, + -1.0, + -1.0 ] ] } ], - "div": [ + "mul": [ { "input_x": [ [ @@ -2278,53 +2337,53 @@ export const testData = { ], "expected_output": [ [ - 0.058350104838609695, - 33.27659225463867, - -0.7134724855422974 + 0.0628381296992302, + 0.009683297947049141, + -0.1581626981496811 ], [ - 33.562042236328125, - -2.977651834487915, - 0.851044774055481 + 0.005554346367716789, + -2.0220115184783936, + 2.8057525157928467 ], [ - -1.4740052223205566, - 1.2500494718551636, - -2.592123508453369 + -0.14114482700824738, + 0.2514669895172119, + -0.27389153838157654 ] ], "expected_grad_x": [ [ - 0.9636275172233582, - 58.621612548828125, - -2.1239123344421387 + 1.0377453565597534, + 0.01705855503678322, + -0.47082921862602234 ], [ - 77.73340606689453, - -1.213515043258667, - 0.5507462024688721 + 0.012864481657743454, + -0.8240524530410767, + 1.8157182931900024 ], [ - 3.231595754623413, - 2.2295804023742676, - 3.0763697624206543 + 0.3094446361064911, + 0.4485149085521698, + 0.3250584602355957 ] ], "expected_grad_y": [ [ - -0.05622776597738266, - -1950.7275390625, - -1.5153530836105347 + 0.06055254861712456, + 0.567650556564331, + 0.3359237015247345 ], [ - -2608.891845703125, - -3.6134250164031982, - -0.46870970726013184 + 0.4317582845687866, + 2.4537413120269775, + 1.545257568359375 ], [ - 4.7633891105651855, - -2.787085771560669, - 7.974330425262451 + -0.456123024225235, + 0.5606658458709717, + -0.8425916433334351 ] ] }, @@ -2365,53 +2424,53 @@ export const testData = { ], "expected_output": [ [ - -3.5962283611297607, - 2.666862964630127, - 119.15495300292969 + -0.44358164072036743, + 0.22852395474910736, + 0.004473161417990923 ], [ - -0.004044986795634031, - 0.31635257601737976, - -10.809895515441895 + -0.007110574748367071, + 0.11582902818918228, + -0.054763324558734894 ], [ - 1.465734601020813, - 0.8268014788627625, - 50.61146545410156 + 1.5055385828018188, + 0.6754500865936279, + 0.022664213553071022 ] ], "expected_grad_x": [ [ - 2.8473236560821533, - 3.416130781173706, - -163.21075439453125 + 0.3512069880962372, + 0.29272884130477905, + -0.006127047352492809 ], [ - 0.7542341351509094, - 1.652635097503662, - 14.049660682678223 + 1.3258482217788696, + 0.6050942540168762, + 0.07117609679698944 ], [ - -0.9866922497749329, - 1.1063791513442993, - -47.25569152832031 + -1.0134872198104858, + 0.9038492441177368, + -0.02116147242486477 ] ], "expected_grad_y": [ [ - 10.23962688446045, - -9.110352516174316, - 19447.369140625 + -1.2630205154418945, + 0.7806677222251892, + -0.730068027973175 ], [ - 0.003050867235288024, - -0.5228153467178345, - 151.8753662109375 + -0.005363038275390863, + 0.19142311811447144, + -0.7694061398506165 ], [ - 1.4462289810180664, - -0.9147559404373169, - 2391.6796875 + -1.4855033159255981, + 0.7473039031028748, + -1.07101309299469 ] ] }, @@ -2452,58 +2511,58 @@ export const testData = { ], "expected_output": [ [ - 1.2626498937606812, - 0.5017896294593811, - -0.06757807731628418 + 1.6085083484649658, + 0.31065061688423157, + -0.0039521800354123116 ], [ - 3.013411521911621, - 7.231535911560059, - 0.5109900236129761 + 1.2733886241912842, + 0.3972281217575073, + 2.2871179580688477 ], [ - -74.80128479003906, - -0.06570270657539368, - 0.2003955990076065 + -0.05141746625304222, + -0.22311604022979736, + 0.021861689165234566 ] ], "expected_grad_x": [ [ - -0.8859920501708984, - -1.2709391117095947, - 4.1350860595703125 + -1.128678321838379, + -0.7868197560310364, + 0.2418329268693924 ], [ - -1.5383273363113403, - -4.266731262207031, - -0.4726742208003998 + -0.6500567197799683, + -0.23437145352363586, + -2.115622043609619 ], [ - -38.141624450683594, - 0.5426580309867859, - -3.0276260375976562 + -0.026218075305223465, + 1.8427811861038208, + -0.3302917778491974 ] ], "expected_grad_y": [ [ - 1.1186977624893188, - 0.6377440690994263, - 0.2794411778450012 + -1.4251255989074707, + -0.3948180079460144, + -0.016342604532837868 ], [ - 4.635613441467285, - 30.85502052307129, - 0.24153180420398712 + -1.9588884115219116, + -1.6948655843734741, + -1.0810617208480835 ], [ - -2853.04248046875, - 0.03565410152077675, - 0.6067229509353638 + 1.9611457586288452, + -0.12107571214437485, + -0.06618902087211609 ] ] } ], - "maximum": [ + "div": [ { "input_x": [ [ @@ -2541,53 +2600,53 @@ export const testData = { ], "expected_output": [ [ - 1.341455340385437, - -0.4575539231300354, - 0.6742424964904785 + 0.632189154624939, + 0.6619322896003723, + -1.8396412134170532 ], [ - 1.325866937637329, - -0.27575162053108215, - 0.22375407814979553 + -2.4499568939208984, + 3.4978513717651367, + -7.159341812133789 ], [ - -0.1522003561258316, - 1.3587521314620972, - 1.6083942651748657 + 1.9658098220825195, + -1.02150559425354, + 2.9248526096343994 ] ], "expected_grad_x": [ [ - 0.0, - 1.0, - 0.0 + 0.7454590201377869, + -1.4466760158538818, + 1.4831459522247314 ], [ - 1.0, - 0.0, - 0.0 + -1.8478150367736816, + -3.6264519691467285, + 4.4691925048828125 ], [ - 0.0, - 1.0, - 1.0 + -6.570286750793457, + -0.7517968416213989, + 1.8184924125671387 ] ], "expected_grad_y": [ [ - 1.0, - 0.0, - 1.0 + -0.4712711274623871, + 0.9576015472412109, + 2.7284562587738037 ], [ - 0.0, - 1.0, - 1.0 + -4.527067184448242, + 12.684789657592773, + 31.996475219726562 ], [ - 1.0, - 0.0, - 0.0 + 12.915934562683105, + -0.7679647207260132, + -5.318821907043457 ] ] }, @@ -2628,53 +2687,53 @@ export const testData = { ], "expected_output": [ [ - 0.9215105772018433, - 0.5769692659378052, - 0.6269291639328003 + 0.6799914836883545, + 1.2445317506790161, + -0.8627113699913025 ], [ - 2.1126511096954346, - 0.1117599681019783, - 0.5981283187866211 + 7.7279229164123535, + 1.1115553379058838, + 2.572852849960327 ], [ - 0.7063558101654053, - 0.3692564070224762, - -0.8367782831192017 + -0.6144076585769653, + -1.586733341217041, + 1.3896194696426392 ] ], "expected_grad_x": [ [ - 0.0, - 1.0, - 1.0 + 1.0851746797561646, + 2.157015562057495, + -1.3760906457901 ], [ - 1.0, - 1.0, - 1.0 + 3.657926559448242, + 9.945916175842285, + 4.301506519317627 ], [ - 0.0, - 0.0, - 0.0 + 1.4157171249389648, + 2.7081453800201416, + -1.1950596570968628 ] ], "expected_grad_y": [ [ - 1.0, - 0.0, - 0.0 + -0.7379095554351807, + -2.684474468231201, + -1.187169075012207 ], [ - 0.0, - 0.0, - 0.0 + -28.26817512512207, + -11.055437088012695, + -11.067143440246582 ], [ - 1.0, - 1.0, - 1.0 + 0.8698274493217468, + 4.297104358673096, + 1.6606782674789429 ] ] }, @@ -2715,58 +2774,58 @@ export const testData = { ], "expected_output": [ [ - -0.13591812551021576, - 0.24926981329917908, - 0.5908606648445129 + 8.978617668151855, + -1.2592661380767822, + -0.5268927812576294 ], [ - -0.606251060962677, - 0.2932665944099426, - 1.1621606349945068 + 2.585892915725708, + -2.138516902923584, + 1.5625298023223877 ], [ - -0.19546888768672943, - 1.2695143222808838, - 0.21413196623325348 + 10.024543762207031, + 0.9763122200965881, + -3.544419527053833 ] ], "expected_grad_x": [ [ - 0.0, - 0.0, - 1.0 + -7.357370376586914, + 4.011717319488525, + -0.8917378187179565 ], [ - 0.0, - 0.0, - 1.0 + -1.6494816541671753, + 3.4098668098449707, + 1.3445041179656982 ], [ - 0.0, - 0.0, - 0.0 + -5.115903854370117, + 0.7877027988433838, + 4.670017242431641 ] ], "expected_grad_y": [ [ - 1.0, - 1.0, - 0.0 + 66.05901336669922, + 5.051819801330566, + -0.46985021233558655 ], [ - 1.0, - 1.0, - 0.0 + 4.265382766723633, + 7.292057514190674, + -2.100827693939209 ], [ - 1.0, - 1.0, - 1.0 + 51.28459930419922, + -0.7690438628196716, + 16.552501678466797 ] ] } ], - "minimum": [ + "pow": [ { "input_x": [ [ @@ -2804,53 +2863,53 @@ export const testData = { ], "expected_output": [ [ - -1.0992363691329956, - -3.066803455352783, - -2.4677371978759766 + 0.6246066689491272, + NaN, + NaN ], [ - -1.2484521865844727, - -2.239192247390747, - -0.732846200466156 + 9.622306823730469, + NaN, + 2.3571856021881104 ], [ - -2.3703532218933105, - 0.06774814426898956, - -0.3587782680988312 + NaN, + 0.17098508775234222, + NaN ] ], "expected_grad_x": [ [ - 0.0, - 1.0, - 1.0 + -0.447462260723114, + NaN, + NaN ], [ - 0.0, - 0.0, - 0.0 + -73.66305541992188, + NaN, + -5.566137313842773 ], [ - 0.0, - 1.0, - 1.0 + NaN, + 1.6558737754821777, + NaN ] ], "expected_grad_y": [ [ - 1.0, - 0.0, - 0.0 + 0.26742255687713623, + NaN, + NaN ], [ - 1.0, - 1.0, - 1.0 + -17.450176239013672, + NaN, + -2.758030414581299 ], [ - 1.0, - 0.0, - 0.0 + NaN, + -0.4602847099304199, + NaN ] ] }, @@ -2891,53 +2950,53 @@ export const testData = { ], "expected_output": [ [ - -0.9435422420501709, - -0.6576043367385864, - -0.0943203940987587 + NaN, + 1.0503326654434204, + 1.0224924087524414 ], [ - 1.4321774244308472, - -1.350498914718628, - -0.5367263555526733 + 1.8830409049987793, + NaN, + 0.9298480749130249 ], [ - -0.8979145288467407, - -0.3949545621871948, - -1.3240617513656616 + 1.559626817703247, + NaN, + NaN ] ], "expected_grad_x": [ [ - 1.0, - 0.0, - 0.0 + NaN, + -0.7442565560340881, + -0.12209095805883408 ], [ - 0.0, - 1.0, - 0.0 + 1.7335611581802368, + NaN, + -0.4358246922492981 ], [ - 0.0, - 0.0, - 0.0 + -2.297318935394287, + NaN, + NaN ] ], "expected_grad_y": [ [ - 0.0, - 1.0, - 1.0 + NaN, + -0.07843408733606339, + -0.2411300390958786 ], [ - 1.0, - 0.0, - 1.0 + 0.8321272730827332, + NaN, + 0.12600766122341156 ], [ - 1.0, - 1.0, - 1.0 + -0.7719786763191223, + NaN, + NaN ] ] }, @@ -2978,42 +3037,464 @@ export const testData = { ], "expected_output": [ [ - -0.9920331239700317, - -0.21955861151218414, - 0.549020528793335 + NaN, + NaN, + 0.8590410351753235 ], [ - -0.6107911467552185, - -0.42454805970191956, - -0.6808373332023621 + NaN, + 0.80033278465271, + NaN ], [ - 0.5729089975357056, - -2.3586840629577637, - -0.9791588187217712 + 0.7379259467124939, + NaN, + 1.7782634496688843 + ] + ], + "expected_grad_x": [ + [ + NaN, + NaN, + 0.6220011711120605 + ], + [ + NaN, + -0.20107434689998627, + NaN + ], + [ + 0.718586802482605, + NaN, + -3.1344869136810303 + ] + ], + "expected_grad_y": [ + [ + NaN, + NaN, + -0.23773515224456787 + ], + [ + NaN, + 0.419872909784317, + NaN + ], + [ + -0.39144858717918396, + NaN, + -1.0454225540161133 + ] + ] + } + ], + "maximum": [ + { + "input_x": [ + [ + 2.2314751148223877, + -0.14775699377059937, + -0.7025889158248901 + ], + [ + -1.3201872110366821, + -1.8284006118774414, + 0.19090472161769867 + ], + [ + 0.17843060195446014, + 1.00639808177948, + 0.9555224180221558 + ] + ], + "input_y": [ + [ + 0.39204949140548706, + 1.397952914237976, + 1.2648344039916992 + ], + [ + -1.6484825611114502, + -0.17498807609081268, + 0.44165265560150146 + ], + [ + 0.6014829277992249, + -0.5517386794090271, + 0.5157949924468994 + ] + ], + "expected_output": [ + [ + 2.2314751148223877, + 1.397952914237976, + 1.2648344039916992 + ], + [ + -1.3201872110366821, + -0.17498807609081268, + 0.44165265560150146 + ], + [ + 0.6014829277992249, + 1.00639808177948, + 0.9555224180221558 ] ], "expected_grad_x": [ [ + 1.0, 0.0, + 0.0 + ], + [ 1.0, + 0.0, 0.0 ], [ + 0.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 0.0, 1.0, + 1.0 + ], + [ 0.0, + 1.0, 1.0 ], [ + 1.0, + 0.0, + 0.0 + ] + ] + }, + { + "input_x": [ + [ + 1.7731256484985352, + -1.6310747861862183, + 1.7790842056274414 + ], + [ + 0.03431599214673042, + 0.4497534930706024, + -0.4963332414627075 + ], + [ + 1.0892176628112793, + -2.281388759613037, + 0.13769249618053436 + ] + ], + "input_y": [ + [ + -1.073378562927246, + -1.0421594381332397, + 1.1992487907409668 + ], + [ + 1.8445014953613281, + 0.5515044331550598, + -1.4479703903198242 + ], + [ + 1.2580268383026123, + -0.16691471636295319, + -1.46559476852417 + ] + ], + "expected_output": [ + [ + 1.7731256484985352, + -1.0421594381332397, + 1.7790842056274414 + ], + [ + 1.8445014953613281, + 0.5515044331550598, + -0.4963332414627075 + ], + [ + 1.2580268383026123, + -0.16691471636295319, + 0.13769249618053436 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 1.0, + 0.0 + ], + [ + 1.0, + 1.0, + 0.0 + ] + ] + }, + { + "input_x": [ + [ + -0.16166037321090698, + 1.3858773708343506, + 0.5715627670288086 + ], + [ + -0.20138078927993774, + -0.09701951593160629, + 2.2975573539733887 + ], + [ + -0.02061469666659832, + -0.6522951722145081, + -0.04624612256884575 + ] + ], + "input_y": [ + [ + 1.0050909519195557, + -0.39795130491256714, + 2.0522775650024414 + ], + [ + 1.2850029468536377, + 0.25980693101882935, + 0.1596033275127411 + ], + [ + 0.8647605776786804, + 0.630111575126648, + 1.3362239599227905 + ] + ], + "expected_output": [ + [ + 1.0050909519195557, + 1.3858773708343506, + 2.0522775650024414 + ], + [ + 1.2850029468536377, + 0.25980693101882935, + 2.2975573539733887 + ], + [ + 0.8647605776786804, + 0.630111575126648, + 1.3362239599227905 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, 0.0, + 1.0 + ], + [ + 1.0, + 1.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + } + ], + "minimum": [ + { + "input_x": [ + [ + -0.9831093549728394, + -0.12308304011821747, + -0.8408450484275818 + ], + [ + 0.48604804277420044, + 1.138323426246643, + -0.2449806183576584 + ], + [ + 1.8371145725250244, + 2.1368844509124756, + 2.196890354156494 + ] + ], + "input_y": [ + [ + 0.9145165085792542, + -0.3624510169029236, + 1.4744350910186768 + ], + [ + -0.8670269846916199, + -0.843208909034729, + 0.06224742531776428 + ], + [ + 0.4080433249473572, + -1.2516316175460815, + -1.2717373371124268 + ] + ], + "expected_output": [ + [ + -0.9831093549728394, + -0.3624510169029236, + -0.8408450484275818 + ], + [ + -0.8670269846916199, + -0.843208909034729, + -0.2449806183576584 + ], + [ + 0.4080433249473572, + -1.2516316175460815, + -1.2717373371124268 + ] + ], + "expected_grad_x": [ + [ 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, 0.0 ] ], "expected_grad_y": [ [ + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 1.0, + 0.0 + ], + [ + 1.0, 1.0, + 1.0 + ] + ] + }, + { + "input_x": [ + [ + 0.8055283427238464, + 1.0920584201812744, + 0.8560135960578918 + ], + [ + 1.5192112922668457, + 0.44675812125205994, + -0.2566242218017578 + ], + [ + 1.7753183841705322, + -0.7927579879760742, + -1.6142888069152832 + ] + ], + "input_y": [ + [ + 0.31103116273880005, + 1.7946441173553467, + 3.19868803024292 + ], + [ + 0.2567588686943054, + 0.8679211735725403, + -1.1851390600204468 + ], + [ + 0.7940642833709717, + 0.19724640250205994, + 0.622898280620575 + ] + ], + "expected_output": [ + [ + 0.31103116273880005, + 1.0920584201812744, + 0.8560135960578918 + ], + [ + 0.2567588686943054, + 0.44675812125205994, + -1.1851390600204468 + ], + [ + 0.7940642833709717, + -0.7927579879760742, + -1.6142888069152832 + ] + ], + "expected_grad_x": [ + [ 0.0, + 1.0, 1.0 ], [ @@ -3021,10 +3502,114 @@ export const testData = { 1.0, 0.0 ], + [ + 0.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 0.0, + 0.0 + ], [ 1.0, 0.0, 1.0 + ], + [ + 1.0, + 0.0, + 0.0 + ] + ] + }, + { + "input_x": [ + [ + 1.186416506767273, + 1.3099017143249512, + -2.1073341369628906 + ], + [ + -0.22107578814029694, + 0.9579378366470337, + -1.3392482995986938 + ], + [ + -1.3702017068862915, + -0.32176926732063293, + 0.1034090593457222 + ] + ], + "input_y": [ + [ + -0.07071641087532043, + -0.3897135257720947, + 1.7265616655349731 + ], + [ + 1.084613561630249, + 1.1876388788223267, + 0.5510113835334778 + ], + [ + -0.27905166149139404, + 0.6056016683578491, + -2.1992974281311035 + ] + ], + "expected_output": [ + [ + -0.07071641087532043, + -0.3897135257720947, + -2.1073341369628906 + ], + [ + -0.22107578814029694, + 0.9579378366470337, + -1.3392482995986938 + ], + [ + -1.3702017068862915, + -0.32176926732063293, + -2.1992974281311035 + ] + ], + "expected_grad_x": [ + [ + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 0.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0 ] ] } From 69d807b65427d732f3605b18445adc8b8a066b1a Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sun, 8 Mar 2026 17:24:38 +0800 Subject: [PATCH 076/128] feat: verify that generated tests are up to date --- .../{push.yml => build-test-publish.yml} | 2 +- .github/workflows/verify-generated-tests.yml | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) rename .github/workflows/{push.yml => build-test-publish.yml} (98%) create mode 100644 .github/workflows/verify-generated-tests.yml diff --git a/.github/workflows/push.yml b/.github/workflows/build-test-publish.yml similarity index 98% rename from .github/workflows/push.yml rename to .github/workflows/build-test-publish.yml index 6641b328..74704699 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/build-test-publish.yml @@ -1,4 +1,4 @@ -name: test-on-push +name: Build, Test, Publish on: [push] diff --git a/.github/workflows/verify-generated-tests.yml b/.github/workflows/verify-generated-tests.yml new file mode 100644 index 00000000..29b9a1bb --- /dev/null +++ b/.github/workflows/verify-generated-tests.yml @@ -0,0 +1,38 @@ +name: Verify Generated Tests + +on: [push] + +jobs: + verify-sync: + runs-on: ubuntu-latest + steps: + - name: Check out source code + uses: actions/checkout@v4 + + - name: Enable Corepack + run: corepack enable + + - name: Use Node.js 💻 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + + - name: Install dependencies + run: yarn install --immutable + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.14' + cache: 'pip' + + - name: Install Python Dependencies + run: pip install -r scripts/requirements.txt + + - name: Regenerate test data + run: yarn update-tests + + - name: Check for differences + run: | + git diff --exit-code test/tensor_ops_data.gen.js || (echo "❌ test/tensor_ops_data.gen.js is out of sync! Please run 'yarn update-tests' locally and commit the updated file." && exit 1) \ No newline at end of file From d579ad17c5c2a4a6b166b4e008eee6656ffa3889 Mon Sep 17 00:00:00 2001 From: Vee Hua Zhi Date: Sun, 8 Mar 2026 17:36:36 +0800 Subject: [PATCH 077/128] feat: use cpu-only torch for minimal installation --- scripts/requirements.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index f60a2ca9..5dec6caf 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1 +1,4 @@ -torch==2.10.0 \ No newline at end of file +--extra-index-url https://download.pytorch.org/whl/cpu + +torch==2.10.0 +numpy From 3fa5a31d07363e89125d4892161f047c9c53f63e Mon Sep 17 00:00:00 2001 From: Vee Hua Zhi Date: Sun, 8 Mar 2026 17:43:04 +0800 Subject: [PATCH 078/128] feat: sanity check in auto-generated tests --- .github/workflows/verify-generated-tests.yml | 24 ++++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/verify-generated-tests.yml b/.github/workflows/verify-generated-tests.yml index 29b9a1bb..90689149 100644 --- a/.github/workflows/verify-generated-tests.yml +++ b/.github/workflows/verify-generated-tests.yml @@ -26,13 +26,27 @@ jobs: with: python-version: '3.14' cache: 'pip' + cache-dependency-path: scripts/requirements.txt - name: Install Python Dependencies run: pip install -r scripts/requirements.txt - - name: Regenerate test data - run: yarn update-tests - - - name: Check for differences + - name: Sanity Check Generated File Length run: | - git diff --exit-code test/tensor_ops_data.gen.js || (echo "❌ test/tensor_ops_data.gen.js is out of sync! Please run 'yarn update-tests' locally and commit the updated file." && exit 1) \ No newline at end of file + # 1. Count lines of the file currently checked into Git + COMMITTED_LINES=$(wc -l < test/tensor_ops_data.gen.js) + + # 2. Regenerate the file using your script + yarn update-tests + + # 3. Count lines of the newly generated file + GENERATED_LINES=$(wc -l < test/tensor_ops_data.gen.js) + + # 4. Compare and fail if different + if [ "$COMMITTED_LINES" -ne "$GENERATED_LINES" ]; then + echo "❌ Line count mismatch! Committed: $COMMITTED_LINES, Generated: $GENERATED_LINES." + echo "Please run 'yarn update-tests' locally and commit the updated test file." + exit 1 + fi + + echo "✅ Line counts match ($COMMITTED_LINES lines). Sanity check passed." From 382ca02e7aeb38a602a6c2dc41f4dd29348a572e Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sun, 8 Mar 2026 22:46:46 +0800 Subject: [PATCH 079/128] feat: add generated testcases for broadcast and matmul * Fix .shape * Fix AccumulateGrad not unbroadcasting before adding * Add Squeeze Function * Fix Matmul backward --- package.json | 2 +- scripts/generate_tests.py | 78 +- src/broadcasting.ts | 9 + src/functions/base.ts | 10 +- src/functions/ops.ts | 142 +- src/tensor.ts | 15 +- test/custom_operations.test.js | 4 +- test/functional.test.js | 4 +- test/generated.test.js | 40 +- test/index.html | 1 + ...ensor_ops_data.gen.js => testcases.gen.js} | 2232 ++++++++++++++++- 11 files changed, 2482 insertions(+), 55 deletions(-) rename test/{tensor_ops_data.gen.js => testcases.gen.js} (64%) diff --git a/package.json b/package.json index 72e264fe..876926a0 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "serve": "http-server -p 8080 -c-1", "test": "mocha test/**/*.test.ts test/**/*.test.js", "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js", - "update-tests": "python3 scripts/generate_tests.py > test/tensor_ops_data.gen.js", + "update-tests": "python3 scripts/generate_tests.py > test/testcases.gen.js", "watch": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\"" }, "devDependencies": { diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index bc2f9fae..ae903bc7 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -13,7 +13,7 @@ def generate_unary_tests(op_name, num_tests=3): torch_op = getattr(torch, op_name) y = torch_op(x) y.sum().backward() - + tests.append({ "input": x.detach().numpy().tolist(), "expected_output": y.detach().numpy().tolist(), @@ -26,11 +26,11 @@ def generate_binary_tests(op_name, num_tests=3): for i in range(num_tests): x = torch.randn(3, 3, requires_grad=True) y = torch.randn(3, 3, requires_grad=True) - + torch_op = getattr(torch, op_name) out = torch_op(x, y) out.sum().backward() - + tests.append({ "input_x": x.detach().numpy().tolist(), "input_y": y.detach().numpy().tolist(), @@ -40,11 +40,79 @@ def generate_binary_tests(op_name, num_tests=3): }) return tests +def generate_broadcasting_tests(): + shape_pairs = [ + ((2, 3), (2, 3)), + ((), (2, 2)), + ((2, 3, 4, 1), (3, 1, 1)), + ((1,), (3, 1, 2)), + ((5, 1, 4, 1), (3, 1, 1)) + ] + + ops = ['add', 'mul'] + tests = [] + + for shape_x, shape_y in shape_pairs: + for op_name in ops: + x = torch.randn(shape_x, requires_grad=True) if shape_x != () else torch.tensor(1.5, requires_grad=True) + y = torch.randn(shape_y, requires_grad=True) if shape_y != () else torch.tensor(-0.5, requires_grad=True) + + torch_op = getattr(torch, op_name) + out = torch_op(x, y) + + out.sum().backward() + + sx_str = "scalar" if shape_x == () else str(shape_x) + sy_str = "scalar" if shape_y == () else str(shape_y) + + tests.append({ + "test_name": f"broadcast_{op_name}_{sx_str}_and_{sy_str}", + "op_name": op_name, + "input_x": x.detach().numpy().tolist(), + "input_y": y.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_x": x.grad.numpy().tolist() if x.grad is not None else 0.0, + "expected_grad_y": y.grad.numpy().tolist() if y.grad is not None else 0.0 + }) + + return tests + +def generate_matmul_tests(): + matmul_cases = [ + ((3,), (3,), "1D_dot_product"), + ((2, 3), (3, 4), "2D_matrix_multiply"), + ((3,), (3, 4), "1D_2D_prepend_remove"), + ((2, 3), (3,), "2D_1D_matrix_vector"), + ((2, 1, 2, 3), (3, 3, 2), "ND_batched_with_broadcast") + ] + + tests = [] + + for shape_x, shape_y, desc in matmul_cases: + x = torch.randn(shape_x, requires_grad=True) + y = torch.randn(shape_y, requires_grad=True) + + out = torch.matmul(x, y) + out.sum().backward() + + tests.append({ + "test_name": f"matmul_{desc}", + "input_x": x.detach().numpy().tolist(), + "input_y": y.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_x": x.grad.numpy().tolist(), + "expected_grad_y": y.grad.numpy().tolist() + }) + + return tests + if __name__ == "__main__": suite = { "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, - "binary": {op: generate_binary_tests(op) for op in BINARY_OPS} + "binary": {op: generate_binary_tests(op) for op in BINARY_OPS}, + "broadcasting": generate_broadcasting_tests(), + "matmul": generate_matmul_tests() } print("export const testData = ", end="") - print(json.dumps(suite, indent=2), end=";\n") \ No newline at end of file + print(json.dumps(suite, indent=2), end=";\n") diff --git a/src/broadcasting.ts b/src/broadcasting.ts index 105b9b6b..d26e1b9a 100644 --- a/src/broadcasting.ts +++ b/src/broadcasting.ts @@ -21,6 +21,15 @@ export function _broadcast_shape(a_shape: number[], b_shape: number[]): number[] return result_shape; } +export function _unbroadcast(result_shape: number[], original_shape: number[], result: number[]) { + const this_shape = _pad_shape(original_shape, result_shape) + const unbroadcasted_result = new Array(original_shape.reduce((acc, cur) => acc * cur, 1)).fill(0); + for(let i = 0; i < result.length; i++){ + unbroadcasted_result[_get_original_index(this_shape, result_shape, i)] += result[i]; + } + return unbroadcasted_result; +} + export function _pad_shape(shape: number[], broadcast_shape: number[]): number[] { if (shape.length >= broadcast_shape.length) { return shape; diff --git a/src/functions/base.ts b/src/functions/base.ts index bb6944df..4fd6151d 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -1,3 +1,4 @@ +import { _get_original_index, _pad_shape, _unbroadcast } from '../broadcasting'; import { zeros_like } from '../creation'; import { Tensor } from '../tensor'; import { eventBus, getNextId, events } from '../util'; @@ -89,12 +90,17 @@ export class AccumulateGrad extends UnaryFunction { return variable; } - protected _backward(dz: Tensor): void { + protected _backward(dz: Tensor | number): void { if (!this.variable.grad) { this.variable.grad = zeros_like(this.variable); } eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); - this.variable.grad = this.variable.grad.add(dz); + if(typeof dz === "number") { + this.variable.grad = this.variable.grad.add(dz); + } else { + const unbroadcasted_dz = _unbroadcast(dz.shape, this.variable.shape, dz.data); + this.variable.grad = this.variable.grad.add(new Tensor(unbroadcasted_dz, {}, { shape: this.variable.shape })); + } eventBus.dispatchEvent(new CustomEvent(events.OPERATION_AFTER_ACCUMULATE_GRAD, { detail: { operation: this, dz } })); } } diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 1149b63a..be98d938 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -4,7 +4,8 @@ import { _get_original_index_from_transposed_index, _get_original_index, _get_original_index_kernel, - _pad_shape + _pad_shape, + _unbroadcast } from '../broadcasting'; import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; import * as functional from './functional'; @@ -12,6 +13,11 @@ import { registerOperation } from './registry'; import { zeros_like } from '../creation'; import { UnaryFunctionMixin, BinaryFunctionMixin } from './mixin'; +function unbroadcast(result: Tensor, original_shape: number[]): Tensor { + const unbroadcasted_result = _unbroadcast(result.shape, original_shape, result.data); + return new Tensor(unbroadcasted_result, { requires_grad: result.requires_grad }, { shape: original_shape }); +} + // debug operations const __Left_index__ = BinaryFunctionMixin( @@ -237,6 +243,55 @@ export class Reshape extends TorchFunction { } registerOperation('reshape', Reshape); +export class Squeeze extends TorchFunction { + protected _forward(a: Tensor, dim?: number) { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else if (a.requires_grad) { + const acc = new AccumulateGrad(); + acc.variable = a; + this.next_functions.push(acc); + } else { + this.next_functions.push(nullOp); + } + + let shape = [...a.shape]; + + if (dim !== undefined) { + if (dim < 0) { + dim += a.shape.length; + } + + // PyTorch only squeezes the specified dimension if its size is exactly 1 + if (shape[dim] === 1) { + shape.splice(dim, 1); + } + } else { + // If no dim is provided, strip out all dimensions of size 1 + shape = shape.filter((d) => d !== 1); + } + + return new Tensor( + a.data, + { requires_grad: a.requires_grad }, + { operation: a.requires_grad ? this : null, shape } + ); + } + + protected _backward(dz: Tensor) { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + // The derivative of squeeze is just reshaping the gradient + // back to the original unsqueezed shape. + aFn.backward(dz.reshape(a.shape)); + } +} +registerOperation('squeeze', Squeeze); + export class Unsqueeze extends TorchFunction { protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { @@ -432,9 +487,9 @@ export class Transpose extends TorchFunction { } registerOperation('transpose', Transpose); -function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor { +function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = null): [Tensor, number[]] { if (a.shape.length == 1 && b.shape.length == 1) { - return a.mul(b).sum(); + return [a.mul(b).sum(), []]; } const a_1d = a.shape.length == 1; @@ -489,51 +544,78 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = shape_after_removing_extra_dims = shape_after_removing_extra_dims.slice(0, -1); } - return new Tensor( + return [new Tensor( data, { requires_grad: a.requires_grad || b.requires_grad }, { operation: operation, shape: shape_after_removing_extra_dims } - ); + ), shape_after_removing_extra_dims]; } -// class generated from matmul_op_class() + export class Matmul extends BinaryFunction { + private shape: number[]; + protected _forward(a: Tensor, b: Tensor): Tensor { if (a.requires_grad || b.requires_grad) { this.saved_tensors = [a, b]; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); + const result = _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); + this.shape = result[1]; + return result[0]; } - protected _backward(dz: Tensor): void { +protected _backward(dz: Tensor): void { const [a, b] = this.saved_tensors; const [aFn, bFn] = this.next_functions; - // backward_operations: - if (a.shape.length == 1 && b.shape.length == 1) { - aFn.backward(dz); - bFn.backward(dz); + // 1. 1D x 1D (Dot Product) + if (a.shape.length === 1 && b.shape.length === 1) { + aFn.backward(dz.mul(b)); + bFn.backward(dz.mul(a)); return; } - if (a.shape.length == 1) { - const dz1 = dz.unsqueeze(0); - const a1 = a.unsqueeze(0); - aFn.backward(dz1.matmul(b.transpose(-2, -1))); - bFn.backward(a1.transpose(0, 1).matmul(dz1)); + // 2. 1D x ND + if (a.shape.length === 1) { + const dz1 = dz.unsqueeze(-2); + const a1 = a.unsqueeze(-2); + + let da = dz1.matmul(b.transpose(-2, -1)); + let db = a1.transpose(-2, -1).matmul(dz1); + + da = da.squeeze(-2); + db = unbroadcast(db, b.shape); + + aFn.backward(da); + bFn.backward(db); return; } - if (b.shape.length == 1) { - const dz1 = dz.unsqueeze(0); - const b1 = b.unsqueeze(1); - aFn.backward(dz1.matmul(b1.transpose(0, 1))); - bFn.backward(a.transpose(-2, -1).matmul(dz1)); + // 3. ND x 1D + if (b.shape.length === 1) { + const dz1 = dz.unsqueeze(-1); + const b1 = b.unsqueeze(-1); + + let da = dz1.matmul(b1.transpose(-2, -1)); + let db = a.transpose(-2, -1).matmul(dz1); + + da = unbroadcast(da, a.shape); + db = db.squeeze(-1); + + aFn.backward(da); + bFn.backward(db); return; } - aFn.backward(dz.matmul(b.transpose(-2, -1))); - bFn.backward(a.transpose(-2, -1).matmul(dz)); + // 4. ND x ND (Batched or Standard) + let da = dz.matmul(b.transpose(-2, -1)); + let db = a.transpose(-2, -1).matmul(dz); + + da = unbroadcast(da, a.shape); + db = unbroadcast(db, b.shape); + + aFn.backward(da); + bFn.backward(db); } } registerOperation('matmul', Matmul); @@ -542,36 +624,36 @@ registerOperation('matmul', Matmul); const Lt = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] < b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => {}, + (a, b, aFn, bFn) => { }, "lt" ); const Gt = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] > b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => {}, + (a, b, aFn, bFn) => { }, "gt" ); const Le = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] <= b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => {}, + (a, b, aFn, bFn) => { }, "le" ); const Ge = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] >= b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => {}, + (a, b, aFn, bFn) => { }, "ge" ); const Eq = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] == b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => {}, + (a, b, aFn, bFn) => { }, "eq" ); const Ne = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] != b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => {}, + (a, b, aFn, bFn) => { }, "ne" ); diff --git a/src/tensor.ts b/src/tensor.ts index 872695b9..e96198a3 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -80,13 +80,8 @@ export class Tensor { } } - // TODO: Somehow having a shape of [] will have a weird error: - // TypeError: Cannot read properties of undefined (reading 'length') - // when running kernel (something to do with constants?) - // so a little hack to return [1] when the shape is [] get shape(): number[] { - return this._shape.length === 0 ? [1] : this._shape; - // return this._shape; + return this._shape; } toArray_(): void { @@ -154,7 +149,7 @@ export class Tensor { if (this.dataLength() !== 1) { throw new Error('Tensor.item() is only valid for scalars'); } - return this.toArray()[0]; + return this.data[0]; } detach(): Tensor { @@ -281,6 +276,10 @@ export class Tensor { return this._executeOpRaw('reshape', shape); } + squeeze(dim: number): Tensor { + return this._executeOpRaw('squeeze', dim); + } + unsqueeze(dim: number): Tensor { return this._executeOpRaw('unsqueeze', dim); } @@ -344,7 +343,7 @@ export class Tensor { ne(other: Tensor | number): Tensor { return this._executeBinaryOp('ne', other); } - + // other sigmoid(): Tensor { diff --git a/test/custom_operations.test.js b/test/custom_operations.test.js index 409be47b..12773947 100644 --- a/test/custom_operations.test.js +++ b/test/custom_operations.test.js @@ -45,7 +45,7 @@ describe('Custom Operations', () => { const t2 = new Tensor([4, 5, 6]); const result = t1.matmul(t2); - assert.deepStrictEqual(result.shape, [1]); + assert.deepStrictEqual(result.shape, []); assert.deepStrictEqual(Array.from(result.toFlatArray()), [32]); }); @@ -85,7 +85,7 @@ describe('Custom Operations', () => { const t2Grad = Array.from(t2.grad.toFlatArray()); assert.deepStrictEqual(t2Grad, [4, 4, 6, 6]); - }); + }); }); describe('Transpose', () => { diff --git a/test/functional.test.js b/test/functional.test.js index 754e2003..d1f6c1a5 100644 --- a/test/functional.test.js +++ b/test/functional.test.js @@ -61,7 +61,7 @@ describe('Functional', () => { const result = torch.matmul(t1, t2); assert.deepStrictEqual(Array.from(result.toFlatArray()), [200]); - assert.deepStrictEqual(result.shape, [1]); + assert.deepStrictEqual(result.shape, []); }); it('should multiply two tensors with 1 dim', () => { @@ -70,7 +70,7 @@ describe('Functional', () => { const result = torch.matmul(t1, t2); assert.deepStrictEqual(Array.from(result.toFlatArray()), [70]); - assert.deepStrictEqual(result.shape, [1]); + assert.deepStrictEqual(result.shape, []); }); it('should multiply two tensors with shape (2, 3) and (3, 3) with the correct values', () => { diff --git a/test/generated.test.js b/test/generated.test.js index 49160088..491fb03b 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -1,12 +1,12 @@ import { Tensor } from 'torch'; import { assert } from 'chai'; -import { testData } from './tensor_ops_data.gen'; +import { testData } from './testcases.gen.js'; -function assertDeepCloseTo(actual, expected, delta = 1e-3) { +function assertDeepCloseTo(actual, expected, delta = 1e-3, first_call = true) { if (Array.isArray(expected)) { assert.lengthOf(actual, expected.length, 'Array lengths do not match'); for (let i = 0; i < expected.length; i++) { - assertDeepCloseTo(actual[i], expected[i], delta); + assertDeepCloseTo(actual[i], expected[i], delta, false); } } else { if (Number.isNaN(expected)) { @@ -51,4 +51,36 @@ describe('Automated Tests', () => { }); } }); -}); \ No newline at end of file + + describe('Broadcasting Operations', () => { + testData.broadcasting?.forEach((test) => { + it(test.test_name, () => { + const x = new Tensor(test.input_x, { requires_grad: true }); + const y = new Tensor(test.input_y, { requires_grad: true }); + + const out = x[test.op_name](y); + + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + }); + }); + }); + + describe('Matmul Operations', () => { + testData.matmul?.forEach((test) => { + it(test.test_name, () => { + const x = new Tensor(test.input_x, { requires_grad: true }); + const y = new Tensor(test.input_y, { requires_grad: true }); + + const out = x.matmul(y); + + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + }); + }); + }); +}); diff --git a/test/index.html b/test/index.html index 2f9b5f1d..1b85e075 100644 --- a/test/index.html +++ b/test/index.html @@ -37,6 +37,7 @@ import "./nn_functional.test.js"; import "./optimizers.test.js"; import "./tensor.test.js"; + import "./generated.test.js" mocha.run(); diff --git a/test/tensor_ops_data.gen.js b/test/testcases.gen.js similarity index 64% rename from test/tensor_ops_data.gen.js rename to test/testcases.gen.js index 79b115b8..788d8c8a 100644 --- a/test/tensor_ops_data.gen.js +++ b/test/testcases.gen.js @@ -3614,5 +3614,2235 @@ export const testData = { ] } ] - } + }, + "broadcasting": [ + { + "test_name": "broadcast_add_(2, 3)_and_(2, 3)", + "op_name": "add", + "input_x": [ + [ + 0.10101978480815887, + -1.7474379539489746, + 0.49967822432518005 + ], + [ + -1.2637113332748413, + 0.19651830196380615, + -0.4187171757221222 + ] + ], + "input_y": [ + [ + 0.48351433873176575, + 0.9704157710075378, + -0.1363738477230072 + ], + [ + -0.4913654327392578, + 0.5787925720214844, + -0.5241618156433105 + ] + ], + "expected_output": [ + [ + 0.5845341086387634, + -0.7770221829414368, + 0.36330437660217285 + ], + [ + -1.7550767660140991, + 0.7753108739852905, + -0.9428789615631104 + ] + ], + "expected_grad_x": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ], + "expected_grad_y": [ + [ + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0 + ] + ] + }, + { + "test_name": "broadcast_mul_(2, 3)_and_(2, 3)", + "op_name": "mul", + "input_x": [ + [ + -0.8587943315505981, + 0.32446324825286865, + -0.17433615028858185 + ], + [ + 0.6593497395515442, + -0.5109422206878662, + -0.944842517375946 + ] + ], + "input_y": [ + [ + -0.5671818852424622, + 0.4958496391773224, + 1.1620975732803345 + ], + [ + 0.726780116558075, + 0.6438865661621094, + 0.6418544054031372 + ] + ], + "expected_output": [ + [ + 0.4870925843715668, + 0.16088499128818512, + -0.20259562134742737 + ], + [ + 0.4792022705078125, + -0.32898882031440735, + -0.6064513325691223 + ] + ], + "expected_grad_x": [ + [ + -0.5671818852424622, + 0.4958496391773224, + 1.1620975732803345 + ], + [ + 0.726780116558075, + 0.6438865661621094, + 0.6418544054031372 + ] + ], + "expected_grad_y": [ + [ + -0.8587943315505981, + 0.32446324825286865, + -0.17433615028858185 + ], + [ + 0.6593497395515442, + -0.5109422206878662, + -0.944842517375946 + ] + ] + }, + { + "test_name": "broadcast_add_scalar_and_(2, 2)", + "op_name": "add", + "input_x": 1.5, + "input_y": [ + [ + 0.7264923453330994, + -0.023122388869524002 + ], + [ + -0.5372034311294556, + -0.5396077632904053 + ] + ], + "expected_output": [ + [ + 2.226492404937744, + 1.4768775701522827 + ], + [ + 0.9627965688705444, + 0.9603922367095947 + ] + ], + "expected_grad_x": 4.0, + "expected_grad_y": [ + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + }, + { + "test_name": "broadcast_mul_scalar_and_(2, 2)", + "op_name": "mul", + "input_x": 1.5, + "input_y": [ + [ + 0.6077166199684143, + 0.27988874912261963 + ], + [ + -1.0373796224594116, + 0.589288592338562 + ] + ], + "expected_output": [ + [ + 0.9115749597549438, + 0.41983312368392944 + ], + [ + -1.5560693740844727, + 0.883932888507843 + ] + ], + "expected_grad_x": 0.4395143389701843, + "expected_grad_y": [ + [ + 1.5, + 1.5 + ], + [ + 1.5, + 1.5 + ] + ] + }, + { + "test_name": "broadcast_add_(2, 3, 4, 1)_and_(3, 1, 1)", + "op_name": "add", + "input_x": [ + [ + [ + [ + -0.10694646835327148 + ], + [ + 0.6531567573547363 + ], + [ + -1.015342116355896 + ], + [ + -0.8090125918388367 + ] + ], + [ + [ + -0.5131909251213074 + ], + [ + -0.8087556958198547 + ], + [ + 1.1124427318572998 + ], + [ + 0.11936674267053604 + ] + ], + [ + [ + 0.6386357545852661 + ], + [ + -0.4361383616924286 + ], + [ + -1.0022987127304077 + ], + [ + 0.3780289888381958 + ] + ] + ], + [ + [ + [ + 0.04276036471128464 + ], + [ + 0.5858650803565979 + ], + [ + -1.3687634468078613 + ], + [ + 1.1168509721755981 + ] + ], + [ + [ + 0.27692535519599915 + ], + [ + 1.0580254793167114 + ], + [ + -0.05147926136851311 + ], + [ + 0.17128385603427887 + ] + ], + [ + [ + -0.21165163815021515 + ], + [ + -0.1787608563899994 + ], + [ + -0.8498311638832092 + ], + [ + 1.166976809501648 + ] + ] + ] + ], + "input_y": [ + [ + [ + 1.2661118507385254 + ] + ], + [ + [ + 0.5520188808441162 + ] + ], + [ + [ + -0.2482202798128128 + ] + ] + ], + "expected_output": [ + [ + [ + [ + 1.159165382385254 + ], + [ + 1.9192686080932617 + ], + [ + 0.2507697343826294 + ], + [ + 0.4570992588996887 + ] + ], + [ + [ + 0.03882795572280884 + ], + [ + -0.2567368149757385 + ], + [ + 1.664461612701416 + ], + [ + 0.671385645866394 + ] + ], + [ + [ + 0.3904154896736145 + ], + [ + -0.6843586564064026 + ], + [ + -1.250519037246704 + ], + [ + 0.129808709025383 + ] + ] + ], + [ + [ + [ + 1.3088722229003906 + ], + [ + 1.8519768714904785 + ], + [ + -0.10265159606933594 + ], + [ + 2.382962703704834 + ] + ], + [ + [ + 0.828944206237793 + ], + [ + 1.6100443601608276 + ], + [ + 0.5005396008491516 + ], + [ + 0.7233027219772339 + ] + ], + [ + [ + -0.45987191796302795 + ], + [ + -0.4269811511039734 + ], + [ + -1.0980514287948608 + ], + [ + 0.9187565445899963 + ] + ] + ] + ], + "expected_grad_x": [ + [ + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ], + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ], + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ] + ], + [ + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ], + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ], + [ + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ], + [ + 1.0 + ] + ] + ] + ], + "expected_grad_y": [ + [ + [ + 8.0 + ] + ], + [ + [ + 8.0 + ] + ], + [ + [ + 8.0 + ] + ] + ] + }, + { + "test_name": "broadcast_mul_(2, 3, 4, 1)_and_(3, 1, 1)", + "op_name": "mul", + "input_x": [ + [ + [ + [ + 0.20935998857021332 + ], + [ + 1.505028486251831 + ], + [ + -1.1346086263656616 + ], + [ + -0.7111839056015015 + ] + ], + [ + [ + -0.8095768690109253 + ], + [ + 0.41242745518684387 + ], + [ + 2.0646610260009766 + ], + [ + -0.32648909091949463 + ] + ], + [ + [ + -0.16211076080799103 + ], + [ + 0.49002620577812195 + ], + [ + 0.9112547636032104 + ], + [ + 1.792615532875061 + ] + ] + ], + [ + [ + [ + 1.0188977718353271 + ], + [ + -1.8317182064056396 + ], + [ + 0.2806217670440674 + ], + [ + 0.6909231543540955 + ] + ], + [ + [ + 0.9776358604431152 + ], + [ + 0.7260830402374268 + ], + [ + 1.2465280294418335 + ], + [ + 0.6389282941818237 + ] + ], + [ + [ + 0.38033702969551086 + ], + [ + -1.962886095046997 + ], + [ + -0.7805798053741455 + ], + [ + -0.1343953162431717 + ] + ] + ] + ], + "input_y": [ + [ + [ + -1.4443291425704956 + ] + ], + [ + [ + 0.9527847170829773 + ] + ], + [ + [ + -2.000053644180298 + ] + ] + ], + "expected_output": [ + [ + [ + [ + -0.30238473415374756 + ], + [ + -2.1737565994262695 + ], + [ + 1.638748288154602 + ], + [ + 1.0271836519241333 + ] + ], + [ + [ + -0.7713524699211121 + ], + [ + 0.39295458793640137 + ], + [ + 1.9671775102615356 + ], + [ + -0.31107380986213684 + ] + ], + [ + [ + 0.32423022389411926 + ], + [ + -0.9800786972045898 + ], + [ + -1.8225584030151367 + ], + [ + -3.5853271484375 + ] + ] + ], + [ + [ + [ + -1.4716237783432007 + ], + [ + 2.645603895187378 + ], + [ + -0.40531018376350403 + ], + [ + -0.9979204535484314 + ] + ], + [ + [ + 0.9314765334129333 + ], + [ + 0.6918008327484131 + ], + [ + 1.1876728534698486 + ], + [ + 0.6087611317634583 + ] + ], + [ + [ + -0.7606944441795349 + ], + [ + 3.925877571105957 + ], + [ + 1.5612014532089233 + ], + [ + 0.2687978446483612 + ] + ] + ] + ], + "expected_grad_x": [ + [ + [ + [ + -1.4443291425704956 + ], + [ + -1.4443291425704956 + ], + [ + -1.4443291425704956 + ], + [ + -1.4443291425704956 + ] + ], + [ + [ + 0.9527847170829773 + ], + [ + 0.9527847170829773 + ], + [ + 0.9527847170829773 + ], + [ + 0.9527847170829773 + ] + ], + [ + [ + -2.000053644180298 + ], + [ + -2.000053644180298 + ], + [ + -2.000053644180298 + ], + [ + -2.000053644180298 + ] + ] + ], + [ + [ + [ + -1.4443291425704956 + ], + [ + -1.4443291425704956 + ], + [ + -1.4443291425704956 + ], + [ + -1.4443291425704956 + ] + ], + [ + [ + 0.9527847170829773 + ], + [ + 0.9527847170829773 + ], + [ + 0.9527847170829773 + ], + [ + 0.9527847170829773 + ] + ], + [ + [ + -2.000053644180298 + ], + [ + -2.000053644180298 + ], + [ + -2.000053644180298 + ], + [ + -2.000053644180298 + ] + ] + ] + ], + "expected_grad_y": [ + [ + [ + 0.027320444583892822 + ] + ], + [ + [ + 4.930197715759277 + ] + ], + [ + [ + 0.5342614650726318 + ] + ] + ] + }, + { + "test_name": "broadcast_add_(1,)_and_(3, 1, 2)", + "op_name": "add", + "input_x": [ + -0.5958812236785889 + ], + "input_y": [ + [ + [ + 0.07782832533121109, + 0.5926167964935303 + ] + ], + [ + [ + 1.030975103378296, + -0.663306713104248 + ] + ], + [ + [ + -0.11067406833171844, + -0.2901550829410553 + ] + ] + ], + "expected_output": [ + [ + [ + -0.518052875995636, + -0.0032644271850585938 + ] + ], + [ + [ + 0.43509387969970703, + -1.259187936782837 + ] + ], + [ + [ + -0.7065553069114685, + -0.8860362768173218 + ] + ] + ], + "expected_grad_x": [ + 6.0 + ], + "expected_grad_y": [ + [ + [ + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "broadcast_mul_(1,)_and_(3, 1, 2)", + "op_name": "mul", + "input_x": [ + -0.698898434638977 + ], + "input_y": [ + [ + [ + -0.7456109523773193, + 1.1263020038604736 + ] + ], + [ + [ + -0.7577127814292908, + -0.24528881907463074 + ] + ], + [ + [ + -0.477226585149765, + -1.3771432638168335 + ] + ] + ], + "expected_output": [ + [ + [ + 0.5211063027381897, + -0.7871707081794739 + ] + ], + [ + [ + 0.5295642614364624, + 0.17143197357654572 + ] + ], + [ + [ + 0.3335328996181488, + 0.962483286857605 + ] + ] + ], + "expected_grad_x": [ + -2.4766805171966553 + ], + "expected_grad_y": [ + [ + [ + -0.698898434638977, + -0.698898434638977 + ] + ], + [ + [ + -0.698898434638977, + -0.698898434638977 + ] + ], + [ + [ + -0.698898434638977, + -0.698898434638977 + ] + ] + ] + }, + { + "test_name": "broadcast_add_(5, 1, 4, 1)_and_(3, 1, 1)", + "op_name": "add", + "input_x": [ + [ + [ + [ + -0.8496796488761902 + ], + [ + -0.6987038254737854 + ], + [ + -0.20516234636306763 + ], + [ + -0.7811664342880249 + ] + ] + ], + [ + [ + [ + -0.8665743470191956 + ], + [ + -0.30639445781707764 + ], + [ + -0.5359372496604919 + ], + [ + -0.35750812292099 + ] + ] + ], + [ + [ + [ + -1.4471426010131836 + ], + [ + -1.6966946125030518 + ], + [ + -2.1704893112182617 + ], + [ + -0.3568725883960724 + ] + ] + ], + [ + [ + [ + 0.21925963461399078 + ], + [ + 0.4133651852607727 + ], + [ + 0.0061524491757154465 + ], + [ + -0.5672794580459595 + ] + ] + ], + [ + [ + [ + 0.10004822909832001 + ], + [ + -0.2485211342573166 + ], + [ + -0.9125545620918274 + ], + [ + -0.8421810865402222 + ] + ] + ] + ], + "input_y": [ + [ + [ + -0.13354362547397614 + ] + ], + [ + [ + 0.5437685251235962 + ] + ], + [ + [ + -2.3363192081451416 + ] + ] + ], + "expected_output": [ + [ + [ + [ + -0.9832232594490051 + ], + [ + -0.8322474360466003 + ], + [ + -0.33870595693588257 + ], + [ + -0.9147100448608398 + ] + ], + [ + [ + -0.305911123752594 + ], + [ + -0.1549353003501892 + ], + [ + 0.33860617876052856 + ], + [ + -0.2373979091644287 + ] + ], + [ + [ + -3.1859989166259766 + ], + [ + -3.0350229740142822 + ], + [ + -2.5414814949035645 + ], + [ + -3.117485523223877 + ] + ] + ], + [ + [ + [ + -1.0001180171966553 + ], + [ + -0.4399380683898926 + ], + [ + -0.6694808602333069 + ], + [ + -0.49105173349380493 + ] + ], + [ + [ + -0.32280582189559937 + ], + [ + 0.23737406730651855 + ], + [ + 0.007831275463104248 + ], + [ + 0.1862604022026062 + ] + ], + [ + [ + -3.2028934955596924 + ], + [ + -2.6427135467529297 + ], + [ + -2.8722565174102783 + ], + [ + -2.6938273906707764 + ] + ] + ], + [ + [ + [ + -1.5806862115859985 + ], + [ + -1.8302382230758667 + ], + [ + -2.304033041000366 + ], + [ + -0.4904162287712097 + ] + ], + [ + [ + -0.9033740758895874 + ], + [ + -1.1529260873794556 + ], + [ + -1.6267207860946655 + ], + [ + 0.1868959367275238 + ] + ], + [ + [ + -3.783461809158325 + ], + [ + -4.033013820648193 + ], + [ + -4.506808280944824 + ], + [ + -2.6931917667388916 + ] + ] + ], + [ + [ + [ + 0.08571600914001465 + ], + [ + 0.27982157468795776 + ], + [ + -0.12739117443561554 + ], + [ + -0.7008230686187744 + ] + ], + [ + [ + 0.7630281448364258 + ], + [ + 0.9571337103843689 + ], + [ + 0.5499209761619568 + ], + [ + -0.02351093292236328 + ] + ], + [ + [ + -2.1170594692230225 + ], + [ + -1.9229540824890137 + ], + [ + -2.330166816711426 + ], + [ + -2.9035987854003906 + ] + ] + ], + [ + [ + [ + -0.03349539637565613 + ], + [ + -0.3820647597312927 + ], + [ + -1.046098232269287 + ], + [ + -0.9757246971130371 + ] + ], + [ + [ + 0.6438167691230774 + ], + [ + 0.2952473759651184 + ], + [ + -0.3687860369682312 + ], + [ + -0.298412561416626 + ] + ], + [ + [ + -2.2362709045410156 + ], + [ + -2.5848402976989746 + ], + [ + -3.248873710632324 + ], + [ + -3.178500175476074 + ] + ] + ] + ], + "expected_grad_x": [ + [ + [ + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ] + ] + ], + [ + [ + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ] + ] + ], + [ + [ + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ] + ] + ], + [ + [ + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ] + ] + ], + [ + [ + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ], + [ + 3.0 + ] + ] + ] + ], + "expected_grad_y": [ + [ + [ + 20.0 + ] + ], + [ + [ + 20.0 + ] + ], + [ + [ + 20.0 + ] + ] + ] + }, + { + "test_name": "broadcast_mul_(5, 1, 4, 1)_and_(3, 1, 1)", + "op_name": "mul", + "input_x": [ + [ + [ + [ + -0.7984835505485535 + ], + [ + 0.5182347893714905 + ], + [ + -1.1608222723007202 + ], + [ + -1.0226510763168335 + ] + ] + ], + [ + [ + [ + -0.89991295337677 + ], + [ + 0.4791645407676697 + ], + [ + -0.24811258912086487 + ], + [ + -1.3093348741531372 + ] + ] + ], + [ + [ + [ + -0.2919580638408661 + ], + [ + 0.45643651485443115 + ], + [ + -0.3147018849849701 + ], + [ + -0.41328999400138855 + ] + ] + ], + [ + [ + [ + -0.17061950266361237 + ], + [ + -0.6140995025634766 + ], + [ + 0.53551185131073 + ], + [ + -1.6644023656845093 + ] + ] + ], + [ + [ + [ + -0.15447334945201874 + ], + [ + -1.6013476848602295 + ], + [ + -0.059470854699611664 + ], + [ + -0.9928666353225708 + ] + ] + ] + ], + "input_y": [ + [ + [ + -1.1151187419891357 + ] + ], + [ + [ + -0.6466555595397949 + ] + ], + [ + [ + -0.9256587624549866 + ] + ] + ], + "expected_output": [ + [ + [ + [ + 0.8904039859771729 + ], + [ + -0.5778933167457581 + ], + [ + 1.2944546937942505 + ], + [ + 1.140377402305603 + ] + ], + [ + [ + 0.5163438320159912 + ], + [ + -0.3351193964481354 + ], + [ + 0.7506521940231323 + ], + [ + 0.6613029837608337 + ] + ], + [ + [ + 0.7391232848167419 + ], + [ + -0.47970858216285706 + ], + [ + 1.0745253562927246 + ], + [ + 0.9466259479522705 + ] + ] + ], + [ + [ + [ + 1.003509759902954 + ], + [ + -0.534325361251831 + ], + [ + 0.2766749858856201 + ], + [ + 1.4600638151168823 + ] + ], + [ + [ + 0.5819337368011475 + ], + [ + -0.3098544180393219 + ], + [ + 0.16044338047504425 + ], + [ + 0.8466886878013611 + ] + ], + [ + [ + 0.8330122828483582 + ], + [ + -0.44354286789894104 + ], + [ + 0.22966758906841278 + ], + [ + 1.2119972705841064 + ] + ] + ], + [ + [ + [ + 0.32556790113449097 + ], + [ + -0.508980929851532 + ], + [ + 0.35092997550964355 + ], + [ + 0.46086740493774414 + ] + ], + [ + [ + 0.18879631161689758 + ], + [ + -0.29515722393989563 + ], + [ + 0.20350372791290283 + ], + [ + 0.2672562599182129 + ] + ], + [ + [ + 0.2702535390853882 + ], + [ + -0.4225044548511505 + ], + [ + 0.2913065552711487 + ], + [ + 0.3825654983520508 + ] + ] + ], + [ + [ + [ + 0.19026100635528564 + ], + [ + 0.6847938895225525 + ], + [ + -0.5971593260765076 + ], + [ + 1.8560062646865845 + ] + ], + [ + [ + 0.11033204942941666 + ], + [ + 0.39711084961891174 + ], + [ + -0.346291720867157 + ], + [ + 1.076295018196106 + ] + ], + [ + [ + 0.15793544054031372 + ], + [ + 0.5684465765953064 + ], + [ + -0.49570122361183167 + ], + [ + 1.5406686067581177 + ] + ] + ], + [ + [ + [ + 0.17225612699985504 + ], + [ + 1.785692811012268 + ], + [ + 0.06631706655025482 + ], + [ + 1.1071641445159912 + ] + ], + [ + [ + 0.0998910516500473 + ], + [ + 1.0355204343795776 + ], + [ + 0.03845715895295143 + ], + [ + 0.6420427560806274 + ] + ], + [ + [ + 0.1429896056652069 + ], + [ + 1.4823014736175537 + ], + [ + 0.05504971742630005 + ], + [ + 0.919055700302124 + ] + ] + ] + ], + "expected_grad_x": [ + [ + [ + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ] + ] + ], + [ + [ + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ] + ] + ], + [ + [ + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ] + ] + ], + [ + [ + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ] + ] + ], + [ + [ + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ], + [ + -2.6874330043792725 + ] + ] + ] + ], + "expected_grad_y": [ + [ + [ + -9.72719955444336 + ] + ], + [ + [ + -9.72719955444336 + ] + ], + [ + [ + -9.72719955444336 + ] + ] + ] + } + ], + "matmul": [ + { + "test_name": "matmul_1D_dot_product", + "input_x": [ + 1.9982808828353882, + 0.34709975123405457, + -0.10135623067617416 + ], + "input_y": [ + -0.7542831897735596, + 1.9345619678497314, + -1.2589340209960938 + ], + "expected_output": -0.7081828713417053, + "expected_grad_x": [ + -0.7542831897735596, + 1.9345619678497314, + -1.2589340209960938 + ], + "expected_grad_y": [ + 1.9982808828353882, + 0.34709975123405457, + -0.10135623067617416 + ] + }, + { + "test_name": "matmul_2D_matrix_multiply", + "input_x": [ + [ + -0.38954418897628784, + 0.5330391526222229, + -0.24234455823898315 + ], + [ + 0.6653695106506348, + 0.9382926821708679, + 0.044521868228912354 + ] + ], + "input_y": [ + [ + 1.1535056829452515, + 1.0917677879333496, + 0.04327869415283203, + -1.7126272916793823 + ], + [ + -1.030257225036621, + -0.5207390189170837, + 1.1711158752441406, + -0.45347651839256287 + ], + [ + 0.3185255229473114, + 1.3442730903625488, + -0.07879567891359329, + -0.7328374981880188 + ] + ], + "expected_output": [ + [ + -1.0757018327713013, + -1.0286433696746826, + 0.6264873743057251, + 0.6030224561691284 + ], + [ + -0.1849939525127411, + 0.29767292737960815, + 1.1241376399993896, + -1.5976510047912598 + ] + ], + "expected_grad_x": [ + [ + 0.5759249925613403, + -0.8333569765090942, + 0.8511654734611511 + ], + [ + 0.5759249925613403, + -0.8333569765090942, + 0.8511654734611511 + ] + ], + "expected_grad_y": [ + [ + 0.2758253216743469, + 0.2758253216743469, + 0.2758253216743469, + 0.2758253216743469 + ], + [ + 1.4713318347930908, + 1.4713318347930908, + 1.4713318347930908, + 1.4713318347930908 + ], + [ + -0.1978226900100708, + -0.1978226900100708, + -0.1978226900100708, + -0.1978226900100708 + ] + ] + }, + { + "test_name": "matmul_1D_2D_prepend_remove", + "input_x": [ + 0.11520808190107346, + -1.3933792114257812, + -2.112499237060547 + ], + "input_y": [ + [ + -0.5033561587333679, + -0.3874717056751251, + 1.9671382904052734, + 0.5708574652671814 + ], + [ + 0.9349703192710876, + -2.07222843170166, + -0.5888614654541016, + -0.5368285179138184 + ], + [ + -0.55372554063797, + 0.13748766481876373, + 0.3860569894313812, + -1.294584035873413 + ] + ], + "expected_output": [ + -0.1910141259431839, + 2.5523173809051514, + 0.23159240186214447, + 3.5485808849334717 + ], + "expected_grad_x": [ + 1.6471679210662842, + -2.2629480361938477, + -1.3247649669647217 + ], + "expected_grad_y": [ + [ + 0.11520808190107346, + 0.11520808190107346, + 0.11520808190107346, + 0.11520808190107346 + ], + [ + -1.3933792114257812, + -1.3933792114257812, + -1.3933792114257812, + -1.3933792114257812 + ], + [ + -2.112499237060547, + -2.112499237060547, + -2.112499237060547, + -2.112499237060547 + ] + ] + }, + { + "test_name": "matmul_2D_1D_matrix_vector", + "input_x": [ + [ + -0.9253478646278381, + 0.026843471452593803, + -1.56169593334198 + ], + [ + 1.6090036630630493, + 0.5269482731819153, + -0.4549155831336975 + ] + ], + "input_y": [ + 0.8616125583648682, + 0.8724160194396973, + 1.0766733884811401 + ], + "expected_output": [ + -2.4553091526031494, + 1.3562602996826172 + ], + "expected_grad_x": [ + [ + 0.8616125583648682, + 0.8724160194396973, + 1.0766733884811401 + ], + [ + 0.8616125583648682, + 0.8724160194396973, + 1.0766733884811401 + ] + ], + "expected_grad_y": [ + 0.6836557984352112, + 0.5537917613983154, + -2.0166115760803223 + ] + }, + { + "test_name": "matmul_ND_batched_with_broadcast", + "input_x": [ + [ + [ + [ + -1.411333680152893, + 0.36025282740592957, + -1.2506803274154663 + ], + [ + -0.1725202202796936, + 0.8875670433044434, + 1.4435428380966187 + ] + ] + ], + [ + [ + [ + -0.4563913941383362, + 0.04452125355601311, + -0.5545827150344849 + ], + [ + 1.213465929031372, + -0.5521613359451294, + 1.3268003463745117 + ] + ] + ] + ], + "input_y": [ + [ + [ + -1.2941471338272095, + -1.2331957817077637 + ], + [ + -1.0800817012786865, + 1.9881891012191772 + ], + [ + 0.1034913882613182, + 0.11661393195390701 + ] + ], + [ + [ + -0.02522038109600544, + 0.3788713812828064 + ], + [ + 0.24455690383911133, + -0.8915789723396301 + ], + [ + -1.5224734544754028, + -2.6157381534576416 + ] + ], + [ + [ + -0.5713837146759033, + -0.6671661734580994 + ], + [ + -0.09203547239303589, + 0.9548746347427368 + ], + [ + 0.18482893705368042, + -0.11677189916372299 + ] + ] + ], + "expected_output": [ + [ + [ + [ + 1.307936429977417, + 2.31085467338562 + ], + [ + -0.5859841108322144, + 2.1457395553588867 + ] + ], + [ + [ + 2.0278244018554688, + 2.4155445098876953 + ], + [ + -1.9763438701629639, + -4.63262939453125 + ] + ], + [ + [ + 0.5420950651168823, + 1.4316346645355225 + ], + [ + 0.2836960554122925, + 0.7940497398376465 + ] + ] + ], + [ + [ + [ + 0.48515650629997253, + 0.5866645574569702 + ], + [ + -0.8367117047309875, + -2.439518690109253 + ] + ], + [ + [ + 0.8667358160018921, + 1.2380353212356567 + ], + [ + -2.185657262802124, + -2.518519401550293 + ] + ], + [ + [ + 0.15417414903640747, + 0.41176077723503113 + ], + [ + -0.39730513095855713, + -1.4917612075805664 + ] + ] + ] + ], + "expected_grad_x": [ + [ + [ + [ + -3.4122416973114014, + 1.1239244937896729, + -3.8500492572784424 + ], + [ + -3.4122416973114014, + 1.1239244937896729, + -3.8500492572784424 + ] + ] + ], + [ + [ + [ + -3.4122416973114014, + 1.1239244937896729, + -3.8500492572784424 + ], + [ + -3.4122416973114014, + 1.1239244937896729, + -3.8500492572784424 + ] + ] + ] + ], + "expected_grad_y": [ + [ + [ + -0.8267794251441956, + -0.8267794251441956 + ], + [ + 0.7401798367500305, + 0.7401798367500305 + ], + [ + 0.9650801420211792, + 0.9650801420211792 + ] + ], + [ + [ + -0.8267794251441956, + -0.8267794251441956 + ], + [ + 0.7401798367500305, + 0.7401798367500305 + ], + [ + 0.9650801420211792, + 0.9650801420211792 + ] + ], + [ + [ + -0.8267794251441956, + -0.8267794251441956 + ], + [ + 0.7401798367500305, + 0.7401798367500305 + ], + [ + 0.9650801420211792, + 0.9650801420211792 + ] + ] + ] + } + ] }; From df011693d90d7dc7fa344d73a1855e330bb82db3 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Sun, 8 Mar 2026 23:11:47 +0800 Subject: [PATCH 080/128] feat: auto test Linear and Optimizer --- scripts/generate_tests.py | 76 +++- test/generated.test.js | 196 +++++++---- test/testcases.gen.js | 706 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 914 insertions(+), 64 deletions(-) diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index ae903bc7..6da891f2 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -106,12 +106,86 @@ def generate_matmul_tests(): return tests +def generate_linear_tests(): + tests = [] + # Test standard 2D inputs and batched 3D inputs + cases = [ + (10, 5, (3, 10), "2D_input"), + (4, 2, (2, 3, 4), "3D_batched_input") + ] + + for in_features, out_features, input_shape, desc in cases: + layer = torch.nn.Linear(in_features, out_features) + x = torch.randn(*input_shape, requires_grad=True) + + out = layer(x) + out.sum().backward() + + tests.append({ + "test_name": f"linear_{desc}", + "in_features": in_features, + "out_features": out_features, + "input": x.detach().numpy().tolist(), + "weight": layer.weight.detach().numpy().tolist(), + "bias": layer.bias.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_input": x.grad.numpy().tolist(), + "expected_grad_weight": layer.weight.grad.numpy().tolist(), + "expected_grad_bias": layer.bias.grad.numpy().tolist() + }) + return tests + +def generate_optimizer_tests(): + tests = [] + configs = [ + ("SGD_basic", torch.optim.SGD, {"lr": 0.1}), + ("SGD_momentum", torch.optim.SGD, {"lr": 0.1, "momentum": 0.9}), + ("Adam_basic", torch.optim.Adam, {"lr": 0.1}), + ("Adam_custom_betas", torch.optim.Adam, {"lr": 0.1, "betas": (0.95, 0.999)}) + ] + + for test_name, optim_class, kwargs in configs: + # 1. Initialize a generic parameter tensor + w = torch.randn(3, 3, requires_grad=True) + x = torch.randn(3, 3) # Dummy input to calculate a loss + + # Save exact starting state + initial_w = w.detach().clone() + + # 2. Setup Optimizer + optimizer = optim_class([w], **kwargs) + optimizer.zero_grad() + + # 3. Compute loss and gradients + loss = (w * x).sum() + loss.backward() + + # Save exact gradient computed by PyTorch + expected_grad = w.grad.detach().clone() + + # 4. Step the optimizer + optimizer.step() + + tests.append({ + "test_name": test_name, + "optimizer": test_name.split("_")[0], # "SGD" or "Adam" + "kwargs": kwargs, + "initial_weight": initial_w.numpy().tolist(), + "input_x": x.numpy().tolist(), + "expected_grad": expected_grad.numpy().tolist(), + "expected_updated_weight": w.detach().numpy().tolist() + }) + + return tests + if __name__ == "__main__": suite = { "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, "binary": {op: generate_binary_tests(op) for op in BINARY_OPS}, "broadcasting": generate_broadcasting_tests(), - "matmul": generate_matmul_tests() + "matmul": generate_matmul_tests(), + "linear": generate_linear_tests(), + "optimizers": generate_optimizer_tests(), } print("export const testData = ", end="") diff --git a/test/generated.test.js b/test/generated.test.js index 491fb03b..86d73ae3 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -1,86 +1,156 @@ +import * as torch from 'torch'; import { Tensor } from 'torch'; import { assert } from 'chai'; import { testData } from './testcases.gen.js'; function assertDeepCloseTo(actual, expected, delta = 1e-3, first_call = true) { - if (Array.isArray(expected)) { - assert.lengthOf(actual, expected.length, 'Array lengths do not match'); - for (let i = 0; i < expected.length; i++) { - assertDeepCloseTo(actual[i], expected[i], delta, false); - } + if (Array.isArray(expected)) { + assert.lengthOf(actual, expected.length, 'Array lengths do not match'); + for (let i = 0; i < expected.length; i++) { + assertDeepCloseTo(actual[i], expected[i], delta, false); + } + } else { + if (Number.isNaN(expected)) { + assert.isTrue(Number.isNaN(actual), `Expected NaN but got ${actual}`); } else { - if (Number.isNaN(expected)) { - assert.isTrue(Number.isNaN(actual), `Expected NaN but got ${actual}`); - } else { - assert.closeTo(actual, expected, delta); - } + assert.closeTo(actual, expected, delta); } + } } describe('Automated Tests', () => { - describe('Unary Operations', () => { - for (const [opName, tests] of Object.entries(testData.unary)) { - describe(`.${opName}()`, () => { - tests.forEach((test, idx) => { - it(`case ${idx + 1}`, () => { - const x = new Tensor(test.input, { requires_grad: true }); - const y = (x)[opName](); - assertDeepCloseTo(y.toArray(), test.expected_output); - y.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad); - }); - }); - }); - } + describe('Unary Operations', () => { + for (const [opName, tests] of Object.entries(testData.unary)) { + describe(`.${opName}()`, () => { + tests.forEach((test, idx) => { + it(`case ${idx + 1}`, () => { + const x = new Tensor(test.input, { requires_grad: true }); + const y = x[opName](); + assertDeepCloseTo(y.toArray(), test.expected_output); + y.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + }); + }); + }); + } + }); + + describe('Binary Operations', () => { + for (const [opName, tests] of Object.entries(testData.binary)) { + describe(`.${opName}()`, () => { + tests.forEach((test, idx) => { + it(`case ${idx + 1}`, () => { + const x = new Tensor(test.input_x, { requires_grad: true }); + const y = new Tensor(test.input_y, { requires_grad: true }); + const out = x[opName](y); + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + }); + }); + }); + } + }); + + describe('Broadcasting Operations', () => { + testData.broadcasting?.forEach(test => { + it(test.test_name, () => { + const x = new Tensor(test.input_x, { requires_grad: true }); + const y = new Tensor(test.input_y, { requires_grad: true }); + + const out = x[test.op_name](y); + + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + }); }); + }); - describe('Binary Operations', () => { - for (const [opName, tests] of Object.entries(testData.binary)) { - describe(`.${opName}()`, () => { - tests.forEach((test, idx) => { - it(`case ${idx + 1}`, () => { - const x = new Tensor(test.input_x, { requires_grad: true }); - const y = new Tensor(test.input_y, { requires_grad: true }); - const out = (x)[opName](y); - assertDeepCloseTo(out.toArray(), test.expected_output); - out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); - assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); - }); - }); - }); - } + describe('Matmul Operations', () => { + testData.matmul?.forEach(test => { + it(test.test_name, () => { + const x = new Tensor(test.input_x, { requires_grad: true }); + const y = new Tensor(test.input_y, { requires_grad: true }); + + const out = x.matmul(y); + + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + }); }); + }); + + describe('Neural Network Modules', () => { + describe('nn.Linear', () => { + testData.linear?.forEach(test => { + it(test.test_name, () => { + const layer = new torch.nn.Linear(test.in_features, test.out_features); + + // Overwrite the layer's internal parameters with Python's starting state + layer.weight = new Tensor(test.weight, { requires_grad: true }); + layer.bias = new Tensor(test.bias, { requires_grad: true }); + + const x = new Tensor(test.input, { requires_grad: true }); - describe('Broadcasting Operations', () => { - testData.broadcasting?.forEach((test) => { - it(test.test_name, () => { - const x = new Tensor(test.input_x, { requires_grad: true }); - const y = new Tensor(test.input_y, { requires_grad: true }); + const out = layer.forward(x); + assertDeepCloseTo(out.toArray(), test.expected_output); - const out = x[test.op_name](y); + out.sum().backward(); - assertDeepCloseTo(out.toArray(), test.expected_output); - out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); - assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); - }); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_input); + assertDeepCloseTo(layer.weight.grad.toArray(), test.expected_grad_weight); + assertDeepCloseTo(layer.bias.grad.toArray(), test.expected_grad_bias); }); + }); }); + }); - describe('Matmul Operations', () => { - testData.matmul?.forEach((test) => { - it(test.test_name, () => { - const x = new Tensor(test.input_x, { requires_grad: true }); - const y = new Tensor(test.input_y, { requires_grad: true }); + describe('Optimizers', () => { + testData.optimizers?.forEach(test => { + it(test.test_name, () => { + const w = new torch.nn.Parameter(test.initial_weight, { requires_grad: true }); + const x = new Tensor(test.input_x); - const out = x.matmul(y); + const OptimizerClass = torch.optim[test.optimizer]; + let optimizer; - assertDeepCloseTo(out.toArray(), test.expected_output); - out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); - assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); - }); - }); + if (test.optimizer === 'SGD') { + optimizer = new OptimizerClass( + [w], + test.kwargs.lr, + test.kwargs.momentum, + test.kwargs.dampening, + test.kwargs.weight_decay, + test.kwargs.nesterov, + test.kwargs.maximize + ); + } else if (test.optimizer === 'Adam') { + optimizer = new OptimizerClass( + [w], + test.kwargs.lr, + test.kwargs.betas, + test.kwargs.eps, + test.kwargs.weight_decay, + test.kwargs.amsgrad, + test.kwargs.maximize + ); + } + + optimizer.zero_grad(); + const loss = w.mul(x).sum(); + loss.backward(); + + assertDeepCloseTo(w.grad.toArray(), test.expected_grad); + + optimizer.step(); + + assertDeepCloseTo(w.toArray(), test.expected_updated_weight); + }); }); + }); }); diff --git a/test/testcases.gen.js b/test/testcases.gen.js index 788d8c8a..b3789e29 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -5844,5 +5844,711 @@ export const testData = { ] ] } + ], + "linear": [ + { + "test_name": "linear_2D_input", + "in_features": 10, + "out_features": 5, + "input": [ + [ + -1.4766337871551514, + 0.982934296131134, + 0.034095875918865204, + -0.461677223443985, + 0.3484693765640259, + 0.3648642897605896, + -0.029142292216420174, + 1.1481481790542603, + -1.35635244846344, + -1.0603324174880981 + ], + [ + 1.0654057264328003, + 0.8679789900779724, + -0.5582399368286133, + -1.7682260274887085, + -1.7561272382736206, + 1.4259073734283447, + 0.5127183794975281, + -0.4026731848716736, + 1.9770677089691162, + -0.030815819278359413 + ], + [ + -1.737373948097229, + 1.2176311016082764, + -0.5283262729644775, + -0.46433013677597046, + -0.15669254958629608, + -1.5964131355285645, + -1.5322294235229492, + -0.11408505588769913, + -0.9761450290679932, + 0.48647579550743103 + ] + ], + "weight": [ + [ + 0.3002844452857971, + 0.017805445939302444, + -0.027198705822229385, + -0.21463561058044434, + -0.15679782629013062, + -0.24376848340034485, + 0.25319355726242065, + -0.0515228807926178, + -0.2793583571910858, + 0.03392322361469269 + ], + [ + 0.022948073223233223, + -0.03906950727105141, + 0.11319813132286072, + 0.17006072402000427, + -0.29738378524780273, + -0.24225947260856628, + -0.015191554091870785, + -0.2931866943836212, + -0.2872485816478729, + 0.27920082211494446 + ], + [ + -0.02405211329460144, + -0.15633995831012726, + -0.10847145318984985, + -0.24688613414764404, + 0.24677330255508423, + -0.06857045739889145, + -0.17779526114463806, + -0.23983119428157806, + 0.18483199179172516, + -0.04371260479092598 + ], + [ + -0.0332220159471035, + -0.08241946250200272, + -0.1526503711938858, + 0.05625385046005249, + 0.2432962954044342, + -0.183279350399971, + 0.015151331201195717, + -0.24049542844295502, + -0.14827828109264374, + 0.27757522463798523 + ], + [ + 0.003315664827823639, + 0.3046282231807709, + -0.0554044172167778, + -0.17235811054706573, + -0.18894238770008087, + 0.280277281999588, + -0.24317501485347748, + 0.16595454514026642, + 0.07860860973596573, + 0.09332110732793808 + ] + ], + "bias": [ + 0.17842835187911987, + -0.0827324241399765, + 0.1956702172756195, + -0.2519457936286926, + -0.1112619936466217 + ], + "expected_output": [ + [ + -0.016492903232574463, + -0.664310097694397, + -0.22575607895851135, + -0.6669389009475708, + 0.2894335091114044 + ], + [ + 0.4334893524646759, + -0.7455325126647949, + 0.3724954128265381, + -1.2588322162628174, + 1.1848678588867188 + ], + [ + 0.11328274011611938, + 0.5973459482192993, + 0.3879339098930359, + 0.2984088063240051, + 0.2677045166492462 + ] + ], + "expected_grad_input": [ + [ + 0.2692740559577942, + 0.044604748487472534, + -0.23052680492401123, + -0.40756529569625854, + -0.1530544012784958, + -0.45760050415992737, + -0.16781693696975708, + -0.6590816378593445, + -0.4514445960521698, + 0.6403077244758606 + ], + [ + 0.2692740559577942, + 0.044604748487472534, + -0.23052680492401123, + -0.40756529569625854, + -0.1530544012784958, + -0.45760050415992737, + -0.16781693696975708, + -0.6590816378593445, + -0.4514445960521698, + 0.6403077244758606 + ], + [ + 0.2692740559577942, + 0.044604748487472534, + -0.23052680492401123, + -0.40756529569625854, + -0.1530544012784958, + -0.45760050415992737, + -0.16781693696975708, + -0.6590816378593445, + -0.4514445960521698, + 0.6403077244758606 + ] + ], + "expected_grad_weight": [ + [ + -2.14860200881958, + 3.068544387817383, + -1.052470326423645, + -2.6942334175109863, + -1.5643503665924072, + 0.19435858726501465, + -1.0486533641815186, + 0.6313899159431458, + -0.3554297685623169, + -0.6046724319458008 + ], + [ + -2.14860200881958, + 3.068544387817383, + -1.052470326423645, + -2.6942334175109863, + -1.5643503665924072, + 0.19435858726501465, + -1.0486533641815186, + 0.6313899159431458, + -0.3554297685623169, + -0.6046724319458008 + ], + [ + -2.14860200881958, + 3.068544387817383, + -1.052470326423645, + -2.6942334175109863, + -1.5643503665924072, + 0.19435858726501465, + -1.0486533641815186, + 0.6313899159431458, + -0.3554297685623169, + -0.6046724319458008 + ], + [ + -2.14860200881958, + 3.068544387817383, + -1.052470326423645, + -2.6942334175109863, + -1.5643503665924072, + 0.19435858726501465, + -1.0486533641815186, + 0.6313899159431458, + -0.3554297685623169, + -0.6046724319458008 + ], + [ + -2.14860200881958, + 3.068544387817383, + -1.052470326423645, + -2.6942334175109863, + -1.5643503665924072, + 0.19435858726501465, + -1.0486533641815186, + 0.6313899159431458, + -0.3554297685623169, + -0.6046724319458008 + ] + ], + "expected_grad_bias": [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ] + }, + { + "test_name": "linear_3D_batched_input", + "in_features": 4, + "out_features": 2, + "input": [ + [ + [ + -0.9297109842300415, + -0.8541247248649597, + 0.15929833054542542, + -0.41023650765419006 + ], + [ + -0.7588294148445129, + 1.6981608867645264, + 0.7436892986297607, + -0.03276701644062996 + ], + [ + -1.0194525718688965, + 0.3848164975643158, + 0.29434895515441895, + 0.6351331472396851 + ] + ], + [ + [ + 0.20356419682502747, + -0.18102435767650604, + -0.9300417900085449, + 0.4725607931613922 + ], + [ + 0.6600029468536377, + -0.16193436086177826, + 0.886084258556366, + 1.8162529468536377 + ], + [ + 0.20681823790073395, + 0.11982676386833191, + 0.9609657526016235, + -1.2074177265167236 + ] + ] + ], + "weight": [ + [ + 0.09339135885238647, + -0.35572314262390137, + 0.1539331078529358, + 0.08821696043014526 + ], + [ + 0.011232852935791016, + -0.34186333417892456, + -0.3030986189842224, + 0.3695688247680664 + ] + ], + "bias": [ + 0.24350953102111816, + 0.26361989974975586 + ], + "expected_output": [ + [ + [ + 0.4488459527492523, + 0.34527677297592163 + ], + [ + -0.31984591484069824, + -0.5629637837409973 + ], + [ + 0.11275289952754974, + 0.2661225497722626 + ] + ], + [ + [ + 0.22543887794017792, + 0.7843302488327026 + ], + [ + 0.659373939037323, + 0.7290526032447815 + ], + [ + 0.26160913705825806, + -0.5125126838684082 + ] + ] + ], + "expected_grad_input": [ + [ + [ + 0.10462421178817749, + -0.6975864768028259, + -0.14916551113128662, + 0.45778578519821167 + ], + [ + 0.10462421178817749, + -0.6975864768028259, + -0.14916551113128662, + 0.45778578519821167 + ], + [ + 0.10462421178817749, + -0.6975864768028259, + -0.14916551113128662, + 0.45778578519821167 + ] + ], + [ + [ + 0.10462421178817749, + -0.6975864768028259, + -0.14916551113128662, + 0.45778578519821167 + ], + [ + 0.10462421178817749, + -0.6975864768028259, + -0.14916551113128662, + 0.45778578519821167 + ], + [ + 0.10462421178817749, + -0.6975864768028259, + -0.14916551113128662, + 0.45778578519821167 + ] + ] + ], + "expected_grad_weight": [ + [ + -1.6376075744628906, + 1.005720853805542, + 2.114344835281372, + 1.2735257148742676 + ], + [ + -1.6376075744628906, + 1.005720853805542, + 2.114344835281372, + 1.2735257148742676 + ] + ], + "expected_grad_bias": [ + 6.0, + 6.0 + ] + } + ], + "optimizers": [ + { + "test_name": "SGD_basic", + "optimizer": "SGD", + "kwargs": { + "lr": 0.1 + }, + "initial_weight": [ + [ + -0.5548203587532043, + 0.14430466294288635, + -0.8963656425476074 + ], + [ + -1.85586416721344, + 1.925358533859253, + -0.1502695381641388 + ], + [ + -0.4557262361049652, + 0.38499918580055237, + 0.8224982619285583 + ] + ], + "input_x": [ + [ + 1.127738356590271, + -0.21481071412563324, + -0.2161199003458023 + ], + [ + -1.7219769954681396, + -1.4746582508087158, + -1.0435383319854736 + ], + [ + -1.0349572896957397, + 0.3165971040725708, + -0.7668118476867676 + ] + ], + "expected_grad": [ + [ + 1.127738356590271, + -0.21481071412563324, + -0.2161199003458023 + ], + [ + -1.7219769954681396, + -1.4746582508087158, + -1.0435383319854736 + ], + [ + -1.0349572896957397, + 0.3165971040725708, + -0.7668118476867676 + ] + ], + "expected_updated_weight": [ + [ + -0.6675941944122314, + 0.16578572988510132, + -0.8747536540031433 + ], + [ + -1.683666467666626, + 2.072824478149414, + -0.04591570422053337 + ], + [ + -0.3522305190563202, + 0.35333946347236633, + 0.8991794586181641 + ] + ] + }, + { + "test_name": "SGD_momentum", + "optimizer": "SGD", + "kwargs": { + "lr": 0.1, + "momentum": 0.9 + }, + "initial_weight": [ + [ + 1.5292918682098389, + -0.6345059275627136, + -0.375550776720047 + ], + [ + -0.7360644340515137, + 2.3721323013305664, + -1.2406166791915894 + ], + [ + 0.8873314261436462, + -0.26175713539123535, + 1.0236345529556274 + ] + ], + "input_x": [ + [ + -0.7798894047737122, + -0.05700850114226341, + 0.49562183022499084 + ], + [ + -1.8779617547988892, + 0.033319782465696335, + -0.5396625995635986 + ], + [ + -0.3761339783668518, + 1.3337057828903198, + -1.753574252128601 + ] + ], + "expected_grad": [ + [ + -0.7798894047737122, + -0.05700850114226341, + 0.49562183022499084 + ], + [ + -1.8779617547988892, + 0.033319782465696335, + -0.5396625995635986 + ], + [ + -0.3761339783668518, + 1.3337057828903198, + -1.753574252128601 + ] + ], + "expected_updated_weight": [ + [ + 1.6072808504104614, + -0.6288051009178162, + -0.4251129627227783 + ], + [ + -0.5482682585716248, + 2.368800401687622, + -1.1866503953933716 + ], + [ + 0.9249448180198669, + -0.39512771368026733, + 1.1989920139312744 + ] + ] + }, + { + "test_name": "Adam_basic", + "optimizer": "Adam", + "kwargs": { + "lr": 0.1 + }, + "initial_weight": [ + [ + 1.6819236278533936, + -0.15222187340259552, + 1.3899450302124023 + ], + [ + -0.8099237084388733, + -0.39533430337905884, + 0.494835764169693 + ], + [ + 1.198076844215393, + -2.5727944374084473, + -0.08748100697994232 + ] + ], + "input_x": [ + [ + 0.6722773313522339, + 0.21969778835773468, + 0.8142342567443848 + ], + [ + 0.510215699672699, + -1.0645642280578613, + -1.035934567451477 + ], + [ + 1.0930753946304321, + -0.06202443689107895, + 0.1334656924009323 + ] + ], + "expected_grad": [ + [ + 0.6722773313522339, + 0.21969778835773468, + 0.8142342567443848 + ], + [ + 0.510215699672699, + -1.0645642280578613, + -1.035934567451477 + ], + [ + 1.0930753946304321, + -0.06202443689107895, + 0.1334656924009323 + ] + ], + "expected_updated_weight": [ + [ + 1.5819236040115356, + -0.25222185254096985, + 1.2899450063705444 + ], + [ + -0.9099236726760864, + -0.2953343093395233, + 0.5948357582092285 + ], + [ + 1.0980768203735352, + -2.472794532775879, + -0.18748098611831665 + ] + ] + }, + { + "test_name": "Adam_custom_betas", + "optimizer": "Adam", + "kwargs": { + "lr": 0.1, + "betas": [ + 0.95, + 0.999 + ] + }, + "initial_weight": [ + [ + -1.495338797569275, + -0.13971441984176636, + 0.5186095833778381 + ], + [ + -0.27415627241134644, + -1.863209843635559, + 0.7076565027236938 + ], + [ + 0.8178618550300598, + 1.4021011590957642, + 0.9863149523735046 + ] + ], + "input_x": [ + [ + 1.3463093042373657, + -1.6255258321762085, + -0.4336149990558624 + ], + [ + 0.3167438805103302, + 0.23875612020492554, + -0.08424656093120575 + ], + [ + -2.0689682960510254, + -0.5692359209060669, + -0.07368183881044388 + ] + ], + "expected_grad": [ + [ + 1.3463093042373657, + -1.6255258321762085, + -0.4336149990558624 + ], + [ + 0.3167438805103302, + 0.23875612020492554, + -0.08424656093120575 + ], + [ + -2.0689682960510254, + -0.5692359209060669, + -0.07368183881044388 + ] + ], + "expected_updated_weight": [ + [ + -1.5953388214111328, + -0.039714425802230835, + 0.6186095476150513 + ], + [ + -0.37415626645088196, + -1.963209867477417, + 0.807656466960907 + ], + [ + 0.9178618788719177, + 1.502101182937622, + 1.0863149166107178 + ] + ] + } ] }; From 34bc280d530a6c7cf10938886902a29feea01a70 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 9 Mar 2026 00:18:53 +0800 Subject: [PATCH 081/128] feat: reduction mixin and tests --- scripts/generate_tests.py | 67 + src/functions/base.ts | 6 +- src/functions/functional.ts | 8 +- src/functions/mixin.ts | 111 +- src/functions/ops.ts | 166 +- src/functions/util.ts | 36 + src/tensor.ts | 20 +- test/generated.test.js | 29 + test/testcases.gen.js | 7165 ++++++++++++++++++++++++++++++++--- 9 files changed, 7098 insertions(+), 510 deletions(-) create mode 100644 src/functions/util.ts diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index 6da891f2..ff00d2d3 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -106,6 +106,43 @@ def generate_matmul_tests(): return tests +def generate_reduction_tests(): + tests = [] + ops = ['sum', 'mean', 'max', 'min'] + dims = [None, 0, 1, -1] + keepdims = [False, True] + + for op in ops: + for dim in dims: + for keepdim in keepdims: + if dim is None and keepdim: + continue + + x = torch.randn(3, 4, 5, requires_grad=True) + torch_op = getattr(torch, op) + + try: + if dim is None: + y = torch_op(x) + else: + out = torch_op(x, dim=dim, keepdim=keepdim) + y = out.values if op in ['max', 'min'] else out + + y.sum().backward() + + tests.append({ + "test_name": f"{op}_dim_{dim}_keepdim_{keepdim}", + "op_name": op, + "dim": dim, + "keepdim": keepdim, + "input": x.detach().numpy().tolist(), + "expected_output": y.detach().numpy().tolist(), + "expected_grad": x.grad.numpy().tolist() + }) + except Exception as e: + pass + return tests + def generate_linear_tests(): tests = [] # Test standard 2D inputs and batched 3D inputs @@ -178,14 +215,44 @@ def generate_optimizer_tests(): return tests +def generate_expand_tests(): + tests = [] + + # Tuples of (initial_shape, expand_shape, description) + cases = [ + ((1,), (3,), "1D_expand"), + ((3,), (2, 3), "prepend_2D"), + ((1, 3), (4, 3), "expand_dim_0"), + ((2, 1, 4), (2, 5, 4), "expand_middle_dim"), + ((1, 3, 1), (2, -1, 4), "preserve_with_negative_one") + ] + + for initial_shape, expand_shape, desc in cases: + x = torch.randn(initial_shape, requires_grad=True) + + out = x.expand(*expand_shape) + out.sum().backward() + + tests.append({ + "test_name": f"expand_{desc}", + "input": x.detach().numpy().tolist(), + "expand_shape": list(expand_shape), + "expected_output": out.detach().numpy().tolist(), + "expected_grad": x.grad.numpy().tolist() + }) + + return tests + if __name__ == "__main__": suite = { "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, "binary": {op: generate_binary_tests(op) for op in BINARY_OPS}, "broadcasting": generate_broadcasting_tests(), "matmul": generate_matmul_tests(), + "reductions": generate_reduction_tests(), "linear": generate_linear_tests(), "optimizers": generate_optimizer_tests(), + "expand": generate_expand_tests(), } print("export const testData = ", end="") diff --git a/src/functions/base.ts b/src/functions/base.ts index 4fd6151d..bb548c7d 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -3,7 +3,7 @@ import { zeros_like } from '../creation'; import { Tensor } from '../tensor'; import { eventBus, getNextId, events } from '../util'; -function resultRequiresGrad(...args: (Tensor | number | number[])[]): boolean { +function resultRequiresGrad(...args: (Tensor | number | number[] | boolean)[]): boolean { for (const arg of args) { if (arg instanceof Tensor && arg.requires_grad) { return true; @@ -18,10 +18,10 @@ abstract class TorchFunction { public saved_tensors: Tensor[] = []; public _retained_tensors: Tensor[] = []; - protected abstract _forward(...args: (Tensor | number | number[])[]): Tensor; + protected abstract _forward(...args: (Tensor | number | number[] | boolean)[]): Tensor; protected abstract _backward(dz: Tensor): void; - forward(...args: (Tensor | number | number[])[]): Tensor { + forward(...args: (Tensor | number | number[] | boolean)[]): Tensor { const requires_grad = resultRequiresGrad(...args); eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_FORWARD, { detail: { diff --git a/src/functions/functional.ts b/src/functions/functional.ts index 962f9b4d..c48974b6 100644 --- a/src/functions/functional.ts +++ b/src/functions/functional.ts @@ -61,7 +61,9 @@ export const sign = generate_unary_function('sign'); export const neg = generate_unary_function('neg'); export const reciprocal = generate_unary_function('reciprocal'); export const reshape = generate_function('reshape'); +export const squeeze = generate_function('squeeze'); export const unsqueeze = generate_function('unsqueeze'); +export const expand = generate_function('expand'); // trigonometric @@ -71,8 +73,10 @@ export const tan = generate_unary_function('tan'); // reduction -export const sum = generate_unary_function('sum'); -export const mean = generate_unary_function('mean'); +export const sum = generate_function('sum'); +export const mean = generate_function('mean'); +export const min = generate_function('min'); +export const max = generate_function('max'); // linalg diff --git a/src/functions/mixin.ts b/src/functions/mixin.ts index 02a2e790..047bcb6e 100644 --- a/src/functions/mixin.ts +++ b/src/functions/mixin.ts @@ -8,6 +8,7 @@ import { } from '../broadcasting'; import { TorchFunction, BinaryFunction, UnaryFunction, nullOp } from './base'; import { registerOperation } from './registry'; +import { _get_reduction_shape, _get_strides, _ravel_index, _unravel_index } from './util'; export function BinaryFunctionMixin( operation: (a: number[], b: number[], a_index: number, b_index: number) => number, @@ -74,14 +75,14 @@ export function UnaryFunctionMixin( return res; }; const forward_tensor = (a: Tensor, operation: TorchFunction | null = null): Tensor => { - const output_size = a.dataLength(); + const output_size = a.dataLength(); - return new Tensor( - kernel(a.data, output_size) as number[], - { requires_grad: a.requires_grad }, - { operation: operation, shape: a.shape } - ); - } + return new Tensor( + kernel(a.data, output_size) as number[], + { requires_grad: a.requires_grad }, + { operation: operation, shape: a.shape } + ); + } const result = class extends UnaryFunction { protected _forward(a: Tensor): Tensor { @@ -104,3 +105,99 @@ export function UnaryFunctionMixin( } return result; } + +export function ReductionFunctionMixin( + init_val: number, + reduce_op: (acc: number, val: number) => number, + backward_operations: (a: Tensor, restored_dz: Tensor, dim: number | number[], keepdim: boolean) => Tensor, // Simplified signature! + opName: string | null = null, + finalize_op?: (acc: number, count: number) => number +): new () => TorchFunction { + + const result = class extends TorchFunction { + protected dim?: number | number[]; + protected keepdim?: boolean; + + protected _forward(a: Tensor, dim?: number | number[], keepdim: boolean = false): Tensor { + this.dim = dim; + this.keepdim = keepdim; + + if (a.requires_grad) { + this.saved_tensors = [a]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + + const out_shape = _get_reduction_shape(a.shape, dim, keepdim); + const out_size = out_shape.reduce((acc, val) => acc * val, 1); + + const res_data = new Array(out_size).fill(init_val); + const counts = new Array(out_size).fill(0); // Tracked specifically for mean() + + const in_strides = _get_strides(a.shape); + const out_strides = _get_strides(out_shape); + + const dims = dim === undefined ? [] : Array.isArray(dim) ? dim : [dim]; + const normalized_dims = dims.map((d) => (d < 0 ? d + a.shape.length : d)); + const is_full_reduce = dim === undefined; + + // Accumulate + for (let i = 0; i < a.data.length; i++) { + const in_coords = _unravel_index(i, in_strides); + let out_coords: number[]; + + if (is_full_reduce) { + out_coords = keepdim ? in_coords.map(() => 0) : []; + } else { + out_coords = []; + for (let j = 0; j < a.shape.length; j++) { + if (normalized_dims.includes(j)) { + if (keepdim) out_coords.push(0); // Collapse dimension to index 0 + } else { + out_coords.push(in_coords[j]); + } + } + } + + const out_idx = _ravel_index(out_coords, out_strides); + res_data[out_idx] = reduce_op(res_data[out_idx], a.data[i]); + counts[out_idx]++; + } + + // Finalize (e.g., divide by count for mean) + if (finalize_op) { + for (let i = 0; i < out_size; i++) { + res_data[i] = finalize_op(res_data[i], counts[i]); + } + } + + return new Tensor( + res_data, + { requires_grad: a.requires_grad }, + { operation: a.requires_grad ? this : null, shape: out_shape } + ); + } + + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + let restored_dz = dz; + + const target_shape = _get_reduction_shape(a.shape, this.dim, true); + + if (dz.shape.length !== target_shape.length) { + restored_dz = dz.reshape(target_shape); + } + + let expanded_dz = restored_dz.expand(a.shape); + const grad_a = backward_operations(a, expanded_dz, this.dim, this.keepdim); + + aFn.backward(grad_a); + } + }; + + if (opName) { + registerOperation(opName, result); + } + return result; +} diff --git a/src/functions/ops.ts b/src/functions/ops.ts index be98d938..351863e2 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -7,17 +7,22 @@ import { _pad_shape, _unbroadcast } from '../broadcasting'; -import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, AccumulateGrad } from './base'; +import { TorchFunction, BinaryFunction, nullOp } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; -import { zeros_like } from '../creation'; -import { UnaryFunctionMixin, BinaryFunctionMixin } from './mixin'; +import { ones } from '../creation'; +import { UnaryFunctionMixin, BinaryFunctionMixin, ReductionFunctionMixin } from './mixin'; +import { _get_reduction_shape } from './util'; function unbroadcast(result: Tensor, original_shape: number[]): Tensor { const unbroadcasted_result = _unbroadcast(result.shape, original_shape, result.data); return new Tensor(unbroadcasted_result, { requires_grad: result.requires_grad }, { shape: original_shape }); } +function broadcast(tensor: Tensor, result_shape: number[]): Tensor { + return tensor.mul(ones(result_shape)); +} + // debug operations const __Left_index__ = BinaryFunctionMixin( @@ -219,10 +224,6 @@ export class Reshape extends TorchFunction { } if (a.grad_fn) { this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); } else { this.next_functions.push(nullOp); } @@ -250,10 +251,6 @@ export class Squeeze extends TorchFunction { } if (a.grad_fn) { this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); } else { this.next_functions.push(nullOp); } @@ -264,7 +261,7 @@ export class Squeeze extends TorchFunction { if (dim < 0) { dim += a.shape.length; } - + // PyTorch only squeezes the specified dimension if its size is exactly 1 if (shape[dim] === 1) { shape.splice(dim, 1); @@ -299,10 +296,6 @@ export class Unsqueeze extends TorchFunction { } if (a.grad_fn) { this.next_functions.push(a.grad_fn); - } else if (a.requires_grad) { - const acc = new AccumulateGrad(); - acc.variable = a; - this.next_functions.push(acc); } else { this.next_functions.push(nullOp); } @@ -330,6 +323,46 @@ export class Unsqueeze extends TorchFunction { } registerOperation('unsqueeze', Unsqueeze); +export class Expand extends TorchFunction { + protected _forward(a: Tensor, expanded_shape: number[]): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + if (a.grad_fn) { + this.next_functions.push(a.grad_fn); + } else { + this.next_functions.push(nullOp); + } + + const offset = expanded_shape.length - a.shape.length; + const target_shape = expanded_shape.map((dim, i) => { + if (dim === -1) { + const orig_i = i - offset; + return orig_i >= 0 ? a.shape[orig_i] : 1; + } + return dim; + }); + + // Steal data from just broadcasting + const outData = broadcast(a, target_shape).data; + + return new Tensor( + outData, + { requires_grad: a.requires_grad }, + { operation: a.requires_grad ? this : null, shape: target_shape } + ); + } + + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; + + // Route the collapsed gradient upstream + aFn.backward(unbroadcast(dz, a.shape)); + } +} +registerOperation('expand', Expand) + // trigonometric const Sin = UnaryFunctionMixin( @@ -358,57 +391,52 @@ const Tan = UnaryFunctionMixin( // reduction -function _sum_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - return new Tensor( - a.toFlatArray().reduce((acc, val) => acc + val, 0), - { requires_grad: a.requires_grad }, - { operation: operation } - ); -} +export const Sum = ReductionFunctionMixin( + 0, + (acc, val) => acc + val, + (a, expanded_dz) => expanded_dz, + 'sum' +); -export class Sum extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _sum_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; +export const Mean = ReductionFunctionMixin( + 0, + (acc, val) => acc + val, + (a, expanded_dz, dim) => { + const target_shape = _get_reduction_shape(a.shape, dim, false); + const out_size = target_shape.length > 0 ? target_shape.reduce((acc, v) => acc * v, 1) : 1; + const N = a.dataLength() / out_size; - // backward_operations: - aFn.backward(zeros_like(a).add(dz.item())); - } -} -registerOperation('sum', Sum); + return expanded_dz.mul(new Tensor([1 / N])); + }, + 'mean', + (acc, count) => acc / count +); -function _mean_tensor(a: Tensor, operation: TorchFunction | null = null): Tensor { - return new Tensor( - a.toFlatArray().reduce((acc, val) => acc + val, 0) / a.dataLength(), - { requires_grad: a.requires_grad }, - { operation: operation } - ); -} +export const Max = ReductionFunctionMixin( + -Infinity, + (acc, val) => Math.max(acc, val), + (a, expanded_dz, dim) => { + const max_tensor = a.max(dim, true); + const max_expanded = max_tensor.expand(a.shape); + const mask = a.eq(max_expanded).detach(); -export class Mean extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _mean_tensor(a, a.requires_grad ? this : null); - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; + return expanded_dz.mul(mask); + }, + 'max' +); - // backward_operations: - aFn.backward(zeros_like(a).add(dz.item() / a.dataLength())); - } -} -registerOperation('mean', Mean); +export const Min = ReductionFunctionMixin( + Infinity, + (acc, val) => Math.min(acc, val), + (a, expanded_dz, dim) => { + const min_tensor = a.min(dim, true); + const min_expanded = min_tensor.expand(a.shape); + const mask = a.eq(min_expanded).detach(); + + return expanded_dz.mul(mask); + }, + 'min' +); // linalg @@ -564,7 +592,7 @@ export class Matmul extends BinaryFunction { this.shape = result[1]; return result[0]; } -protected _backward(dz: Tensor): void { + protected _backward(dz: Tensor): void { const [a, b] = this.saved_tensors; const [aFn, bFn] = this.next_functions; @@ -579,13 +607,13 @@ protected _backward(dz: Tensor): void { if (a.shape.length === 1) { const dz1 = dz.unsqueeze(-2); const a1 = a.unsqueeze(-2); - + let da = dz1.matmul(b.transpose(-2, -1)); let db = a1.transpose(-2, -1).matmul(dz1); - + da = da.squeeze(-2); db = unbroadcast(db, b.shape); - + aFn.backward(da); bFn.backward(db); return; @@ -595,13 +623,13 @@ protected _backward(dz: Tensor): void { if (b.shape.length === 1) { const dz1 = dz.unsqueeze(-1); const b1 = b.unsqueeze(-1); - + let da = dz1.matmul(b1.transpose(-2, -1)); let db = a.transpose(-2, -1).matmul(dz1); - + da = unbroadcast(da, a.shape); db = db.squeeze(-1); - + aFn.backward(da); bFn.backward(db); return; diff --git a/src/functions/util.ts b/src/functions/util.ts new file mode 100644 index 00000000..2675ec5d --- /dev/null +++ b/src/functions/util.ts @@ -0,0 +1,36 @@ +export function _get_strides(shape: number[]): number[] { + const strides = new Array(shape.length).fill(1); + for (let i = shape.length - 2; i >= 0; i--) { + strides[i] = strides[i + 1] * shape[i + 1]; + } + return strides; +} + +export function _unravel_index(index: number, strides: number[]): number[] { + return strides.map((stride) => { + const coord = Math.floor(index / stride); + index %= stride; + return coord; + }); +} + +export function _ravel_index(coords: number[], strides: number[]): number { + return coords.reduce((acc, coord, i) => acc + coord * strides[i], 0); +} + +export function _get_reduction_shape( + shape: number[], + dim?: number | number[], + keepdim: boolean = false +): number[] { + if (dim === undefined) return keepdim ? shape.map(() => 1) : []; + + const dims = Array.isArray(dim) ? dim : [dim]; + const normalized_dims = dims.map((d) => (d < 0 ? d + shape.length : d)); + + if (keepdim) { + return shape.map((s, i) => (normalized_dims.includes(i) ? 1 : s)); + } else { + return shape.filter((_, i) => !normalized_dims.includes(i)); + } +} \ No newline at end of file diff --git a/src/tensor.ts b/src/tensor.ts index e96198a3..29ab0a76 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -284,6 +284,10 @@ export class Tensor { return this._executeOpRaw('unsqueeze', dim); } + expand(sizes: number[]): Tensor { + return this._executeOpRaw('expand', sizes); + } + // trigonometric sin(): Tensor { @@ -300,12 +304,20 @@ export class Tensor { // reduction - sum(): Tensor { - return this._executeUnaryOp('sum'); + sum(dim?: number | number[], keepdim: boolean = false): Tensor { + return this._executeOpRaw('sum', dim, keepdim); + } + + mean(dim?: number | number[], keepdim: boolean = false): Tensor { + return this._executeOpRaw('mean', dim, keepdim); + } + + max(dim?: number | number[], keepdim: boolean = false): Tensor { + return this._executeOpRaw('max', dim, keepdim); } - mean(): Tensor { - return this._executeUnaryOp('mean'); + min(dim?: number | number[], keepdim: boolean = false): Tensor { + return this._executeOpRaw('min', dim, keepdim); } // linalg diff --git a/test/generated.test.js b/test/generated.test.js index 86d73ae3..0c32c5f5 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -85,6 +85,23 @@ describe('Automated Tests', () => { }); }); + describe('Reduction Operations', () => { + testData.reductions?.forEach(test => { + it(test.test_name, () => { + const x = new Tensor(test.input, { requires_grad: true }); + let out; + if (test.dim === null || test.dim === undefined) { + out = x[test.op_name](); + } else { + out = x[test.op_name](test.dim, test.keepdim); + } + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + }); + }); + }); + describe('Neural Network Modules', () => { describe('nn.Linear', () => { testData.linear?.forEach(test => { @@ -153,4 +170,16 @@ describe('Automated Tests', () => { }); }); }); + + describe('Expand Operations', () => { + testData.expand?.forEach(test => { + it(test.test_name, () => { + const x = new Tensor(test.input, { requires_grad: true }); + const out = x.expand(test.expand_shape); + assertDeepCloseTo(out.toArray(), test.expected_output); + out.sum().backward(); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + }); + }); + }); }); diff --git a/test/testcases.gen.js b/test/testcases.gen.js index b3789e29..e2339a33 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -5845,6 +5845,6044 @@ export const testData = { ] } ], + "reductions": [ + { + "test_name": "sum_dim_None_keepdim_False", + "op_name": "sum", + "dim": null, + "keepdim": false, + "input": [ + [ + [ + 2.5331664085388184, + -1.1566962003707886, + -1.0765177011489868, + -0.5477657318115234, + -0.3289257884025574 + ], + [ + 0.05841278284788132, + 2.1100034713745117, + 0.7726138234138489, + 0.9717037081718445, + -0.40528324246406555 + ], + [ + -0.2497664988040924, + 0.22397132217884064, + -0.6875526905059814, + -0.489844411611557, + 0.399687796831131 + ], + [ + 0.6981958150863647, + 0.8767979145050049, + -0.21163156628608704, + 0.05950453504920006, + 1.7285562753677368 + ] + ], + [ + [ + 0.2920781075954437, + -0.6925867199897766, + -0.8442767858505249, + -0.32920387387275696, + -0.7236549258232117 + ], + [ + 0.1715654879808426, + 0.3004419207572937, + 1.6395184993743896, + -1.0744175910949707, + 0.32121846079826355 + ], + [ + 0.2892301678657532, + 0.35196706652641296, + -0.7732301354408264, + 1.324594259262085, + -1.7715193033218384 + ], + [ + 0.0968942642211914, + 0.36735019087791443, + 0.47318676114082336, + 0.5876799821853638, + 0.183979332447052 + ] + ], + [ + [ + -0.025479229167103767, + -0.15332099795341492, + 1.0871516466140747, + 0.6801379919052124, + 0.3648642897605896 + ], + [ + -0.029142292216420174, + 1.1481481790542603, + -1.1586997509002686, + 0.16382797062397003, + -0.5482404828071594 + ], + [ + 0.5447612404823303, + 1.522364616394043, + -1.7682260274887085, + 1.1501456499099731, + 0.03875375911593437 + ], + [ + -0.7637909650802612, + -2.0094480514526367, + -0.5111404657363892, + -0.7054344415664673, + 1.1544770002365112 + ] + ] + ], + "expected_output": 5.651155948638916, + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "sum_dim_0_keepdim_False", + "op_name": "sum", + "dim": 0, + "keepdim": false, + "input": [ + [ + [ + 1.6580723524093628, + 0.2531333863735199, + -0.7901830077171326, + 1.3513535261154175, + -0.07234654575586319 + ], + [ + 2.0859556198120117, + 0.6107109189033508, + 0.2142704576253891, + 0.20150239765644073, + -0.5960649251937866 + ], + [ + -1.5545626878738403, + 1.5109810829162598, + -1.4638135433197021, + -0.5889208316802979, + 0.0267170500010252 + ], + [ + -0.25020739436149597, + 1.2176311016082764, + -1.04723060131073, + 1.5084929466247559, + -1.4026533365249634 + ] + ], + [ + [ + -1.339130163192749, + -2.1181247234344482, + 0.8562206029891968, + 0.4322175085544586, + 0.48647579550743103 + ], + [ + -0.6963290572166443, + 1.926598310470581, + -2.0344724655151367, + -0.8289412260055542, + -0.14974211156368256 + ], + [ + 1.3149042129516602, + 1.2470786571502686, + 0.8008047342300415, + 0.9250672459602356, + 1.6375963687896729 + ], + [ + -0.9297109842300415, + -0.8541247248649597, + 0.15929833054542542, + -0.41023650765419006, + -0.7588294148445129 + ] + ], + [ + [ + -1.8527090549468994, + -1.3658616542816162, + 0.45045167207717896, + -0.01783839240670204, + 0.3848164975643158 + ], + [ + 0.29434895515441895, + 0.6351331472396851, + 0.20356419682502747, + -0.18102435767650604, + -0.9300417900085449 + ], + [ + 0.4725607931613922, + -1.008976936340332, + -0.16193436086177826, + 0.886084258556366, + 1.8162529468536377 + ], + [ + 0.20681823790073395, + 0.11982676386833191, + 0.9609657526016235, + -1.2074177265167236, + 0.1798500418663025 + ] + ] + ], + "expected_output": [ + [ + -1.5337668657302856, + -3.2308530807495117, + 0.5164892673492432, + 1.7657326459884644, + 0.7989457845687866 + ], + [ + 1.6839754581451416, + 3.1724424362182617, + -1.6166378259658813, + -0.8084632158279419, + -1.6758488416671753 + ], + [ + 0.23290231823921204, + 1.7490828037261963, + -0.8249431848526001, + 1.2222306728363037, + 3.4805665016174316 + ], + [ + -0.9731001853942871, + 0.48333314061164856, + 0.07303345203399658, + -0.10916125774383545, + -1.9816327095031738 + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "sum_dim_0_keepdim_True", + "op_name": "sum", + "dim": 0, + "keepdim": true, + "input": [ + [ + [ + 1.354137897491455, + -0.07092823088169098, + 2.172628879547119, + 2.2334160804748535, + 0.22253729403018951 + ], + [ + -0.9300196170806885, + 0.3208498954772949, + 0.03714213892817497, + 0.5674765110015869, + 0.8283826112747192 + ], + [ + -0.005647851154208183, + 0.3184404969215393, + -0.24027781188488007, + -0.25278961658477783, + -0.23367400467395782 + ], + [ + 1.5783164501190186, + 1.2004878520965576, + -1.2668757438659668, + -0.6659766435623169, + -1.7441022396087646 + ] + ], + [ + [ + 0.11392442137002945, + -0.19157223403453827, + 2.5826096534729004, + -0.6460883021354675, + 1.443666696548462 + ], + [ + 0.196146160364151, + 1.050157904624939, + 0.7994747757911682, + 0.19265566766262054, + -0.4098454415798187 + ], + [ + 1.2105144262313843, + -0.1680372804403305, + 0.16369947791099548, + 1.3456140756607056, + -1.1182259321212769 + ], + [ + -0.5912953019142151, + 0.528777003288269, + -0.9880816340446472, + 0.09833063185214996, + 0.31492868065834045 + ] + ], + [ + [ + 1.763922929763794, + -0.048379626125097275, + 0.6488431692123413, + -1.1631555557250977, + 0.45085909962654114 + ], + [ + 0.04091703146696091, + -0.06933283060789108, + 0.2585761547088623, + 0.4775455594062805, + -1.4889180660247803 + ], + [ + -1.4860504865646362, + 0.2769140899181366, + 0.07306429743766785, + 0.9967362284660339, + 1.0237910747528076 + ], + [ + -1.2132517099380493, + 0.9744538068771362, + 0.45322731137275696, + 1.1672674417495728, + 0.7930575013160706 + ] + ] + ], + "expected_output": [ + [ + [ + 3.231985092163086, + -0.3108800947666168, + 5.40408182144165, + 0.42417216300964355, + 2.117063045501709 + ], + [ + -0.6929564476013184, + 1.3016749620437622, + 1.0951931476593018, + 1.237677812576294, + -1.0703809261322021 + ], + [ + -0.28118395805358887, + 0.4273173213005066, + -0.003514036536216736, + 2.0895607471466064, + -0.32810890674591064 + ], + [ + -0.22623056173324585, + 2.703718662261963, + -1.8017301559448242, + 0.5996214151382446, + -0.636116087436676 + ] + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "sum_dim_1_keepdim_False", + "op_name": "sum", + "dim": 1, + "keepdim": false, + "input": [ + [ + [ + -0.9585699439048767, + -0.5702749490737915, + 0.19281719624996185, + 0.3847457766532898, + -0.8595814108848572 + ], + [ + 1.2814747095108032, + 0.9838918447494507, + -0.060601282864809036, + -1.2942535877227783, + 0.6038413643836975 + ], + [ + 1.117246150970459, + 0.4163925051689148, + 0.6747081875801086, + 0.2249874323606491, + -0.5817884206771851 + ], + [ + 0.8646862506866455, + 0.6935068964958191, + -0.4358613193035126, + -0.9824548959732056, + -0.9062879085540771 + ] + ], + [ + [ + 1.25956130027771, + 0.34626761078834534, + 0.21445013582706451, + -0.26712074875831604, + 0.46033239364624023 + ], + [ + 1.179113507270813, + -1.0105520486831665, + -0.620258629322052, + -1.4548780918121338, + -0.5897568464279175 + ], + [ + 1.492590308189392, + 1.144742488861084, + 0.723761260509491, + -0.18846826255321503, + -0.5821011662483215 + ], + [ + -0.4351550042629242, + -1.2878144979476929, + 1.9290111064910889, + -0.13884380459785461, + -0.4319995641708374 + ] + ], + [ + [ + 0.6912683248519897, + 0.5198960900306702, + -0.7546091079711914, + -0.033411234617233276, + 0.0006704955594614148 + ], + [ + -0.012675444595515728, + 2.065865993499756, + 1.0178154706954956, + -1.9378867149353027, + -0.5477144718170166 + ], + [ + -0.18265697360038757, + -1.2373387813568115, + 1.439368486404419, + -0.9488052129745483, + 0.10380307585000992 + ], + [ + -0.6988955140113831, + -0.5013832449913025, + -0.1714278757572174, + -1.5410068035125732, + -0.3302071988582611 + ] + ] + ], + "expected_output": [ + [ + 2.304837226867676, + 1.523516297340393, + 0.3710627853870392, + -1.6669752597808838, + -1.7438163757324219 + ], + [ + 3.496110439300537, + -0.8073564767837524, + 2.2469639778137207, + -2.0493109226226807, + -1.1435251235961914 + ], + [ + -0.20295962691307068, + 0.8470399975776672, + 1.5311470031738281, + -4.4611101150512695, + -0.77344810962677 + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "sum_dim_1_keepdim_True", + "op_name": "sum", + "dim": 1, + "keepdim": true, + "input": [ + [ + [ + 0.21622301638126373, + 0.9593762159347534, + 0.17837846279144287, + -0.1793491244316101, + -0.5583686828613281 + ], + [ + -0.880412757396698, + -0.8791263699531555, + 1.5490630865097046, + 1.5681371688842773, + 1.577425479888916 + ], + [ + -0.4480331838130951, + 1.8764188289642334, + -0.8918796181678772, + 0.43931636214256287, + -1.030982494354248 + ], + [ + -1.4263975620269775, + -0.6300327181816101, + -0.21408268809318542, + -1.3461240530014038, + -0.05369861051440239 + ] + ], + [ + [ + -1.0822854042053223, + 0.3181943893432617, + -2.230900526046753, + -1.0310343503952026, + 0.411555677652359 + ], + [ + 0.7411331534385681, + 0.960921049118042, + -1.2231221199035645, + 0.0782814472913742, + -0.15562321245670319 + ], + [ + 0.40913498401641846, + 0.4989188015460968, + -1.1010884046554565, + -0.5320523977279663, + -0.5345580577850342 + ], + [ + -1.4051520824432373, + 1.8911962509155273, + 1.3595441579818726, + -0.8487699627876282, + -1.841177225112915 + ] + ], + [ + [ + -1.3550636768341064, + -1.025729775428772, + -0.8582409024238586, + -0.47482022643089294, + -1.0972518920898438 + ], + [ + 0.8443618416786194, + 1.2229877710342407, + -0.607181966304779, + -1.8006703853607178, + 1.8074243068695068 + ], + [ + -1.3159326314926147, + -0.1285407692193985, + -0.565393328666687, + 0.2557545602321625, + -1.537744164466858 + ], + [ + -0.1796068251132965, + -0.11240867525339127, + 0.2712157368659973, + 1.1221709251403809, + 2.794304609298706 + ] + ] + ], + "expected_output": [ + [ + [ + -2.5386204719543457, + 1.3266358375549316, + 0.6214792728424072, + 0.4819803237915039, + -0.06562431156635284 + ] + ], + [ + [ + -1.3371694087982178, + 3.6692304611206055, + -3.1955666542053223, + -2.3335752487182617, + -2.119802951812744 + ] + ], + [ + [ + -2.0062413215637207, + -0.043691448867321014, + -1.7596004009246826, + -0.8975651264190674, + 1.9667328596115112 + ] + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "sum_dim_-1_keepdim_False", + "op_name": "sum", + "dim": -1, + "keepdim": false, + "input": [ + [ + [ + 2.321488618850708, + -0.9497286677360535, + 1.6485934257507324, + -1.9016783237457275, + 0.6118991374969482 + ], + [ + -0.5020667910575867, + 0.5067698955535889, + 0.2828640341758728, + -1.9398406744003296, + -1.724557876586914 + ], + [ + -1.187090516090393, + 0.2815004289150238, + 0.21720317006111145, + 0.6477780938148499, + -0.6847841143608093 + ], + [ + -0.7950332760810852, + -0.5194478034973145, + 0.31374549865722656, + -0.13856260478496552, + -0.7214519381523132 + ] + ], + [ + [ + -0.6180415749549866, + 0.8307966589927673, + -1.4335700273513794, + -0.8756160736083984, + 1.3628478050231934 + ], + [ + -0.8794435858726501, + 0.2203734815120697, + 0.07557395845651627, + 1.5741719007492065, + 0.13540978729724884 + ], + [ + -0.7953895330429077, + -1.1213213205337524, + -0.10318246483802795, + 1.6807347536087036, + -0.2909294664859772 + ], + [ + -0.19037924706935883, + -0.4397279620170593, + 0.890130877494812, + 0.3846955895423889, + 0.17066167294979095 + ] + ], + [ + [ + -0.7483856081962585, + 0.6799973845481873, + -0.1450810432434082, + -0.010367825627326965, + -0.4629494845867157 + ], + [ + -1.6245776414871216, + -0.18524813652038574, + -0.34354501962661743, + -0.9827845096588135, + 1.4724041223526 + ], + [ + 0.5184305310249329, + 1.1344083547592163, + 0.1288852095603943, + 0.2891088128089905, + 0.6047351360321045 + ], + [ + 0.0995018258690834, + 0.21674297749996185, + -0.7446264624595642, + -1.889365315437317, + 0.8229770660400391 + ] + ] + ], + "expected_output": [ + [ + 1.730574131011963, + -3.376831531524658, + -0.7253928780555725, + -1.8607500791549683 + ], + [ + -0.7335832118988037, + 1.1260855197906494, + -0.6300879716873169, + 0.8153809309005737 + ], + [ + -0.6867865324020386, + -1.6637511253356934, + 2.675568103790283, + -1.494769811630249 + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "sum_dim_-1_keepdim_True", + "op_name": "sum", + "dim": -1, + "keepdim": true, + "input": [ + [ + [ + 0.6587340831756592, + 0.6428387761116028, + -1.036969780921936, + -0.2975744307041168, + -0.8517249226570129 + ], + [ + 0.2891763746738434, + -0.8932358622550964, + 1.8647022247314453, + 0.9801297783851624, + 0.11956664174795151 + ], + [ + -0.12774989008903503, + 0.357759952545166, + -1.123816728591919, + 0.46558526158332825, + -3.0509555339813232 + ], + [ + 0.8507809042930603, + -0.6753576993942261, + -0.32092228531837463, + -1.3800082206726074, + -0.3640788197517395 + ] + ], + [ + [ + -0.1983477771282196, + 0.5546607375144958, + 0.26535895466804504, + -0.27042195200920105, + -0.28734639286994934 + ], + [ + -0.6621134877204895, + 0.8970773220062256, + 1.0963815450668335, + 0.00377941457554698, + 0.41841161251068115 + ], + [ + 0.7451213002204895, + 0.019408423453569412, + -2.3971786499023438, + 0.38038408756256104, + 1.3957277536392212 + ], + [ + -0.00876561738550663, + 0.04509954899549484, + 0.21804611384868622, + 2.176718235015869, + 2.1929168701171875 + ] + ], + [ + [ + 0.15840405225753784, + -0.8398545384407043, + -0.8984683752059937, + -0.8500047326087952, + 2.26790452003479 + ], + [ + 0.9991294741630554, + -0.29818224906921387, + -0.7564722895622253, + -0.20476730167865753, + 1.405016303062439 + ], + [ + -1.5722324848175049, + 0.6451810002326965, + 0.3931215703487396, + 0.4133126139640808, + 0.4638987183570862 + ], + [ + -0.02982708252966404, + 1.2715272903442383, + 1.0848652124404907, + -0.5404359698295593, + 0.4884187579154968 + ] + ] + ], + "expected_output": [ + [ + [ + -0.8846962451934814 + ], + [ + 2.3603391647338867 + ], + [ + -3.4791769981384277 + ], + [ + -1.889586091041565 + ] + ], + [ + [ + 0.0639035701751709 + ], + [ + 1.7535364627838135 + ], + [ + 0.14346301555633545 + ], + [ + 4.624014854431152 + ] + ], + [ + [ + -0.16201895475387573 + ], + [ + 1.1447237730026245 + ], + [ + 0.3432813584804535 + ], + [ + 2.274548292160034 + ] + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "mean_dim_None_keepdim_False", + "op_name": "mean", + "dim": null, + "keepdim": false, + "input": [ + [ + [ + -0.49658793210983276, + 0.36382463574409485, + 0.3396982252597809, + 1.273138165473938, + -1.5371414422988892 + ], + [ + 1.0402002334594727, + -1.1433440446853638, + -0.6347954273223877, + -0.009090420790016651, + 0.253021240234375 + ], + [ + 0.8895691633224487, + 2.015190601348877, + 0.12288182973861694, + 0.283156156539917, + 0.7347971796989441 + ], + [ + 1.4138668775558472, + -2.4690840244293213, + -1.6101100444793701, + 1.7436981201171875, + -0.38771313428878784 + ] + ], + [ + [ + 0.7723278403282166, + 0.22671592235565186, + -0.3837747573852539, + -0.7681311964988708, + 1.8044092655181885 + ], + [ + 1.4646685123443604, + 0.2913444936275482, + -1.1624996662139893, + -0.4783642590045929, + 1.3870203495025635 + ], + [ + -0.4341133236885071, + 0.2929425835609436, + -1.144444465637207, + -1.1233654022216797, + -0.7945832014083862 + ], + [ + -0.5694751739501953, + 0.0549420528113842, + -0.7646363377571106, + -1.0492900609970093, + 1.0828652381896973 + ] + ], + [ + [ + -0.0699654296040535, + 0.4944293797016144, + 2.1871159076690674, + 1.1617707014083862, + -0.9024235010147095 + ], + [ + -2.41979718208313, + 0.7134581804275513, + -1.9506268501281738, + -0.6031076312065125, + -0.7942026853561401 + ], + [ + 0.023615580052137375, + -0.7165514230728149, + 1.0070719718933105, + -0.12568299472332, + 0.2154434323310852 + ], + [ + -1.2841796875, + 2.2291040420532227, + 0.8249357342720032, + 0.4553866684436798, + 0.5599141120910645 + ] + ] + ], + "expected_output": 0.03159071132540703, + "expected_grad": [ + [ + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ] + ], + [ + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ] + ], + [ + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ], + [ + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107, + 0.01666666753590107 + ] + ] + ] + }, + { + "test_name": "mean_dim_0_keepdim_False", + "op_name": "mean", + "dim": 0, + "keepdim": false, + "input": [ + [ + [ + 0.20383627712726593, + -0.7248139977455139, + 0.2881997525691986, + 1.6998308897018433, + 2.432499408721924 + ], + [ + 0.2585121691226959, + 1.3330131769180298, + 0.12649448215961456, + 0.17614391446113586, + 0.10091600567102432 + ], + [ + 1.2233283519744873, + 0.791765034198761, + 0.5074418187141418, + 0.4391697347164154, + -0.8357943892478943 + ], + [ + -0.6900646686553955, + 0.47324633598327637, + 0.22348645329475403, + 0.41359904408454895, + -0.5239112377166748 + ] + ], + [ + [ + 0.13422854244709015, + -1.1245696544647217, + 1.3094075918197632, + -0.07285541296005249, + -0.70379638671875 + ], + [ + 0.558134913444519, + 0.2722645699977875, + -0.428587943315506, + 0.8239985108375549, + -1.3989880084991455 + ], + [ + -0.6815629601478577, + 0.8538435697555542, + -0.5384427905082703, + -0.6699069142341614, + 0.23984402418136597 + ], + [ + 2.1043002605438232, + -0.7700114250183105, + -1.5130436420440674, + -0.403571754693985, + -0.442477822303772 + ] + ], + [ + [ + -0.19414693117141724, + -1.3718643188476562, + -0.2043316662311554, + -1.1885942220687866, + -1.4498616456985474 + ], + [ + 0.1425102800130844, + 0.3205632269382477, + -0.585231602191925, + 0.4060876965522766, + 0.2572997212409973 + ], + [ + 0.8778835535049438, + 0.7318398952484131, + 0.3467099368572235, + -0.08159374445676804, + -1.4703203439712524 + ], + [ + -0.3415772616863251, + 1.2259759902954102, + 1.8914309740066528, + -0.6524525284767151, + -0.8879274725914001 + ] + ] + ], + "expected_output": [ + [ + 0.047972630709409714, + -1.073749303817749, + 0.4644252359867096, + 0.1461271047592163, + 0.09294712543487549 + ], + [ + 0.3197191059589386, + 0.6419469714164734, + -0.29577502608299255, + 0.4687434136867523, + -0.3469240665435791 + ], + [ + 0.47321629524230957, + 0.792482852935791, + 0.10523632168769836, + -0.10411030799150467, + -0.6887569427490234 + ], + [ + 0.35755276679992676, + 0.309736967086792, + 0.20062458515167236, + -0.21414174139499664, + -0.6181054711341858 + ] + ], + "expected_grad": [ + [ + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ] + ], + [ + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ] + ], + [ + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ] + ] + ] + }, + { + "test_name": "mean_dim_0_keepdim_True", + "op_name": "mean", + "dim": 0, + "keepdim": true, + "input": [ + [ + [ + 1.7347886562347412, + 0.032030463218688965, + 0.9726912379264832, + 1.0879974365234375, + -1.1082324981689453 + ], + [ + 2.1468100547790527, + -0.20463405549526215, + -0.1949448138475418, + -0.3272537291049957, + 0.48203662037849426 + ], + [ + -1.8594290018081665, + 0.14130207896232605, + 1.6815085411071777, + 0.9141939282417297, + 1.2556324005126953 + ], + [ + -0.8077448010444641, + 0.19963520765304565, + -0.19339345395565033, + -1.219641089439392, + 1.0411797761917114 + ] + ], + [ + [ + -0.10632240027189255, + 0.07336213439702988, + 0.4191838204860687, + -0.8154667019844055, + -0.5155897736549377 + ], + [ + 0.32028329372406006, + 1.5522725582122803, + 1.3522603511810303, + 1.1632877588272095, + -0.5602036714553833 + ], + [ + -0.8605437278747559, + -0.400406152009964, + 0.5620190501213074, + -2.7735390663146973, + 1.15679931640625 + ], + [ + -0.2487672120332718, + -0.10994483530521393, + -0.4232594072818756, + 1.6037938594818115, + 0.7152358293533325 + ] + ], + [ + [ + -0.6582046151161194, + 0.395238995552063, + -0.6984677910804749, + 0.8194941282272339, + -2.815762519836426 + ], + [ + -0.28375279903411865, + 1.9665663242340088, + 0.4404697120189667, + -0.5943435430526733, + 0.7206440567970276 + ], + [ + -1.0877529382705688, + -0.19153426587581635, + -0.6546841263771057, + 1.0335131883621216, + -0.31327491998672485 + ], + [ + -0.18328620493412018, + -0.17836901545524597, + 2.0791051387786865, + 0.1488768607378006, + 3.190993547439575 + ] + ] + ], + "expected_output": [ + [ + [ + 0.32342055439949036, + 0.16687719523906708, + 0.23113574087619781, + 0.3640082776546478, + -1.4798616170883179 + ], + [ + 0.7277801632881165, + 1.1047348976135254, + 0.5325950980186462, + 0.0805635079741478, + 0.2141590118408203 + ], + [ + -1.2692418098449707, + -0.15021277964115143, + 0.5296145081520081, + -0.27527734637260437, + 0.6997189521789551 + ], + [ + -0.41326606273651123, + -0.0295595470815897, + 0.4874840974807739, + 0.17767654359340668, + 1.6491364240646362 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ] + ], + [ + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ] + ], + [ + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ], + [ + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408, + 0.3333333432674408 + ] + ] + ] + }, + { + "test_name": "mean_dim_1_keepdim_False", + "op_name": "mean", + "dim": 1, + "keepdim": false, + "input": [ + [ + [ + 0.7202309370040894, + 0.8769089579582214, + -0.8568285703659058, + -1.469225525856018, + 0.9260697960853577 + ], + [ + -0.5594438910484314, + 2.2181360721588135, + 0.4000236988067627, + 1.8645329475402832, + -0.8439115881919861 + ], + [ + -1.0606149435043335, + 1.045390248298645, + 1.1547093391418457, + 0.3212544322013855, + 0.1364518105983734 + ], + [ + -1.7697168588638306, + -0.4297706186771393, + -0.9330264925956726, + 0.03445770964026451, + 0.5089080333709717 + ] + ], + [ + [ + 0.6470111608505249, + -0.5019861459732056, + -0.14353430271148682, + -1.2236298322677612, + -1.9437434673309326 + ], + [ + 0.09865526109933853, + 2.5731418132781982, + -0.7051668167114258, + -1.1590256690979004, + -0.2769569158554077 + ], + [ + 1.1326403617858887, + -0.961678147315979, + 0.07773400843143463, + 1.8036106824874878, + -1.3065544366836548 + ], + [ + 1.1060339212417603, + 0.921552836894989, + -1.3966097831726074, + -0.888012707233429, + -2.21113920211792 + ] + ], + [ + [ + -1.1771180629730225, + 1.7409440279006958, + 4.6923309128033e-05, + 0.5687845945358276, + -0.8220173120498657 + ], + [ + 0.7975156307220459, + -0.7685240507125854, + 1.5375657081604004, + -1.7771120071411133, + -1.0646121501922607 + ], + [ + -0.42104366421699524, + -0.6636930704116821, + -1.5027097463607788, + -1.0865437984466553, + 2.1495704650878906 + ], + [ + -0.9262224435806274, + -0.8617974519729614, + -0.013285640627145767, + -0.051826003938913345, + 0.41152408719062805 + ] + ] + ], + "expected_output": [ + [ + -0.6673861742019653, + 0.9276661276817322, + -0.05878050625324249, + 0.18775488436222076, + 0.18187952041625977 + ], + [ + 0.7460851669311523, + 0.5077575445175171, + -0.5418941974639893, + -0.3667644262313843, + -1.434598445892334 + ], + [ + -0.4317171275615692, + -0.1382676362991333, + 0.005404322408139706, + -0.5866743326187134, + 0.16861626505851746 + ] + ], + "expected_grad": [ + [ + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ] + ], + [ + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ] + ], + [ + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ] + ] + ] + }, + { + "test_name": "mean_dim_1_keepdim_True", + "op_name": "mean", + "dim": 1, + "keepdim": true, + "input": [ + [ + [ + -2.168846368789673, + 1.213675856590271, + -1.8085858821868896, + 0.19425715506076813, + 0.6679531335830688 + ], + [ + -1.1588698625564575, + 0.8675621151924133, + 1.5683906078338623, + -1.4785282611846924, + 0.045808374881744385 + ], + [ + -0.10694064944982529, + 0.35308536887168884, + 0.3301672339439392, + -0.5309102535247803, + 1.9589688777923584 + ], + [ + -0.46830111742019653, + -0.16547387838363647, + -0.3069077730178833, + 1.4188532829284668, + -0.4566229581832886 + ] + ], + [ + [ + -1.5976078510284424, + 0.7735506892204285, + -0.0893024280667305, + -2.8384506702423096, + 0.7005379796028137 + ], + [ + 1.4387873411178589, + -1.0684497356414795, + -0.16634242236614227, + 0.517611563205719, + -0.7325262427330017 + ], + [ + 1.6848194599151611, + 0.4438650906085968, + 0.056602153927087784, + -1.5038570165634155, + -0.4485261142253876 + ], + [ + 0.5257315635681152, + 0.2619018256664276, + 0.7167068123817444, + -1.2776819467544556, + 0.4211602210998535 + ] + ], + [ + [ + 1.9249420166015625, + -0.3405316174030304, + -0.43293496966362, + 1.3083903789520264, + 0.6581417322158813 + ], + [ + 1.5086971521377563, + 0.40693262219429016, + 0.4082213044166565, + -0.4960733652114868, + -0.9290968179702759 + ], + [ + -0.1992855966091156, + 0.468250036239624, + -0.9421932697296143, + 1.3477203845977783, + -0.08609210699796677 + ], + [ + 0.60735023021698, + 0.227834552526474, + -0.6186387538909912, + 1.1308897733688354, + -0.12078773975372314 + ] + ] + ], + "expected_output": [ + [ + [ + -0.9757395386695862, + 0.5672123432159424, + -0.05423395335674286, + -0.09908202290534973, + 0.5540268421173096 + ] + ], + [ + [ + 0.5129326581954956, + 0.10271696746349335, + 0.12941601872444153, + -1.2755944728851318, + -0.014838539063930511 + ] + ], + [ + [ + 0.9604259729385376, + 0.19062140583992004, + -0.39638641476631165, + 0.8227318525314331, + -0.11945873498916626 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ] + ], + [ + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ] + ], + [ + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ], + [ + 0.25, + 0.25, + 0.25, + 0.25, + 0.25 + ] + ] + ] + }, + { + "test_name": "mean_dim_-1_keepdim_False", + "op_name": "mean", + "dim": -1, + "keepdim": false, + "input": [ + [ + [ + 0.5786823630332947, + -1.099729299545288, + 0.2812545895576477, + 0.08700139075517654, + -0.25706610083580017 + ], + [ + 2.2180261611938477, + 1.240154504776001, + -0.6573424935340881, + -0.05131905525922775, + -0.26267147064208984 + ], + [ + -0.45390239357948303, + 1.4244478940963745, + 2.269195318222046, + 1.3104835748672485, + -0.3178943395614624 + ], + [ + -0.3773656487464905, + -0.45319506525993347, + 1.2440320253372192, + -0.7194162011146545, + 1.2199066877365112 + ] + ], + [ + [ + 1.435631513595581, + -0.31398269534111023, + 0.8979019522666931, + 0.6358874440193176, + -0.31363436579704285 + ], + [ + 0.13522106409072876, + -0.39359593391418457, + -0.02484050951898098, + -0.3632628321647644, + -0.6941221952438354 + ], + [ + -0.9816297292709351, + -0.05556102097034454, + -0.6147816777229309, + 1.4754621982574463, + -0.5717736482620239 + ], + [ + -1.5560880899429321, + -0.9632699489593506, + -0.4366423487663269, + -0.008548072539269924, + 0.04459971562027931 + ] + ], + [ + [ + -1.2941125631332397, + 0.14418895542621613, + -1.1567072868347168, + 1.8155642747879028, + 0.05806141346693039 + ], + [ + -1.070618987083435, + 0.8081686496734619, + -1.5791850090026855, + 0.6206215023994446, + -1.152881145477295 + ], + [ + 2.2968475818634033, + 1.649484395980835, + -0.2084096521139145, + 1.9412633180618286, + -0.18736235797405243 + ], + [ + -1.7039966583251953, + -2.115445852279663, + 0.9916136860847473, + -2.7026309967041016, + -0.6108700037002563 + ] + ] + ], + "expected_output": [ + [ + -0.08197140693664551, + 0.49736952781677246, + 0.8464659452438354, + 0.18279236555099487 + ], + [ + 0.4683607518672943, + -0.2681201100349426, + -0.1496567726135254, + -0.5839897394180298 + ], + [ + -0.08660104125738144, + -0.47477903962135315, + 1.0983645915985107, + -1.2282660007476807 + ] + ], + "expected_grad": [ + [ + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ] + ], + [ + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ] + ], + [ + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ] + ] + ] + }, + { + "test_name": "mean_dim_-1_keepdim_True", + "op_name": "mean", + "dim": -1, + "keepdim": true, + "input": [ + [ + [ + 0.00420670909807086, + -1.4650157690048218, + 0.6085794568061829, + -0.07576155662536621, + -0.4139658212661743 + ], + [ + -1.3813194036483765, + -0.07809803634881973, + -0.3723330795764923, + 0.4985557794570923, + -1.633231520652771 + ], + [ + 0.03490933030843735, + 0.5769792199134827, + -0.009515623562037945, + -0.4003794491291046, + 0.5099198222160339 + ], + [ + -0.7801733613014221, + 0.5647550821304321, + 0.30276739597320557, + -0.15120232105255127, + -0.47413021326065063 + ] + ], + [ + [ + 0.6317481994628906, + -0.22863811254501343, + -0.38931718468666077, + 1.4754453897476196, + 0.23239462077617645 + ], + [ + -0.26003894209861755, + 1.0476551055908203, + 0.545058012008667, + 1.7255419492721558, + 0.5405985116958618 + ], + [ + 1.0360978841781616, + 0.5318379998207092, + 1.2613322734832764, + 0.8772295713424683, + -2.291107416152954 + ], + [ + 1.8939599990844727, + -2.3213963508605957, + -0.6423410773277283, + 1.5522570610046387, + -2.3087081909179688 + ] + ], + [ + [ + -0.7946994304656982, + 0.7812591195106506, + 1.9472111463546753, + 0.21231839060783386, + 0.1915358453989029 + ], + [ + 0.16352267563343048, + 0.3051132261753082, + 0.7242569923400879, + -0.08786772191524506, + -1.1320451498031616 + ], + [ + 0.2265060991048813, + 0.5291025042533875, + -1.4391361474990845, + 1.6620672941207886, + 0.14816075563430786 + ], + [ + -1.129300832748413, + 1.3774371147155762, + -0.16838155686855316, + -2.7773499488830566, + 0.3025462329387665 + ] + ] + ], + "expected_output": [ + [ + [ + -0.2683914303779602 + ], + [ + -0.5932852625846863 + ], + [ + 0.1423826515674591 + ], + [ + -0.10759668052196503 + ] + ], + [ + [ + 0.34432658553123474 + ], + [ + 0.719762921333313 + ], + [ + 0.28307804465293884 + ], + [ + -0.3652457296848297 + ] + ], + [ + [ + 0.46752500534057617 + ], + [ + -0.005403992719948292 + ], + [ + 0.2253400981426239 + ], + [ + -0.47900980710983276 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ] + ], + [ + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ] + ], + [ + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ], + [ + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224, + 0.20000000298023224 + ] + ] + ] + }, + { + "test_name": "max_dim_None_keepdim_False", + "op_name": "max", + "dim": null, + "keepdim": false, + "input": [ + [ + [ + 0.3821605145931244, + -0.19578158855438232, + -2.0732667446136475, + 0.6599233150482178, + 1.7670403718948364 + ], + [ + -1.169783353805542, + -0.1317385584115982, + -0.6004424095153809, + -0.05841507390141487, + -1.4766151905059814 + ], + [ + -1.0946006774902344, + -0.8658109307289124, + 0.8367514610290527, + -0.9400964975357056, + 1.4285417795181274 + ], + [ + 0.1983281522989273, + 1.4749457836151123, + -1.4756296873092651, + 0.8483810424804688, + -0.09390979260206223 + ] + ], + [ + [ + -0.13151048123836517, + -0.035332635045051575, + 0.004686277825385332, + 0.15220017731189728, + -0.06878392398357391 + ], + [ + -0.6154842972755432, + 1.0898313522338867, + -0.4806813597679138, + -0.630047082901001, + 1.1917531490325928 + ], + [ + -1.0328683853149414, + 0.38320526480674744, + -1.2028323411941528, + -2.4587764739990234, + -0.5534238815307617 + ], + [ + 0.3374936878681183, + 0.9784513115882874, + 1.1227375268936157, + 0.5851324796676636, + 1.3817517757415771 + ] + ], + [ + [ + 0.8889638781547546, + -1.1525547504425049, + 1.7995572090148926, + 1.6228371858596802, + 1.9551998376846313 + ], + [ + -0.06532658636569977, + 0.14630116522312164, + 1.1357200145721436, + -0.2688539922237396, + -0.9126741886138916 + ], + [ + -1.0687869787216187, + 0.38017958402633667, + 1.013214111328125, + -1.1486494541168213, + -0.7915613055229187 + ], + [ + -0.3213580846786499, + 0.5456286668777466, + -1.2671267986297607, + -0.12716197967529297, + 0.8282967209815979 + ] + ] + ], + "expected_output": 1.9551998376846313, + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "max_dim_0_keepdim_False", + "op_name": "max", + "dim": 0, + "keepdim": false, + "input": [ + [ + [ + -0.13801060616970062, + 0.09937097132205963, + -0.16284485161304474, + 0.18977606296539307, + -1.2571945190429688 + ], + [ + 0.25705486536026, + 1.104391098022461, + 1.1175512075424194, + -0.6293240189552307, + -1.676796793937683 + ], + [ + 0.6724022030830383, + 1.988852858543396, + 0.8156912922859192, + -1.4682725667953491, + -1.521799087524414 + ], + [ + -1.2172812223434448, + -0.23146040737628937, + 0.5549997091293335, + 0.32450324296951294, + 1.4936802387237549 + ] + ], + [ + [ + 0.5853366255760193, + 0.7599589824676514, + 1.7872188091278076, + -1.3676286935806274, + 0.8856539726257324 + ], + [ + 0.9161636829376221, + 0.4850791096687317, + -1.0356383323669434, + 0.1620996594429016, + -0.34564009308815 + ], + [ + -1.2987875938415527, + -0.2696373760700226, + 0.6803566813468933, + -0.12983323633670807, + 0.09731336683034897 + ], + [ + 0.7956935167312622, + -2.1607372760772705, + -0.5694004893302917, + -1.2072747945785522, + 0.7853367924690247 + ] + ], + [ + [ + 0.8770406246185303, + -2.0921499729156494, + 1.5937228202819824, + 2.563725471496582, + -0.2689884901046753 + ], + [ + 0.13259819149971008, + 0.4738202393054962, + 0.031055578961968422, + -0.1489359736442566, + -0.3652037978172302 + ], + [ + -1.8156386613845825, + 1.1129406690597534, + -0.09201753884553909, + -0.981147050857544, + 1.0239890813827515 + ], + [ + -1.036582350730896, + -1.997800350189209, + 1.5087897777557373, + 0.19652637839317322, + 1.0685486793518066 + ] + ] + ], + "expected_output": [ + [ + 0.8770406246185303, + 0.7599589824676514, + 1.7872188091278076, + 2.563725471496582, + 0.8856539726257324 + ], + [ + 0.9161636829376221, + 1.104391098022461, + 1.1175512075424194, + 0.1620996594429016, + -0.34564009308815 + ], + [ + 0.6724022030830383, + 1.988852858543396, + 0.8156912922859192, + -0.12983323633670807, + 1.0239890813827515 + ], + [ + 0.7956935167312622, + -0.23146040737628937, + 1.5087897777557373, + 0.32450324296951294, + 1.4936802387237549 + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 1.0, + 0.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 1.0, + 1.0 + ] + ], + [ + [ + 0.0, + 1.0, + 1.0, + 0.0, + 1.0 + ], + [ + 1.0, + 0.0, + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "max_dim_0_keepdim_True", + "op_name": "max", + "dim": 0, + "keepdim": true, + "input": [ + [ + [ + 0.3579265773296356, + -1.0362085103988647, + 1.0006709098815918, + 0.7048721313476562, + -0.6978404521942139 + ], + [ + 0.4728609323501587, + -0.6566532254219055, + -0.8678151965141296, + 0.0302385576069355, + -0.5570979714393616 + ], + [ + -0.8829219937324524, + -0.7062578201293945, + -1.2799997329711914, + 0.13592901825904846, + -0.28107115626335144 + ], + [ + 1.7253460884094238, + -0.7556604743003845, + 2.0246987342834473, + -0.6380594372749329, + 0.5336771607398987 + ] + ], + [ + [ + 0.1680675745010376, + -1.0805774927139282, + 0.8652670383453369, + 0.9823195338249207, + -0.5655248165130615 + ], + [ + 0.43977639079093933, + -0.6277503967285156, + -0.14591790735721588, + -0.42359691858291626, + -1.4881683588027954 + ], + [ + 0.8582064509391785, + 3.035121202468872, + 1.7607189416885376, + -0.5611859560012817, + 0.030582552775740623 + ], + [ + 0.01513738464564085, + 1.1773208379745483, + -0.9649611115455627, + -0.24674776196479797, + -0.6797627210617065 + ] + ], + [ + [ + -0.7475828528404236, + -0.21754391491413116, + -1.3795819282531738, + 1.0700255632400513, + 1.608759880065918 + ], + [ + -0.4297754466533661, + -0.77903813123703, + 1.1783149242401123, + 0.04237056151032448, + -0.610821008682251 + ], + [ + -0.6625555157661438, + -0.5495360493659973, + 0.2577652037143707, + -2.150420904159546, + -2.154161214828491 + ], + [ + -0.42972853779792786, + 1.4808158874511719, + -2.7135519981384277, + 1.1272135972976685, + 0.5445007681846619 + ] + ] + ], + "expected_output": [ + [ + [ + 0.3579265773296356, + -0.21754391491413116, + 1.0006709098815918, + 1.0700255632400513, + 1.608759880065918 + ], + [ + 0.4728609323501587, + -0.6277503967285156, + 1.1783149242401123, + 0.04237056151032448, + -0.5570979714393616 + ], + [ + 0.8582064509391785, + 3.035121202468872, + 1.7607189416885376, + 0.13592901825904846, + 0.030582552775740623 + ], + [ + 1.7253460884094238, + 1.4808158874511719, + 2.0246987342834473, + 1.1272135972976685, + 0.5445007681846619 + ] + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 1.0, + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "max_dim_1_keepdim_False", + "op_name": "max", + "dim": 1, + "keepdim": false, + "input": [ + [ + [ + -1.1812111139297485, + 0.29110395908355713, + -1.908882975578308, + -0.06162146106362343, + -0.628868818283081 + ], + [ + -0.0399823822081089, + -0.9634820222854614, + -1.054305911064148, + 1.3201165199279785, + 0.01912905089557171 + ], + [ + 0.6439768075942993, + -1.622911810874939, + 0.24067530035972595, + 1.6770813465118408, + -0.09622633457183838 + ], + [ + -0.6806969046592712, + 0.22181209921836853, + -0.09738165885210037, + -0.3662233054637909, + 0.5110824108123779 + ] + ], + [ + [ + 0.947607159614563, + -1.7693769931793213, + 0.9019067287445068, + 0.3177003860473633, + -0.9191910624504089 + ], + [ + 0.47818925976753235, + 0.627395510673523, + -0.9072081446647644, + -1.1753108501434326, + -1.6300257444381714 + ], + [ + 0.7812330722808838, + -1.473711609840393, + -0.2650183439254761, + 1.5695449113845825, + -0.9781676530838013 + ], + [ + 0.46865877509117126, + -0.03328606113791466, + -0.8684351444244385, + -1.338854193687439, + -0.10444001853466034 + ] + ], + [ + [ + 0.33355948328971863, + -0.5553439855575562, + 0.8256968259811401, + 1.3953009843826294, + -0.8951465487480164 + ], + [ + -0.08590231090784073, + -0.34807300567626953, + -0.9660927653312683, + -0.6545328497886658, + -2.0421197414398193 + ], + [ + 0.9974169135093689, + 0.3814171552658081, + 0.24766799807548523, + 0.9761032462120056, + -1.2878117561340332 + ], + [ + 1.9193944931030273, + -0.9316161870956421, + -0.3878573179244995, + 1.8630023002624512, + 0.6344600915908813 + ] + ] + ], + "expected_output": [ + [ + 0.6439768075942993, + 0.29110395908355713, + 0.24067530035972595, + 1.6770813465118408, + 0.5110824108123779 + ], + [ + 0.947607159614563, + 0.627395510673523, + 0.9019067287445068, + 1.5695449113845825, + -0.10444001853466034 + ], + [ + 1.9193944931030273, + 0.3814171552658081, + 0.8256968259811401, + 1.8630023002624512, + 0.6344600915908813 + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 1.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + ], + [ + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + ], + [ + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "max_dim_1_keepdim_True", + "op_name": "max", + "dim": 1, + "keepdim": true, + "input": [ + [ + [ + -0.15298272669315338, + -0.291658490896225, + 1.3547232151031494, + 1.1477179527282715, + -1.1454607248306274 + ], + [ + 0.33044537901878357, + -0.9961053133010864, + 0.06837695091962814, + -0.002813637489452958, + -0.6423792839050293 + ], + [ + 0.45413073897361755, + -0.44131579995155334, + 1.692244052886963, + -0.12363708764314651, + 0.5800541639328003 + ], + [ + -0.3184976875782013, + 1.165942907333374, + -0.24008060991764069, + 0.681287944316864, + -0.34171757102012634 + ] + ], + [ + [ + 0.34814006090164185, + 0.992973804473877, + 0.6181811690330505, + 2.570577383041382, + 2.195984125137329 + ], + [ + 0.8412518501281738, + -0.6978152394294739, + 1.6602482795715332, + -0.1676439493894577, + -1.480851411819458 + ], + [ + -0.17118047177791595, + 0.2488422989845276, + 0.08594394475221634, + -0.3800842761993408, + 0.944334864616394 + ], + [ + -0.4332982003688812, + -0.9019569158554077, + -1.0107343196868896, + -0.7094535827636719, + -0.1548715978860855 + ] + ], + [ + [ + -1.1838287115097046, + 0.8204308748245239, + -1.0191556215286255, + -0.27120286226272583, + 1.2692794799804688 + ], + [ + 2.2910208702087402, + -0.07968119531869888, + -2.142704963684082, + 1.5941132307052612, + 2.5384137630462646 + ], + [ + 0.8317916393280029, + 0.5718692541122437, + -1.202392816543579, + -0.6351379156112671, + 0.20571336150169373 + ], + [ + 1.2084790468215942, + -1.2975432872772217, + -1.7842353582382202, + -1.5064395666122437, + -0.5166544914245605 + ] + ] + ], + "expected_output": [ + [ + [ + 0.45413073897361755, + 1.165942907333374, + 1.692244052886963, + 1.1477179527282715, + 0.5800541639328003 + ] + ], + [ + [ + 0.8412518501281738, + 0.992973804473877, + 1.6602482795715332, + 2.570577383041382, + 2.195984125137329 + ] + ], + [ + [ + 2.2910208702087402, + 0.8204308748245239, + -1.0191556215286255, + 1.5941132307052612, + 2.5384137630462646 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 1.0, + 0.0, + 1.0, + 1.0 + ], + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 1.0, + 1.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "max_dim_-1_keepdim_False", + "op_name": "max", + "dim": -1, + "keepdim": false, + "input": [ + [ + [ + 0.7335371971130371, + 0.9938647150993347, + 0.00801965780556202, + -0.28345587849617004, + -1.0710505247116089 + ], + [ + -0.39534568786621094, + -1.0722109079360962, + 0.33898138999938965, + 0.1372641772031784, + -0.28324073553085327 + ], + [ + 0.8449776768684387, + -1.6651710271835327, + 0.9013379216194153, + 0.29200538992881775, + 0.0021756188943982124 + ], + [ + -0.2805594801902771, + -0.8447388410568237, + -1.7777600288391113, + 1.6797508001327515, + -0.30756810307502747 + ] + ], + [ + [ + 0.17818263173103333, + 0.3059806525707245, + 0.3167516589164734, + -0.9520257711410522, + 0.6430982351303101 + ], + [ + -1.3191593885421753, + -0.5693896412849426, + -1.8995989561080933, + 0.2520817816257477, + 0.7248584032058716 + ], + [ + -0.30675002932548523, + -0.3078252077102661, + -0.39913156628608704, + -0.545810341835022, + -0.9492759704589844 + ], + [ + -0.5826377272605896, + 0.6084815859794617, + 1.8586663007736206, + 0.33828064799308777, + 0.22547557950019836 + ] + ], + [ + [ + 1.375124216079712, + 0.4969656765460968, + -0.5050092339515686, + 1.3103235960006714, + -0.5601279139518738 + ], + [ + 0.564572811126709, + 0.28999093174934387, + -0.2832452356815338, + -0.7486765384674072, + -1.4253593683242798 + ], + [ + -0.3249308466911316, + 0.24911366403102875, + -0.6594748497009277, + -1.5963871479034424, + -0.6603827476501465 + ], + [ + -0.9291712641716003, + 1.041069507598877, + 1.7303272485733032, + -0.8963518738746643, + -1.7486891746520996 + ] + ] + ], + "expected_output": [ + [ + 0.9938647150993347, + 0.33898138999938965, + 0.9013379216194153, + 1.6797508001327515 + ], + [ + 0.6430982351303101, + 0.7248584032058716, + -0.30675002932548523, + 1.8586663007736206 + ], + [ + 1.375124216079712, + 0.564572811126709, + 0.24911366403102875, + 1.7303272485733032 + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "max_dim_-1_keepdim_True", + "op_name": "max", + "dim": -1, + "keepdim": true, + "input": [ + [ + [ + -0.9125152230262756, + 0.4803459644317627, + -0.41451194882392883, + -1.7112841606140137, + 0.3645228147506714 + ], + [ + -0.5803453326225281, + -0.7104259729385376, + -0.27301856875419617, + -0.6705332398414612, + 1.595921277999878 + ], + [ + 0.5219618082046509, + 0.34126174449920654, + 1.010899543762207, + -0.04691770300269127, + 0.2992815375328064 + ], + [ + -0.4206298589706421, + -1.9771111011505127, + -0.004498381167650223, + 0.023252639919519424, + -1.0357731580734253 + ] + ], + [ + [ + 0.6917201280593872, + -0.6789452433586121, + -0.9247362613677979, + -0.31068262457847595, + 0.2013172209262848 + ], + [ + 0.6645943522453308, + -1.7228929996490479, + -0.5210925936698914, + 0.060717396438121796, + 0.42114102840423584 + ], + [ + 1.0576668977737427, + 1.3254046440124512, + 0.07843684405088425, + -0.19520922005176544, + 0.7735913395881653 + ], + [ + 0.1407848447561264, + -0.2778305411338806, + 0.015577469952404499, + -0.9061261415481567, + -0.6032977104187012 + ] + ], + [ + [ + 0.7053933143615723, + -0.40017446875572205, + -3.028942346572876, + 0.26209768652915955, + 0.02327004447579384 + ], + [ + -0.6302129626274109, + 0.888484001159668, + 0.1747579276561737, + -2.0527801513671875, + 0.03855415806174278 + ], + [ + 1.213753581047058, + -0.08656994998455048, + -0.5959414839744568, + -1.8832926750183105, + 0.5548990964889526 + ], + [ + -0.9461650252342224, + -0.7394051551818848, + 0.7492458820343018, + -0.6058419346809387, + -0.384304404258728 + ] + ] + ], + "expected_output": [ + [ + [ + 0.4803459644317627 + ], + [ + 1.595921277999878 + ], + [ + 1.010899543762207 + ], + [ + 0.023252639919519424 + ] + ], + [ + [ + 0.6917201280593872 + ], + [ + 0.6645943522453308 + ], + [ + 1.3254046440124512 + ], + [ + 0.1407848447561264 + ] + ], + [ + [ + 0.7053933143615723 + ], + [ + 0.888484001159668 + ], + [ + 1.213753581047058 + ], + [ + 0.7492458820343018 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "min_dim_None_keepdim_False", + "op_name": "min", + "dim": null, + "keepdim": false, + "input": [ + [ + [ + 0.3851594030857086, + -0.3151880204677582, + 0.039046529680490494, + -0.17162249982357025, + -0.842478334903717 + ], + [ + 1.226798415184021, + 0.6258861422538757, + -0.021849583834409714, + -1.4504739046096802, + 0.8094747066497803 + ], + [ + -0.7144426107406616, + 0.7041144371032715, + -1.2723145484924316, + -0.713442862033844, + 0.23755493760108948 + ], + [ + 2.4901089668273926, + -0.9031432867050171, + -1.279140830039978, + -0.4034813344478607, + -0.6024842858314514 + ] + ], + [ + [ + -0.46980521082878113, + 0.5732667446136475, + -0.0040825954638421535, + 0.07298417389392853, + -0.6787295341491699 + ], + [ + -0.2703229784965515, + -0.15237197279930115, + 0.11046099662780762, + -0.9912855625152588, + -0.8878551721572876 + ], + [ + 1.3682804107666016, + 1.2855982780456543, + 1.5158559083938599, + 0.5367690324783325, + 1.7698261737823486 + ], + [ + 1.3941913843154907, + -0.4474734365940094, + -0.8029153347015381, + -0.9047854542732239, + -0.010661765933036804 + ] + ], + [ + [ + 0.4942079484462738, + -0.09941978752613068, + 0.5940057635307312, + 0.8259775638580322, + 0.1896892935037613 + ], + [ + -0.15840917825698853, + -1.5296630859375, + 1.0559983253479004, + 2.0524368286132812, + -0.3509976267814636 + ], + [ + -1.1978983879089355, + 0.5596528053283691, + 1.5097410678863525, + -0.40140989422798157, + 0.8937979340553284 + ], + [ + 0.8215998411178589, + 1.038364052772522, + 0.37289324402809143, + -1.419432282447815, + -0.2249353677034378 + ] + ] + ], + "expected_output": -1.5296630859375, + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "min_dim_0_keepdim_False", + "op_name": "min", + "dim": 0, + "keepdim": false, + "input": [ + [ + [ + 1.1369043588638306, + -0.9767837524414062, + -0.467501699924469, + -0.31253546476364136, + -2.420801877975464 + ], + [ + -0.6981193423271179, + -0.8373439908027649, + -0.4472923278808594, + 1.659290075302124, + -0.6820825934410095 + ], + [ + 0.4594089686870575, + -0.11755221337080002, + 0.058173540979623795, + -0.11270477622747421, + 0.6009398698806763 + ], + [ + 0.05460839346051216, + 1.5627477169036865, + -1.3852146863937378, + 1.388021469116211, + -0.41201210021972656 + ] + ], + [ + [ + 0.17847855389118195, + -0.4211631417274475, + 0.6745750904083252, + -1.7007237672805786, + -0.2912011444568634 + ], + [ + -1.4456785917282104, + 1.786425232887268, + 0.15301446616649628, + -0.35936856269836426, + -0.9645422697067261 + ], + [ + 0.8855559229850769, + -0.31540220975875854, + 0.08357129991054535, + -0.5507245063781738, + -1.8988375663757324 + ], + [ + -0.01925942301750183, + 0.29304513335227966, + 0.24341490864753723, + 2.0406532287597656, + -0.7569413781166077 + ] + ], + [ + [ + -0.16658450663089752, + -0.6370474696159363, + -0.4297468662261963, + 0.8156528472900391, + 1.2827181816101074 + ], + [ + 0.40247759222984314, + 1.5573612451553345, + 2.0378758907318115, + -0.11328133195638657, + -1.0065470933914185 + ], + [ + -0.6232604384422302, + 1.0608307123184204, + -1.0525683164596558, + 0.22322431206703186, + 1.0225255489349365 + ], + [ + 0.7757742404937744, + 0.645967423915863, + 0.7403110861778259, + 1.311670184135437, + -1.945209264755249 + ] + ] + ], + "expected_output": [ + [ + -0.16658450663089752, + -0.9767837524414062, + -0.467501699924469, + -1.7007237672805786, + -2.420801877975464 + ], + [ + -1.4456785917282104, + -0.8373439908027649, + -0.4472923278808594, + -0.35936856269836426, + -1.0065470933914185 + ], + [ + -0.6232604384422302, + -0.31540220975875854, + -1.0525683164596558, + -0.5507245063781738, + -1.8988375663757324 + ], + [ + -0.01925942301750183, + 0.29304513335227966, + -1.3852146863937378, + 1.311670184135437, + -1.945209264755249 + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 1.0, + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 1.0, + 1.0 + ], + [ + 1.0, + 1.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "min_dim_0_keepdim_True", + "op_name": "min", + "dim": 0, + "keepdim": true, + "input": [ + [ + [ + 0.4310223162174225, + -0.22314855456352234, + 0.04046724736690521, + 0.3553427457809448, + 1.9382938146591187 + ], + [ + -1.254912257194519, + 0.14595302939414978, + 0.2614082098007202, + 0.38991880416870117, + 0.40374335646629333 + ], + [ + -0.47906389832496643, + -0.5763978362083435, + -2.3239030838012695, + -0.28545263409614563, + 1.02093505859375 + ], + [ + 0.8959177732467651, + -2.674952745437622, + 0.185286283493042, + -1.3125312328338623, + -0.7755544781684875 + ] + ], + [ + [ + -0.09462077915668488, + -1.171595811843872, + 0.5055325031280518, + 0.37683606147766113, + -1.171151041984558 + ], + [ + 0.2559703290462494, + 0.4515315592288971, + -0.7774103879928589, + -2.5792624950408936, + 1.3327691555023193 + ], + [ + 0.8247588872909546, + 0.1895250678062439, + 0.13722558319568634, + 1.2756917476654053, + 0.4262869358062744 + ], + [ + 0.1224641352891922, + 0.5574866533279419, + 0.30463987588882446, + 0.5269746780395508, + 1.4476677179336548 + ] + ], + [ + [ + -0.1862286925315857, + -0.16418692469596863, + 0.5037822723388672, + 1.202155351638794, + -0.4691736400127411 + ], + [ + 3.5406761169433594, + -0.38007304072380066, + -0.2619936764240265, + -0.5226048827171326, + -0.42274436354637146 + ], + [ + 0.0772174745798111, + 1.6049801111221313, + -1.6840441226959229, + 0.6537221670150757, + 0.36240431666374207 + ], + [ + -1.1095906496047974, + 0.15686734020709991, + 0.6184999346733093, + 1.4835309982299805, + -0.26363199949264526 + ] + ] + ], + "expected_output": [ + [ + [ + -0.1862286925315857, + -1.171595811843872, + 0.04046724736690521, + 0.3553427457809448, + -1.171151041984558 + ], + [ + -1.254912257194519, + -0.38007304072380066, + -0.7774103879928589, + -2.5792624950408936, + -0.42274436354637146 + ], + [ + -0.47906389832496643, + -0.5763978362083435, + -2.3239030838012695, + -0.28545263409614563, + 0.36240431666374207 + ], + [ + -1.1095906496047974, + -2.674952745437622, + 0.185286283493042, + -1.3125312328338623, + -0.7755544781684875 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 1.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 1.0, + 1.0, + 1.0, + 0.0 + ], + [ + 0.0, + 1.0, + 1.0, + 1.0, + 1.0 + ] + ], + [ + [ + 0.0, + 1.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "min_dim_1_keepdim_False", + "op_name": "min", + "dim": 1, + "keepdim": false, + "input": [ + [ + [ + 0.391838014125824, + 0.27027666568756104, + -1.9761329889297485, + -0.6592251062393188, + -0.6763451099395752 + ], + [ + 0.07715956121683121, + -0.3971971273422241, + -0.3989383280277252, + -0.23806536197662354, + -0.38905683159828186 + ], + [ + -0.3005983531475067, + -0.04975222051143646, + 1.6682186126708984, + 0.7086811661720276, + 0.987306535243988 + ], + [ + -0.662408173084259, + -0.4409155547618866, + -1.6116207838058472, + 0.7781904339790344, + -0.865123450756073 + ] + ], + [ + [ + -0.41890090703964233, + 0.9132878184318542, + 0.2694464921951294, + 0.020374706014990807, + -0.9279459714889526 + ], + [ + -1.0296690464019775, + -1.044813632965088, + -0.8124385476112366, + 0.49416670203208923, + 1.2590702772140503 + ], + [ + 0.06191536784172058, + -1.3849509954452515, + 0.28555789589881897, + 0.27377936244010925, + -0.7898518443107605 + ], + [ + -0.42242521047592163, + 2.0086865425109863, + -0.6715307831764221, + -2.07552170753479, + -0.09107904881238937 + ] + ], + [ + [ + -1.6961005926132202, + -0.42137637734413147, + -1.1771284341812134, + -0.762600839138031, + -2.5596771240234375 + ], + [ + -0.4311526417732239, + 0.7832211852073669, + 0.27603602409362793, + 0.3852384686470032, + 0.8465394377708435 + ], + [ + 0.12128926813602448, + 0.44558772444725037, + -0.10837887972593307, + 0.9687615633010864, + -1.8719896078109741 + ], + [ + -0.5508694648742676, + 0.14841115474700928, + 0.6105049252510071, + -0.44323164224624634, + 1.2706385850906372 + ] + ] + ], + "expected_output": [ + [ + -0.662408173084259, + -0.4409155547618866, + -1.9761329889297485, + -0.6592251062393188, + -0.865123450756073 + ], + [ + -1.0296690464019775, + -1.3849509954452515, + -0.8124385476112366, + -2.07552170753479, + -0.9279459714889526 + ], + [ + -1.6961005926132202, + -0.42137637734413147, + -1.1771284341812134, + -0.762600839138031, + -2.5596771240234375 + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 1.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 1.0, + 0.0, + 0.0, + 1.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ] + ], + [ + [ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "min_dim_1_keepdim_True", + "op_name": "min", + "dim": 1, + "keepdim": true, + "input": [ + [ + [ + -1.0289336442947388, + 0.42619314789772034, + -1.3302918672561646, + -0.7120002508163452, + 1.0063550472259521 + ], + [ + 0.7243992686271667, + -0.7196370363235474, + 0.6451484560966492, + -0.8696923851966858, + -0.8558129668235779 + ], + [ + 0.10319733619689941, + 0.02185261994600296, + -0.6163969039916992, + -0.5053693056106567, + 0.353022038936615 + ], + [ + 0.4127030372619629, + -0.649102509021759, + 1.3514323234558105, + 0.1669526845216751, + 0.2536453902721405 + ] + ], + [ + [ + 0.9374377131462097, + 2.011122703552246, + -0.32855224609375, + 0.6405972242355347, + 1.2246845960617065 + ], + [ + 0.5188621282577515, + 0.43879711627960205, + -0.203304260969162, + -0.8538898825645447, + 2.200573205947876 + ], + [ + -0.02216072380542755, + 0.4223840832710266, + 1.257797122001648, + -0.5768603682518005, + -0.7109366059303284 + ], + [ + -0.7689208388328552, + -1.3047925233840942, + 0.5878376364707947, + 0.10670913010835648, + 0.1493469625711441 + ] + ], + [ + [ + -0.9368554949760437, + 0.11115618795156479, + -0.23906701803207397, + -0.18269838392734528, + -0.35426023602485657 + ], + [ + 1.3937491178512573, + -1.6012654304504395, + -0.9598016738891602, + 0.36583781242370605, + -0.7097951173782349 + ], + [ + -0.7645633816719055, + 0.19768379628658295, + -0.5498691201210022, + 0.25587576627731323, + 0.017203141003847122 + ], + [ + -0.47457176446914673, + 1.916212558746338, + -0.9796661734580994, + -0.5351609587669373, + -0.33613622188568115 + ] + ] + ], + "expected_output": [ + [ + [ + -1.0289336442947388, + -0.7196370363235474, + -1.3302918672561646, + -0.8696923851966858, + -0.8558129668235779 + ] + ], + [ + [ + -0.7689208388328552, + -1.3047925233840942, + -0.32855224609375, + -0.8538898825645447, + -0.7109366059303284 + ] + ], + [ + [ + -0.9368554949760437, + -1.6012654304504395, + -0.9796661734580994, + -0.5351609587669373, + -0.7097951173782349 + ] + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 1.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 1.0, + 0.0 + ] + ] + ] + }, + { + "test_name": "min_dim_-1_keepdim_False", + "op_name": "min", + "dim": -1, + "keepdim": false, + "input": [ + [ + [ + -1.1161184310913086, + 0.14304663240909576, + -0.32119596004486084, + 0.8723122477531433, + -0.49654293060302734 + ], + [ + 0.05724964290857315, + 0.47545480728149414, + -0.4795941412448883, + -1.4507311582565308, + -0.4242385923862457 + ], + [ + 0.4160293638706207, + 0.009711174294352531, + -0.23619726300239563, + -1.4613094329833984, + -0.3903917670249939 + ], + [ + -0.14734792709350586, + 1.1412599086761475, + 0.2379687875509262, + 2.7321791648864746, + -0.36258259415626526 + ] + ], + [ + [ + 0.48279520869255066, + 1.2329903841018677, + -0.7630826830863953, + -1.0484687089920044, + 1.5664156675338745 + ], + [ + -0.22833675146102905, + -0.4468657970428467, + -0.5083827376365662, + -0.3354898989200592, + 1.5477113723754883 + ], + [ + 0.6345664858818054, + -1.4856488704681396, + -0.8773688077926636, + -0.34968942403793335, + -0.6551162004470825 + ], + [ + -0.8283827304840088, + 0.4841196835041046, + 1.1001728773117065, + 0.45901453495025635, + 0.26477116346359253 + ] + ], + [ + [ + -1.5105466842651367, + -0.6389901041984558, + -1.726313591003418, + 0.36199653148651123, + 1.421317458152771 + ], + [ + -1.9939244985580444, + 0.07572164386510849, + -0.5763441920280457, + -0.5786607265472412, + -1.460897445678711 + ], + [ + 1.426108717918396, + 1.2192761898040771, + 1.2584720849990845, + -0.5713672637939453, + 0.7841975092887878 + ], + [ + 0.40953299403190613, + 0.3059408664703369, + -0.23000852763652802, + 0.5811874866485596, + -0.6039872765541077 + ] + ] + ], + "expected_output": [ + [ + -1.1161184310913086, + -1.4507311582565308, + -1.4613094329833984, + -0.36258259415626526 + ], + [ + -1.0484687089920044, + -0.5083827376365662, + -1.4856488704681396, + -0.8283827304840088 + ], + [ + -1.726313591003418, + -1.9939244985580444, + -0.5713672637939453, + -0.6039872765541077 + ] + ], + "expected_grad": [ + [ + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + ] + ] + }, + { + "test_name": "min_dim_-1_keepdim_True", + "op_name": "min", + "dim": -1, + "keepdim": true, + "input": [ + [ + [ + 0.3473411798477173, + -0.2978079319000244, + 0.2347842901945114, + -0.10979556292295456, + -1.323111653327942 + ], + [ + -1.7342220544815063, + 1.767889142036438, + -0.7062178254127502, + -0.7460381984710693, + 1.4306825399398804 + ], + [ + 1.9143685102462769, + -1.5510687828063965, + -1.430296540260315, + 0.2052573710680008, + 0.9466792941093445 + ], + [ + -1.166908860206604, + 0.6379362940788269, + 1.0802478790283203, + -1.2114757299423218, + 0.6006536483764648 + ] + ], + [ + [ + 0.07689109444618225, + -0.8847613334655762, + -0.7983061075210571, + 0.26852527260780334, + -1.751050591468811 + ], + [ + -0.028895698487758636, + -0.6638352870941162, + -1.484498143196106, + 0.0809166356921196, + -0.5466802716255188 + ], + [ + 0.3434705436229706, + 0.6989194750785828, + -1.3570187091827393, + -1.3314623832702637, + 0.5109858512878418 + ], + [ + -1.461991786956787, + 1.4522364139556885, + 1.4651625156402588, + 1.0964486598968506, + 0.831229567527771 + ] + ], + [ + [ + 0.061060722917318344, + -0.6163668632507324, + 1.015307068824768, + 0.595319926738739, + -0.008159872144460678 + ], + [ + -0.7545639276504517, + 2.069274663925171, + -0.17883431911468506, + 0.809699535369873, + -0.4801141619682312 + ], + [ + -0.6375554203987122, + 1.179660439491272, + -0.6031109094619751, + 1.404761552810669, + 0.22640825808048248 + ], + [ + 0.7069153189659119, + 0.660965621471405, + 0.4534458816051483, + -1.3935517072677612, + 0.6880179643630981 + ] + ] + ], + "expected_output": [ + [ + [ + -1.323111653327942 + ], + [ + -1.7342220544815063 + ], + [ + -1.5510687828063965 + ], + [ + -1.2114757299423218 + ] + ], + [ + [ + -1.751050591468811 + ], + [ + -1.484498143196106 + ], + [ + -1.3570187091827393 + ], + [ + -1.461991786956787 + ] + ], + [ + [ + -0.6163668632507324 + ], + [ + -0.7545639276504517 + ], + [ + -0.6375554203987122 + ], + [ + -1.3935517072677612 + ] + ] + ], + "expected_grad": [ + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ] + ], + [ + [ + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 1.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ] + ], + [ + [ + 0.0, + 1.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, + 1.0, + 0.0 + ] + ] + ] + } + ], "linear": [ { "test_name": "linear_2D_input", @@ -5852,232 +11890,232 @@ export const testData = { "out_features": 5, "input": [ [ - -1.4766337871551514, - 0.982934296131134, - 0.034095875918865204, - -0.461677223443985, - 0.3484693765640259, - 0.3648642897605896, - -0.029142292216420174, - 1.1481481790542603, - -1.35635244846344, - -1.0603324174880981 - ], - [ - 1.0654057264328003, - 0.8679789900779724, - -0.5582399368286133, - -1.7682260274887085, - -1.7561272382736206, - 1.4259073734283447, - 0.5127183794975281, - -0.4026731848716736, - 1.9770677089691162, - -0.030815819278359413 - ], - [ - -1.737373948097229, - 1.2176311016082764, - -0.5283262729644775, - -0.46433013677597046, - -0.15669254958629608, - -1.5964131355285645, - -1.5322294235229492, - -0.11408505588769913, - -0.9761450290679932, - 0.48647579550743103 + 1.1283513307571411, + -0.7886322736740112, + -0.038704462349414825, + 0.6835862398147583, + -0.427450567483902, + -0.7580193877220154, + 0.061286136507987976, + -0.5027238726615906, + -0.27131080627441406, + -0.9536606073379517 + ], + [ + -0.6736571192741394, + 1.259739637374878, + -0.23389844596385956, + -0.848857581615448, + -0.3439099192619324, + -0.7324386835098267, + -0.5639234185218811, + 0.04004557058215141, + -0.4779359698295593, + 2.1152544021606445 + ], + [ + -0.9166030287742615, + 0.21347090601921082, + 0.3113662600517273, + -0.5756134390830994, + 0.3273322880268097, + 0.6297365427017212, + 1.879461407661438, + -0.04444850981235504, + -0.5365133285522461, + 1.4397056102752686 ] ], "weight": [ [ - 0.3002844452857971, - 0.017805445939302444, - -0.027198705822229385, - -0.21463561058044434, - -0.15679782629013062, - -0.24376848340034485, - 0.25319355726242065, - -0.0515228807926178, - -0.2793583571910858, - 0.03392322361469269 - ], - [ - 0.022948073223233223, - -0.03906950727105141, - 0.11319813132286072, - 0.17006072402000427, - -0.29738378524780273, - -0.24225947260856628, - -0.015191554091870785, - -0.2931866943836212, - -0.2872485816478729, - 0.27920082211494446 - ], - [ - -0.02405211329460144, - -0.15633995831012726, - -0.10847145318984985, - -0.24688613414764404, - 0.24677330255508423, - -0.06857045739889145, - -0.17779526114463806, - -0.23983119428157806, - 0.18483199179172516, - -0.04371260479092598 - ], - [ - -0.0332220159471035, - -0.08241946250200272, - -0.1526503711938858, - 0.05625385046005249, - 0.2432962954044342, - -0.183279350399971, - 0.015151331201195717, - -0.24049542844295502, - -0.14827828109264374, - 0.27757522463798523 - ], - [ - 0.003315664827823639, - 0.3046282231807709, - -0.0554044172167778, - -0.17235811054706573, - -0.18894238770008087, - 0.280277281999588, - -0.24317501485347748, - 0.16595454514026642, - 0.07860860973596573, - 0.09332110732793808 + -0.014760938473045826, + -0.30939099192619324, + -0.22409461438655853, + -0.22140328586101532, + -0.10767091810703278, + -0.16022561490535736, + 0.048675112426280975, + 0.1933113932609558, + 0.2384445071220398, + 0.09963622689247131 + ], + [ + -0.002092500915750861, + -0.056352920830249786, + 0.2147195190191269, + -0.18111325800418854, + 0.22857233881950378, + -0.30446791648864746, + -0.23602305352687836, + 0.08388392627239227, + -0.1302446573972702, + 0.058998893946409225 + ], + [ + 0.2755293548107147, + 0.1444312036037445, + 0.3095139265060425, + -0.13394437730312347, + -0.15100832283496857, + -0.04015190899372101, + -0.06368821114301682, + -0.13909903168678284, + -0.01963338814675808, + 0.2856864631175995 + ], + [ + -0.17334267497062683, + 0.1775881052017212, + 0.14690226316452026, + 0.18313315510749817, + 0.08531231433153152, + -0.11681929230690002, + 0.13051147758960724, + -0.14894190430641174, + -0.19410604238510132, + 0.29560813307762146 + ], + [ + 0.26211726665496826, + -0.2285388559103012, + 0.25685709714889526, + 0.06557296216487885, + 0.081057608127594, + 0.304801344871521, + -0.01660444773733616, + -0.10057568550109863, + 0.19852009415626526, + -0.08168602734804153 ] ], "bias": [ - 0.17842835187911987, - -0.0827324241399765, - 0.1956702172756195, - -0.2519457936286926, - -0.1112619936466217 + -0.0759141594171524, + -0.12752050161361694, + 0.3112594485282898, + 0.15089142322540283, + -0.05126401409506798 ], "expected_output": [ [ - -0.016492903232574463, - -0.664310097694397, - -0.22575607895851135, - -0.6669389009475708, - 0.2894335091114044 + -0.07768147438764572, + -0.16203129291534424, + 0.29859665036201477, + -0.15953725576400757, + 0.2675035297870636 ], [ - 0.4334893524646759, - -0.7455325126647949, - 0.3724954128265381, - -1.2588322162628174, - 1.1848678588867188 + 0.016104310750961304, + 0.37431609630584717, + 1.074267864227295, + 0.9962825179100037, + -1.1449365615844727 ], [ - 0.11328274011611938, - 0.5973459482192993, - 0.3879339098930359, - 0.2984088063240051, - 0.2677045166492462 + -0.10849833488464355, + -0.3759457468986511, + 0.49661877751350403, + 1.024014949798584, + -0.33044812083244324 ] ], "expected_grad_input": [ [ - 0.2692740559577942, - 0.044604748487472534, - -0.23052680492401123, - -0.40756529569625854, - -0.1530544012784958, - -0.45760050415992737, - -0.16781693696975708, - -0.6590816378593445, - -0.4514445960521698, - 0.6403077244758606 - ], - [ - 0.2692740559577942, - 0.044604748487472534, - -0.23052680492401123, - -0.40756529569625854, - -0.1530544012784958, - -0.45760050415992737, - -0.16781693696975708, - -0.6590816378593445, - -0.4514445960521698, - 0.6403077244758606 - ], - [ - 0.2692740559577942, - 0.044604748487472534, - -0.23052680492401123, - -0.40756529569625854, - -0.1530544012784958, - -0.45760050415992737, - -0.16781693696975708, - -0.6590816378593445, - -0.4514445960521698, - 0.6403077244758606 + 0.34745049476623535, + -0.27226346731185913, + 0.7038981914520264, + -0.28775477409362793, + 0.13626301288604736, + -0.31686341762542725, + -0.13712912797927856, + -0.11142130196094513, + 0.09298050403594971, + 0.6582436561584473 + ], + [ + 0.34745049476623535, + -0.27226346731185913, + 0.7038981914520264, + -0.28775477409362793, + 0.13626301288604736, + -0.31686341762542725, + -0.13712912797927856, + -0.11142130196094513, + 0.09298050403594971, + 0.6582436561584473 + ], + [ + 0.34745049476623535, + -0.27226346731185913, + 0.7038981914520264, + -0.28775477409362793, + 0.13626301288604736, + -0.31686341762542725, + -0.13712912797927856, + -0.11142130196094513, + 0.09298050403594971, + 0.6582436561584473 ] ], "expected_grad_weight": [ [ - -2.14860200881958, - 3.068544387817383, - -1.052470326423645, - -2.6942334175109863, - -1.5643503665924072, - 0.19435858726501465, - -1.0486533641815186, - 0.6313899159431458, - -0.3554297685623169, - -0.6046724319458008 - ], - [ - -2.14860200881958, - 3.068544387817383, - -1.052470326423645, - -2.6942334175109863, - -1.5643503665924072, - 0.19435858726501465, - -1.0486533641815186, - 0.6313899159431458, - -0.3554297685623169, - -0.6046724319458008 - ], - [ - -2.14860200881958, - 3.068544387817383, - -1.052470326423645, - -2.6942334175109863, - -1.5643503665924072, - 0.19435858726501465, - -1.0486533641815186, - 0.6313899159431458, - -0.3554297685623169, - -0.6046724319458008 - ], - [ - -2.14860200881958, - 3.068544387817383, - -1.052470326423645, - -2.6942334175109863, - -1.5643503665924072, - 0.19435858726501465, - -1.0486533641815186, - 0.6313899159431458, - -0.3554297685623169, - -0.6046724319458008 - ], - [ - -2.14860200881958, - 3.068544387817383, - -1.052470326423645, - -2.6942334175109863, - -1.5643503665924072, - 0.19435858726501465, - -1.0486533641815186, - 0.6313899159431458, - -0.3554297685623169, - -0.6046724319458008 + -0.46190881729125977, + 0.6845782995223999, + 0.038763344287872314, + -0.7408847808837891, + -0.44402822852134705, + -0.8607214689254761, + 1.376824140548706, + -0.5071268081665039, + -1.2857601642608643, + 2.601299285888672 + ], + [ + -0.46190881729125977, + 0.6845782995223999, + 0.038763344287872314, + -0.7408847808837891, + -0.44402822852134705, + -0.8607214689254761, + 1.376824140548706, + -0.5071268081665039, + -1.2857601642608643, + 2.601299285888672 + ], + [ + -0.46190881729125977, + 0.6845782995223999, + 0.038763344287872314, + -0.7408847808837891, + -0.44402822852134705, + -0.8607214689254761, + 1.376824140548706, + -0.5071268081665039, + -1.2857601642608643, + 2.601299285888672 + ], + [ + -0.46190881729125977, + 0.6845782995223999, + 0.038763344287872314, + -0.7408847808837891, + -0.44402822852134705, + -0.8607214689254761, + 1.376824140548706, + -0.5071268081665039, + -1.2857601642608643, + 2.601299285888672 + ], + [ + -0.46190881729125977, + 0.6845782995223999, + 0.038763344287872314, + -0.7408847808837891, + -0.44402822852134705, + -0.8607214689254761, + 1.376824140548706, + -0.5071268081665039, + -1.2857601642608643, + 2.601299285888672 ] ], "expected_grad_bias": [ @@ -6095,147 +12133,147 @@ export const testData = { "input": [ [ [ - -0.9297109842300415, - -0.8541247248649597, - 0.15929833054542542, - -0.41023650765419006 + 0.648219883441925, + 1.850017786026001, + -0.8941981196403503, + 1.5534266233444214 ], [ - -0.7588294148445129, - 1.6981608867645264, - 0.7436892986297607, - -0.03276701644062996 + 0.17955924570560455, + -1.1150798797607422, + -0.9356100559234619, + -0.41874298453330994 ], [ - -1.0194525718688965, - 0.3848164975643158, - 0.29434895515441895, - 0.6351331472396851 + -0.20334042608737946, + -1.6620466709136963, + 0.8806517720222473, + 0.34086135029792786 ] ], [ [ - 0.20356419682502747, - -0.18102435767650604, - -0.9300417900085449, - 0.4725607931613922 + -0.9606906771659851, + -0.8203177452087402, + 1.1280782222747803, + 1.5793778896331787 ], [ - 0.6600029468536377, - -0.16193436086177826, - 0.886084258556366, - 1.8162529468536377 + -1.171597957611084, + 1.6002179384231567, + -0.3856680691242218, + 1.3663055896759033 ], [ - 0.20681823790073395, - 0.11982676386833191, - 0.9609657526016235, - -1.2074177265167236 + -1.4047266244888306, + -0.5991130471229553, + -1.49435293674469, + 1.004637360572815 ] ] ], "weight": [ [ - 0.09339135885238647, - -0.35572314262390137, - 0.1539331078529358, - 0.08821696043014526 + 0.05675828456878662, + -0.4988272786140442, + 0.00441056489944458, + 0.38382667303085327 ], [ - 0.011232852935791016, - -0.34186333417892456, - -0.3030986189842224, - 0.3695688247680664 + 0.05767112970352173, + 0.11913007497787476, + -0.4709845185279846, + -0.09404438734054565 ] ], "bias": [ - 0.24350953102111816, - 0.26361989974975586 + 0.29504191875457764, + -0.3666014075279236 ], "expected_output": [ [ [ - 0.4488459527492523, - 0.34527677297592163 + 0.0012971162796020508, + 0.16623735427856445 ], [ - -0.31984591484069824, - -0.5629637837409973 + 0.6966143846511841, + -0.009047269821166992 ], [ - 0.11275289952754974, - 0.2661225497722626 + 1.2472907304763794, + -1.0231574773788452 ] ], [ [ - 0.22543887794017792, - 0.7843302488327026 + 1.2608944177627563, + -1.1995689868927002 ], [ - 0.659373939037323, - 0.7290526032447815 + -0.04696476459503174, + -0.1903843879699707 ], [ - 0.26160913705825806, - -0.5125126838684082 + 0.8931816816329956, + 0.09035056829452515 ] ] ], "expected_grad_input": [ [ [ - 0.10462421178817749, - -0.6975864768028259, - -0.14916551113128662, - 0.45778578519821167 + 0.11442941427230835, + -0.37969720363616943, + -0.46657395362854004, + 0.2897822856903076 ], [ - 0.10462421178817749, - -0.6975864768028259, - -0.14916551113128662, - 0.45778578519821167 + 0.11442941427230835, + -0.37969720363616943, + -0.46657395362854004, + 0.2897822856903076 ], [ - 0.10462421178817749, - -0.6975864768028259, - -0.14916551113128662, - 0.45778578519821167 + 0.11442941427230835, + -0.37969720363616943, + -0.46657395362854004, + 0.2897822856903076 ] ], [ [ - 0.10462421178817749, - -0.6975864768028259, - -0.14916551113128662, - 0.45778578519821167 + 0.11442941427230835, + -0.37969720363616943, + -0.46657395362854004, + 0.2897822856903076 ], [ - 0.10462421178817749, - -0.6975864768028259, - -0.14916551113128662, - 0.45778578519821167 + 0.11442941427230835, + -0.37969720363616943, + -0.46657395362854004, + 0.2897822856903076 ], [ - 0.10462421178817749, - -0.6975864768028259, - -0.14916551113128662, - 0.45778578519821167 + 0.11442941427230835, + -0.37969720363616943, + -0.46657395362854004, + 0.2897822856903076 ] ] ], "expected_grad_weight": [ [ - -1.6376075744628906, - 1.005720853805542, - 2.114344835281372, - 1.2735257148742676 + -2.91257643699646, + -0.7463215589523315, + -1.701099157333374, + 5.425865650177002 ], [ - -1.6376075744628906, - 1.005720853805542, - 2.114344835281372, - 1.2735257148742676 + -2.91257643699646, + -0.7463215589523315, + -1.701099157333374, + 5.425865650177002 ] ], "expected_grad_bias": [ @@ -6254,69 +12292,69 @@ export const testData = { "initial_weight": [ [ -0.5548203587532043, - 0.14430466294288635, - -0.8963656425476074 + -0.16434448957443237, + -0.4784829616546631 ], [ - -1.85586416721344, - 1.925358533859253, - -0.1502695381641388 + 0.38463443517684937, + -0.3245149850845337, + -1.5829708576202393 ], [ - -0.4557262361049652, - 0.38499918580055237, - 0.8224982619285583 + -0.6101211309432983, + 0.2677954137325287, + 1.1987781524658203 ] ], "input_x": [ [ - 1.127738356590271, - -0.21481071412563324, - -0.2161199003458023 + 1.122973918914795, + 1.4562538862228394, + 0.9092239141464233 ], [ - -1.7219769954681396, - -1.4746582508087158, - -1.0435383319854736 + 0.9442354440689087, + 2.31821870803833, + 0.64822918176651 ], [ - -1.0349572896957397, - 0.3165971040725708, - -0.7668118476867676 + -0.4594375491142273, + 0.8558579683303833, + 1.3270264863967896 ] ], "expected_grad": [ [ - 1.127738356590271, - -0.21481071412563324, - -0.2161199003458023 + 1.122973918914795, + 1.4562538862228394, + 0.9092239141464233 ], [ - -1.7219769954681396, - -1.4746582508087158, - -1.0435383319854736 + 0.9442354440689087, + 2.31821870803833, + 0.64822918176651 ], [ - -1.0349572896957397, - 0.3165971040725708, - -0.7668118476867676 + -0.4594375491142273, + 0.8558579683303833, + 1.3270264863967896 ] ], "expected_updated_weight": [ [ - -0.6675941944122314, - 0.16578572988510132, - -0.8747536540031433 + -0.6671177744865417, + -0.30996987223625183, + -0.5694053769111633 ], [ - -1.683666467666626, - 2.072824478149414, - -0.04591570422053337 + 0.29021090269088745, + -0.5563368797302246, + -1.6477937698364258 ], [ - -0.3522305190563202, - 0.35333946347236633, - 0.8991794586181641 + -0.564177393913269, + 0.18220961093902588, + 1.0660754442214966 ] ] }, @@ -6329,70 +12367,70 @@ export const testData = { }, "initial_weight": [ [ - 1.5292918682098389, - -0.6345059275627136, - -0.375550776720047 + 0.9446682333946228, + -0.30597713589668274, + 0.44008857011795044 ], [ - -0.7360644340515137, - 2.3721323013305664, - -1.2406166791915894 + -0.17014701664447784, + 0.12107481062412262, + 0.10815810412168503 ], [ - 0.8873314261436462, - -0.26175713539123535, - 1.0236345529556274 + 0.5580024719238281, + -1.8953827619552612, + 0.12464731931686401 ] ], "input_x": [ [ - -0.7798894047737122, - -0.05700850114226341, - 0.49562183022499084 + -0.3046552538871765, + -0.7077358961105347, + -1.7160437107086182 ], [ - -1.8779617547988892, - 0.033319782465696335, - -0.5396625995635986 + -0.5965784788131714, + -0.6017999053001404, + 0.8372399806976318 ], [ - -0.3761339783668518, - 1.3337057828903198, - -1.753574252128601 + -0.5020561218261719, + -0.10574329644441605, + -0.16421273350715637 ] ], "expected_grad": [ [ - -0.7798894047737122, - -0.05700850114226341, - 0.49562183022499084 + -0.3046552538871765, + -0.7077358961105347, + -1.7160437107086182 ], [ - -1.8779617547988892, - 0.033319782465696335, - -0.5396625995635986 + -0.5965784788131714, + -0.6017999053001404, + 0.8372399806976318 ], [ - -0.3761339783668518, - 1.3337057828903198, - -1.753574252128601 + -0.5020561218261719, + -0.10574329644441605, + -0.16421273350715637 ] ], "expected_updated_weight": [ [ - 1.6072808504104614, - -0.6288051009178162, - -0.4251129627227783 + 0.9751337766647339, + -0.2352035492658615, + 0.6116929650306702 ], [ - -0.5482682585716248, - 2.368800401687622, - -1.1866503953933716 + -0.11048916727304459, + 0.1812548041343689, + 0.024434104561805725 ], [ - 0.9249448180198669, - -0.39512771368026733, - 1.1989920139312744 + 0.6082080602645874, + -1.8848084211349487, + 0.14106859266757965 ] ] }, @@ -6404,70 +12442,70 @@ export const testData = { }, "initial_weight": [ [ - 1.6819236278533936, - -0.15222187340259552, - 1.3899450302124023 + -0.7310932874679565, + 0.3742406666278839, + 0.07989589124917984 ], [ - -0.8099237084388733, - -0.39533430337905884, - 0.494835764169693 + 0.8226869702339172, + 0.528905987739563, + 0.3527827858924866 ], [ - 1.198076844215393, - -2.5727944374084473, - -0.08748100697994232 + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ] ], "input_x": [ [ - 0.6722773313522339, - 0.21969778835773468, - 0.8142342567443848 + -1.4255669116973877, + 0.8732106685638428, + -2.0518009662628174 ], [ - 0.510215699672699, - -1.0645642280578613, - -1.035934567451477 + -0.9301124811172485, + 0.7590786218643188, + -0.012546157464385033 ], [ - 1.0930753946304321, - -0.06202443689107895, - 0.1334656924009323 + -0.16888298094272614, + -0.7453446984291077, + -1.6509697437286377 ] ], "expected_grad": [ [ - 0.6722773313522339, - 0.21969778835773468, - 0.8142342567443848 + -1.4255669116973877, + 0.8732106685638428, + -2.0518009662628174 ], [ - 0.510215699672699, - -1.0645642280578613, - -1.035934567451477 + -0.9301124811172485, + 0.7590786218643188, + -0.012546157464385033 ], [ - 1.0930753946304321, - -0.06202443689107895, - 0.1334656924009323 + -0.16888298094272614, + -0.7453446984291077, + -1.6509697437286377 ] ], "expected_updated_weight": [ [ - 1.5819236040115356, - -0.25222185254096985, - 1.2899450063705444 + -0.6310932636260986, + 0.2742406725883484, + 0.17989589273929596 ], [ - -0.9099236726760864, - -0.2953343093395233, - 0.5948357582092285 + 0.9226869344711304, + 0.42890599370002747, + 0.45278269052505493 ], [ - 1.0980768203735352, - -2.472794532775879, - -0.18748098611831665 + -0.3038589358329773, + 0.5434445738792419, + -0.5249487161636353 ] ] }, @@ -6483,70 +12521,347 @@ export const testData = { }, "initial_weight": [ [ - -1.495338797569275, - -0.13971441984176636, - 0.5186095833778381 + 0.06193928048014641, + -1.7777185440063477, + -0.5515789985656738 ], [ - -0.27415627241134644, - -1.863209843635559, - 0.7076565027236938 + 0.45636066794395447, + -0.9359204769134521, + 0.031871069222688675 ], [ - 0.8178618550300598, - 1.4021011590957642, - 0.9863149523735046 + 0.12983688712120056, + -0.07866957783699036, + -0.38718998432159424 ] ], "input_x": [ [ - 1.3463093042373657, - -1.6255258321762085, - -0.4336149990558624 + 0.43904364109039307, + -0.7205687761306763, + -0.5494226813316345 ], [ - 0.3167438805103302, - 0.23875612020492554, - -0.08424656093120575 + 1.25302255153656, + -1.1181309223175049, + 0.7164333462715149 ], [ - -2.0689682960510254, - -0.5692359209060669, - -0.07368183881044388 + -0.858248770236969, + 0.20800915360450745, + 0.880598783493042 ] ], "expected_grad": [ [ - 1.3463093042373657, - -1.6255258321762085, - -0.4336149990558624 + 0.43904364109039307, + -0.7205687761306763, + -0.5494226813316345 ], [ - 0.3167438805103302, - 0.23875612020492554, - -0.08424656093120575 + 1.25302255153656, + -1.1181309223175049, + 0.7164333462715149 ], [ - -2.0689682960510254, - -0.5692359209060669, - -0.07368183881044388 + -0.858248770236969, + 0.20800915360450745, + 0.880598783493042 ] ], "expected_updated_weight": [ [ - -1.5953388214111328, - -0.039714425802230835, - 0.6186095476150513 + -0.038060713559389114, + -1.6777185201644897, + -0.4515790045261383 + ], + [ + 0.35636067390441895, + -0.835920512676239, + -0.06812892854213715 + ], + [ + 0.22983688116073608, + -0.17866957187652588, + -0.48718997836112976 + ] + ] + } + ], + "expand": [ + { + "test_name": "expand_1D_expand", + "input": [ + 1.2542186975479126 + ], + "expand_shape": [ + 3 + ], + "expected_output": [ + 1.2542186975479126, + 1.2542186975479126, + 1.2542186975479126 + ], + "expected_grad": [ + 3.0 + ] + }, + { + "test_name": "expand_prepend_2D", + "input": [ + 0.13348865509033203, + 0.39146795868873596, + 0.9119104146957397 + ], + "expand_shape": [ + 2, + 3 + ], + "expected_output": [ + [ + 0.13348865509033203, + 0.39146795868873596, + 0.9119104146957397 + ], + [ + 0.13348865509033203, + 0.39146795868873596, + 0.9119104146957397 + ] + ], + "expected_grad": [ + 2.0, + 2.0, + 2.0 + ] + }, + { + "test_name": "expand_expand_dim_0", + "input": [ + [ + -0.17490753531455994, + -0.37665173411369324, + -0.9659009575843811 + ] + ], + "expand_shape": [ + 4, + 3 + ], + "expected_output": [ + [ + -0.17490753531455994, + -0.37665173411369324, + -0.9659009575843811 + ], + [ + -0.17490753531455994, + -0.37665173411369324, + -0.9659009575843811 + ], + [ + -0.17490753531455994, + -0.37665173411369324, + -0.9659009575843811 + ], + [ + -0.17490753531455994, + -0.37665173411369324, + -0.9659009575843811 + ] + ], + "expected_grad": [ + [ + 4.0, + 4.0, + 4.0 + ] + ] + }, + { + "test_name": "expand_expand_middle_dim", + "input": [ + [ + [ + 0.9704499244689941, + 0.2379537969827652, + -0.7329998016357422, + -0.7835293412208557 + ] + ], + [ + [ + 0.41817715764045715, + -0.9935426712036133, + 0.88087397813797, + -0.38332679867744446 + ] + ] + ], + "expand_shape": [ + 2, + 5, + 4 + ], + "expected_output": [ + [ + [ + 0.9704499244689941, + 0.2379537969827652, + -0.7329998016357422, + -0.7835293412208557 + ], + [ + 0.9704499244689941, + 0.2379537969827652, + -0.7329998016357422, + -0.7835293412208557 + ], + [ + 0.9704499244689941, + 0.2379537969827652, + -0.7329998016357422, + -0.7835293412208557 + ], + [ + 0.9704499244689941, + 0.2379537969827652, + -0.7329998016357422, + -0.7835293412208557 + ], + [ + 0.9704499244689941, + 0.2379537969827652, + -0.7329998016357422, + -0.7835293412208557 + ] + ], + [ + [ + 0.41817715764045715, + -0.9935426712036133, + 0.88087397813797, + -0.38332679867744446 + ], + [ + 0.41817715764045715, + -0.9935426712036133, + 0.88087397813797, + -0.38332679867744446 + ], + [ + 0.41817715764045715, + -0.9935426712036133, + 0.88087397813797, + -0.38332679867744446 + ], + [ + 0.41817715764045715, + -0.9935426712036133, + 0.88087397813797, + -0.38332679867744446 + ], + [ + 0.41817715764045715, + -0.9935426712036133, + 0.88087397813797, + -0.38332679867744446 + ] + ] + ], + "expected_grad": [ + [ + [ + 5.0, + 5.0, + 5.0, + 5.0 + ] ], [ - -0.37415626645088196, - -1.963209867477417, - 0.807656466960907 + [ + 5.0, + 5.0, + 5.0, + 5.0 + ] + ] + ] + }, + { + "test_name": "expand_preserve_with_negative_one", + "input": [ + [ + [ + 0.5941327810287476 + ], + [ + -0.8920964002609253 + ], + [ + 0.6283209323883057 + ] + ] + ], + "expand_shape": [ + 2, + -1, + 4 + ], + "expected_output": [ + [ + [ + 0.5941327810287476, + 0.5941327810287476, + 0.5941327810287476, + 0.5941327810287476 + ], + [ + -0.8920964002609253, + -0.8920964002609253, + -0.8920964002609253, + -0.8920964002609253 + ], + [ + 0.6283209323883057, + 0.6283209323883057, + 0.6283209323883057, + 0.6283209323883057 + ] ], [ - 0.9178618788719177, - 1.502101182937622, - 1.0863149166107178 + [ + 0.5941327810287476, + 0.5941327810287476, + 0.5941327810287476, + 0.5941327810287476 + ], + [ + -0.8920964002609253, + -0.8920964002609253, + -0.8920964002609253, + -0.8920964002609253 + ], + [ + 0.6283209323883057, + 0.6283209323883057, + 0.6283209323883057, + 0.6283209323883057 + ] + ] + ], + "expected_grad": [ + [ + [ + 8.0 + ], + [ + 8.0 + ], + [ + 8.0 + ] ] ] } From 6d0397cb577d53bfbbd90e848503839ede4a9b95 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 9 Mar 2026 00:21:19 +0800 Subject: [PATCH 082/128] fix: auto test sanity check --- .github/workflows/verify-generated-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify-generated-tests.yml b/.github/workflows/verify-generated-tests.yml index 90689149..2f3521d4 100644 --- a/.github/workflows/verify-generated-tests.yml +++ b/.github/workflows/verify-generated-tests.yml @@ -34,13 +34,13 @@ jobs: - name: Sanity Check Generated File Length run: | # 1. Count lines of the file currently checked into Git - COMMITTED_LINES=$(wc -l < test/tensor_ops_data.gen.js) + COMMITTED_LINES=$(wc -l < test/testcases.gen.js) # 2. Regenerate the file using your script yarn update-tests # 3. Count lines of the newly generated file - GENERATED_LINES=$(wc -l < test/tensor_ops_data.gen.js) + GENERATED_LINES=$(wc -l < test/testcases.gen.js) # 4. Compare and fail if different if [ "$COMMITTED_LINES" -ne "$GENERATED_LINES" ]; then From a7981cbf682886cd586272f901635894776b3fbd Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 9 Mar 2026 00:28:25 +0800 Subject: [PATCH 083/128] fix: visibility --- src/functions/ops.ts | 14 +++++++------- src/tensor.ts | 9 +++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 351863e2..1aeac024 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -122,7 +122,7 @@ function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = ); } -export class PowInt extends TorchFunction { +class PowInt extends TorchFunction { private n: number; protected _forward(a: Tensor, n: number): Tensor { if (a.requires_grad) { @@ -210,7 +210,7 @@ const Reciprocal = UnaryFunctionMixin( "reciprocal" ); -export class Reshape extends TorchFunction { +class Reshape extends TorchFunction { protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); const target_length = shape.reduce((acc, val) => acc * val, 1); @@ -244,7 +244,7 @@ export class Reshape extends TorchFunction { } registerOperation('reshape', Reshape); -export class Squeeze extends TorchFunction { +class Squeeze extends TorchFunction { protected _forward(a: Tensor, dim?: number) { if (a.requires_grad) { this.saved_tensors = [a]; @@ -289,7 +289,7 @@ export class Squeeze extends TorchFunction { } registerOperation('squeeze', Squeeze); -export class Unsqueeze extends TorchFunction { +class Unsqueeze extends TorchFunction { protected _forward(a: Tensor, dim: number) { if (a.requires_grad) { this.saved_tensors = [a]; @@ -323,7 +323,7 @@ export class Unsqueeze extends TorchFunction { } registerOperation('unsqueeze', Unsqueeze); -export class Expand extends TorchFunction { +class Expand extends TorchFunction { protected _forward(a: Tensor, expanded_shape: number[]): Tensor { if (a.requires_grad) { this.saved_tensors = [a]; @@ -491,7 +491,7 @@ function _transpose_tensor( { operation: operation, shape: output_shape } ); } -export class Transpose extends TorchFunction { +class Transpose extends TorchFunction { private dim0: number; private dim1: number; protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { @@ -579,7 +579,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = ), shape_after_removing_extra_dims]; } -export class Matmul extends BinaryFunction { +class Matmul extends BinaryFunction { private shape: number[]; protected _forward(a: Tensor, b: Tensor): Tensor { diff --git a/src/tensor.ts b/src/tensor.ts index 29ab0a76..6246c375 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -51,12 +51,13 @@ export class Tensor { // Optional user-defined name public name: string | null = null; - data: number[]; - _shape: number[]; - grad_fn: TorchFunction | null = null; + public data: number[]; + public grad_fn: TorchFunction | null = null; public grad: Tensor | null = null; + + public requires_grad: boolean; - requires_grad: boolean; + private _shape: number[]; constructor( data: NestedNumberArray, From 9ba720917990898b8faf7c93998d41c94296466f Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 9 Mar 2026 00:33:26 +0800 Subject: [PATCH 084/128] feat: make shape public --- src/tensor.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/tensor.ts b/src/tensor.ts index 6246c375..273f9ea7 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -52,12 +52,12 @@ export class Tensor { public name: string | null = null; public data: number[]; + + public shape: number[]; public grad_fn: TorchFunction | null = null; public grad: Tensor | null = null; - - public requires_grad: boolean; - private _shape: number[]; + public requires_grad: boolean; constructor( data: NestedNumberArray, @@ -71,7 +71,7 @@ export class Tensor { this.name = options.name; } - this._shape = internal_options.shape ?? _get_shape(data); + this.shape = internal_options.shape ?? _get_shape(data); this.grad_fn = internal_options.operation ?? null; if (this.requires_grad && !this.grad_fn) { @@ -81,10 +81,6 @@ export class Tensor { } } - get shape(): number[] { - return this._shape; - } - toArray_(): void { return; } @@ -124,10 +120,6 @@ export class Tensor { return this.data.length; } - set shape(shape: number[]) { - this._shape = shape; - } - private _executeUnaryOp(opName: string): Tensor { const operation = this.requires_grad ? new (getOperation(opName))() : getOperationCache(opName); return operation.forward(this); From fadb58ef20064526b7b8ace144a5767811616342 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 9 Mar 2026 00:36:26 +0800 Subject: [PATCH 085/128] fix: export types for docs --- src/index.ts | 2 +- src/tensor.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 33e11617..a5815378 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export { Tensor } from './tensor'; +export * from './tensor'; export { TorchFunction, AccumulateGrad } from './functions/base'; export * from './functions/ops'; diff --git a/src/tensor.ts b/src/tensor.ts index 273f9ea7..328da56d 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -8,7 +8,7 @@ import { getNextId, eventBus, events } from './util'; * - Add support for Textures to be stored in Tensors */ -type TypedArray = +export type TypedArray = | Int8Array | Uint8Array | Uint8ClampedArray From bac9873e0a2fca9c03decdc46090f7ab09a2e268 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 9 Mar 2026 16:22:13 +0800 Subject: [PATCH 086/128] feat: keep constructor.name in mixin --- src/functions/mixin.ts | 220 +++++++++++++++++++++++------------------ 1 file changed, 122 insertions(+), 98 deletions(-) diff --git a/src/functions/mixin.ts b/src/functions/mixin.ts index 047bcb6e..5472360a 100644 --- a/src/functions/mixin.ts +++ b/src/functions/mixin.ts @@ -15,7 +15,14 @@ export function BinaryFunctionMixin( backward_operations: (a, b, aFn, bFn, dz) => void, opName: string | null = null ): typeof BinaryFunction { - const kernel = (a: number[], as: number[], b: number[], bs: number[], bcs: number[], output_size: number) => { + const kernel = ( + a: number[], + as: number[], + b: number[], + bs: number[], + bcs: number[], + output_size: number + ) => { const res = Array(output_size); for (let x = 0; x < output_size; x++) { const a_index = _get_original_index(as, bcs, x); @@ -23,7 +30,7 @@ export function BinaryFunctionMixin( res[x] = operation(a, b, a_index, b_index); } return res; - } + }; const forward_tensor = (a: Tensor, b: Tensor, operation: TorchFunction | null = null): Tensor => { const broadcast_shape = _broadcast_shape(a.shape, b.shape); @@ -33,29 +40,38 @@ export function BinaryFunctionMixin( const output_size = broadcast_shape.reduce((acc, val) => acc * val, 1); return new Tensor( - kernel(a.data, padded_a_shape, b.data, padded_b_shape, broadcast_shape, output_size) as number[], + kernel( + a.data, + padded_a_shape, + b.data, + padded_b_shape, + broadcast_shape, + output_size + ) as number[], { requires_grad: a.requires_grad || b.requires_grad }, { operation: operation, shape: broadcast_shape } ); - } + }; - const result = class extends BinaryFunction { - protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { - this.saved_tensors = [a, b]; + const result = { + [opName]: class extends BinaryFunction { + protected _forward(a: Tensor, b: Tensor): Tensor { + if (a.requires_grad || b.requires_grad) { + this.saved_tensors = [a, b]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); + return forward_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return forward_tensor(a, b, a.requires_grad || b.requires_grad ? this : null) - } - protected _backward(dz: Tensor): void { - const [a, b] = this.saved_tensors; - const [aFn, bFn] = this.next_functions; + protected _backward(dz: Tensor): void { + const [a, b] = this.saved_tensors; + const [aFn, bFn] = this.next_functions; - backward_operations(a, b, aFn, bFn, dz); + backward_operations(a, b, aFn, bFn, dz); + } } - } + }[opName]; if (opName) { registerOperation(opName, result); } @@ -82,24 +98,26 @@ export function UnaryFunctionMixin( { requires_grad: a.requires_grad }, { operation: operation, shape: a.shape } ); - } + }; - const result = class extends UnaryFunction { - protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { - this.saved_tensors = [a]; + const result = { + [opName]: class extends UnaryFunction { + protected _forward(a: Tensor): Tensor { + if (a.requires_grad) { + this.saved_tensors = [a]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + return forward_tensor(a, a.requires_grad ? this : null); } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return forward_tensor(a, a.requires_grad ? this : null) - } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; - backward_operations(a, aFn, dz); + backward_operations(a, aFn, dz); + } } - } + }[opName]; if (opName) { registerOperation(opName, result); } @@ -109,92 +127,98 @@ export function UnaryFunctionMixin( export function ReductionFunctionMixin( init_val: number, reduce_op: (acc: number, val: number) => number, - backward_operations: (a: Tensor, restored_dz: Tensor, dim: number | number[], keepdim: boolean) => Tensor, // Simplified signature! + backward_operations: ( + a: Tensor, + restored_dz: Tensor, + dim: number | number[], + keepdim: boolean + ) => Tensor, opName: string | null = null, finalize_op?: (acc: number, count: number) => number ): new () => TorchFunction { + const result = { + [opName]: class extends TorchFunction { + protected dim?: number | number[]; + protected keepdim?: boolean; - const result = class extends TorchFunction { - protected dim?: number | number[]; - protected keepdim?: boolean; + protected _forward(a: Tensor, dim?: number | number[], keepdim: boolean = false): Tensor { + this.dim = dim; + this.keepdim = keepdim; - protected _forward(a: Tensor, dim?: number | number[], keepdim: boolean = false): Tensor { - this.dim = dim; - this.keepdim = keepdim; - - if (a.requires_grad) { - this.saved_tensors = [a]; - } - this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - - const out_shape = _get_reduction_shape(a.shape, dim, keepdim); - const out_size = out_shape.reduce((acc, val) => acc * val, 1); - - const res_data = new Array(out_size).fill(init_val); - const counts = new Array(out_size).fill(0); // Tracked specifically for mean() - - const in_strides = _get_strides(a.shape); - const out_strides = _get_strides(out_shape); - - const dims = dim === undefined ? [] : Array.isArray(dim) ? dim : [dim]; - const normalized_dims = dims.map((d) => (d < 0 ? d + a.shape.length : d)); - const is_full_reduce = dim === undefined; - - // Accumulate - for (let i = 0; i < a.data.length; i++) { - const in_coords = _unravel_index(i, in_strides); - let out_coords: number[]; - - if (is_full_reduce) { - out_coords = keepdim ? in_coords.map(() => 0) : []; - } else { - out_coords = []; - for (let j = 0; j < a.shape.length; j++) { - if (normalized_dims.includes(j)) { - if (keepdim) out_coords.push(0); // Collapse dimension to index 0 - } else { - out_coords.push(in_coords[j]); + if (a.requires_grad) { + this.saved_tensors = [a]; + } + this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); + + const out_shape = _get_reduction_shape(a.shape, dim, keepdim); + const out_size = out_shape.reduce((acc, val) => acc * val, 1); + + const res_data = new Array(out_size).fill(init_val); + const counts = new Array(out_size).fill(0); // Tracked specifically for mean() + + const in_strides = _get_strides(a.shape); + const out_strides = _get_strides(out_shape); + + const dims = dim === undefined ? [] : Array.isArray(dim) ? dim : [dim]; + const normalized_dims = dims.map(d => (d < 0 ? d + a.shape.length : d)); + const is_full_reduce = dim === undefined; + + // Accumulate + for (let i = 0; i < a.data.length; i++) { + const in_coords = _unravel_index(i, in_strides); + let out_coords: number[]; + + if (is_full_reduce) { + out_coords = keepdim ? in_coords.map(() => 0) : []; + } else { + out_coords = []; + for (let j = 0; j < a.shape.length; j++) { + if (normalized_dims.includes(j)) { + if (keepdim) out_coords.push(0); // Collapse dimension to index 0 + } else { + out_coords.push(in_coords[j]); + } } } - } - const out_idx = _ravel_index(out_coords, out_strides); - res_data[out_idx] = reduce_op(res_data[out_idx], a.data[i]); - counts[out_idx]++; - } + const out_idx = _ravel_index(out_coords, out_strides); + res_data[out_idx] = reduce_op(res_data[out_idx], a.data[i]); + counts[out_idx]++; + } - // Finalize (e.g., divide by count for mean) - if (finalize_op) { - for (let i = 0; i < out_size; i++) { - res_data[i] = finalize_op(res_data[i], counts[i]); + // Finalize (e.g., divide by count for mean) + if (finalize_op) { + for (let i = 0; i < out_size; i++) { + res_data[i] = finalize_op(res_data[i], counts[i]); + } } - } - return new Tensor( - res_data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape: out_shape } - ); - } + return new Tensor( + res_data, + { requires_grad: a.requires_grad }, + { operation: a.requires_grad ? this : null, shape: out_shape } + ); + } - protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; - const [aFn] = this.next_functions; + protected _backward(dz: Tensor): void { + const [a] = this.saved_tensors; + const [aFn] = this.next_functions; - let restored_dz = dz; + let restored_dz = dz; - const target_shape = _get_reduction_shape(a.shape, this.dim, true); + const target_shape = _get_reduction_shape(a.shape, this.dim, true); - if (dz.shape.length !== target_shape.length) { - restored_dz = dz.reshape(target_shape); - } + if (dz.shape.length !== target_shape.length) { + restored_dz = dz.reshape(target_shape); + } - let expanded_dz = restored_dz.expand(a.shape); - const grad_a = backward_operations(a, expanded_dz, this.dim, this.keepdim); + let expanded_dz = restored_dz.expand(a.shape); + const grad_a = backward_operations(a, expanded_dz, this.dim, this.keepdim); - aFn.backward(grad_a); + aFn.backward(grad_a); + } } - }; + }[opName]; if (opName) { registerOperation(opName, result); From 0632a9d95db4fbf2c9460cd52897a7a3d6b0d86d Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 14:14:21 +0800 Subject: [PATCH 087/128] refactor: nn modules --- package.json | 2 +- src/nn/base.ts | 99 +++++++++++++++++++++++++++++++++++++ src/nn/index.ts | 3 +- src/nn/module.ts | 105 ++-------------------------------------- src/optim/base.ts | 2 +- src/optim/optimizers.ts | 2 +- 6 files changed, 108 insertions(+), 105 deletions(-) create mode 100644 src/nn/base.ts diff --git a/package.json b/package.json index 876926a0..0355d6ae 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "generate": "python3 scripts/generate.py", "serve": "http-server -p 8080 -c-1", "test": "mocha test/**/*.test.ts test/**/*.test.js", - "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js", + "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js --watch-files build", "update-tests": "python3 scripts/generate_tests.py > test/testcases.gen.js", "watch": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\"" }, diff --git a/src/nn/base.ts b/src/nn/base.ts new file mode 100644 index 00000000..9af70bd5 --- /dev/null +++ b/src/nn/base.ts @@ -0,0 +1,99 @@ +import { Tensor } from '../tensor'; +import { NestedNumberArray } from '../tensor'; +import { TorchFunction } from '../functions/base'; + +export class Parameter extends Tensor { + constructor( + data: NestedNumberArray | Tensor | Parameter, + // Default to requires_grad=true + options: { requires_grad?: boolean } = { + requires_grad: true + }, + internal_options: { operation?: TorchFunction; shape?: number[] } = {} + ) { + if (data instanceof Tensor) { + super(data.data, { requires_grad: true }, { shape: data.shape }); + } else if (data instanceof Parameter) { + super(data.data, { requires_grad: true }, { shape: data.shape }); + } else { + super(data, options, internal_options); + } + } +} + +export abstract class Module { + private _modules: { [key: string]: Module }; + private _parameters: { [key: string]: Parameter }; + + constructor() { + this._parameters = {}; + this._modules = {}; + } + + private register_parameter(parameter_name: string, parameter: Parameter) { + this._parameters[parameter_name] = parameter; + } + + private register_module(module_name: string, module: Module) { + this._modules[module_name] = module; + } + + protected register(name: string, value: Parameter | Module) { + if (value instanceof Parameter) { + this.register_parameter(name, value); + } else { + this.register_module(name, value); + } + } + + public abstract forward(...args: Tensor[]): Tensor; + + public parameters(): Parameter[] { + let params: Parameter[] = Object.values(this._parameters); + for (const module of Object.values(this._modules)) { + params = params.concat(module.parameters()); + } + return params; + } +} + +export class Sequential extends Module { + private _modulesArr: Module[]; + + constructor(...modules: Module[]) { + super(); + this._modulesArr = modules; + for (let i = 0; i < modules.length; i++) { + this.register(i.toString(), modules[i]); + } + } + + append(module: Module): this { + this.register(this._modulesArr.length.toString(), module); + this._modulesArr.push(module); + return this; + } + + extend(sequential: Sequential): this { + for (const module of sequential._modulesArr) { + this.append(module); + } + return this; + } + + insert(index: number, module: Module): this { + this._modulesArr.splice(index, 0, module); + for (let i = index; i < this._modulesArr.length; i++) { + this.register(i.toString(), this._modulesArr[i]); + } + return this; + } + + forward(input: Tensor) { + let x = input; + for (const module of this._modulesArr) { + x = module.forward(x); + } + return x; + } +} diff --git a/src/nn/index.ts b/src/nn/index.ts index d30c86cd..7b0fd77b 100644 --- a/src/nn/index.ts +++ b/src/nn/index.ts @@ -1,5 +1,6 @@ import './ops'; -export * from './module'; +export * from './base'; export * from './loss'; +export * from './module'; export * as functional from './functional'; \ No newline at end of file diff --git a/src/nn/module.ts b/src/nn/module.ts index 9e29151b..17fe14f2 100644 --- a/src/nn/module.ts +++ b/src/nn/module.ts @@ -1,63 +1,7 @@ -import { Tensor } from '../tensor'; -import { NestedNumberArray } from '../tensor'; -import { TorchFunction } from '../functions/base'; -import { rand } from '../creation'; -import { functional } from '.'; - -export class Parameter extends Tensor { - constructor( - data: NestedNumberArray | Tensor | Parameter, - // Default to requires_grad=true - options: { requires_grad?: boolean } = { - requires_grad: true - }, - internal_options: { operation?: TorchFunction; shape?: number[] } = {} - ) { - if (data instanceof Tensor) { - super(data.data, { requires_grad: true }, { shape: data.shape }); - } else if (data instanceof Parameter) { - super(data.data, { requires_grad: true }, { shape: data.shape }); - } else { - super(data, options, internal_options); - } - } -} - -export abstract class Module { - private _modules: { [key: string]: Module }; - private _parameters: { [key: string]: Parameter }; - - constructor() { - this._parameters = {}; - this._modules = {}; - } - - private register_parameter(parameter_name: string, parameter: Parameter) { - this._parameters[parameter_name] = parameter; - } - - private register_module(module_name: string, module: Module) { - this._modules[module_name] = module; - } - - protected register(name: string, value: Parameter | Module) { - if (value instanceof Parameter) { - this.register_parameter(name, value); - } else { - this.register_module(name, value); - } - } - - public abstract forward(...args: Tensor[]): Tensor; - - public parameters(): Parameter[] { - let params: Parameter[] = Object.values(this._parameters); - for (const module of Object.values(this._modules)) { - params = params.concat(module.parameters()); - } - return params; - } -} +import { Module, Parameter } from "./base"; +import { rand } from "../creation"; +import * as functional from "./functional"; +import { Tensor } from "../tensor"; export class Linear extends Module { private weight: Parameter; @@ -106,44 +50,3 @@ export class Sigmoid extends Module { return functional.sigmoid(input); } } - -export class Sequential extends Module { - private _modulesArr: Module[]; - - constructor(...modules: Module[]) { - super(); - this._modulesArr = modules; - for (let i = 0; i < modules.length; i++) { - this.register(i.toString(), modules[i]); - } - } - - append(module: Module): this { - this.register(this._modulesArr.length.toString(), module); - this._modulesArr.push(module); - return this; - } - - extend(sequential: Sequential): this { - for (const module of sequential._modulesArr) { - this.append(module); - } - return this; - } - - insert(index: number, module: Module): this { - this._modulesArr.splice(index, 0, module); - for (let i = index; i < this._modulesArr.length; i++) { - this.register(i.toString(), this._modulesArr[i]); - } - return this; - } - - forward(input: Tensor) { - let x = input; - for (const module of this._modulesArr) { - x = module.forward(x); - } - return x; - } -} diff --git a/src/optim/base.ts b/src/optim/base.ts index 5295ecc1..99684b06 100644 --- a/src/optim/base.ts +++ b/src/optim/base.ts @@ -1,4 +1,4 @@ -import { Parameter } from "../nn/module"; +import { Parameter } from "../nn/base"; export abstract class Optimizer { params: Parameter[]; diff --git a/src/optim/optimizers.ts b/src/optim/optimizers.ts index 3b8fa96f..cf55400a 100644 --- a/src/optim/optimizers.ts +++ b/src/optim/optimizers.ts @@ -1,5 +1,5 @@ import { Optimizer } from "./base"; -import { Parameter } from "../nn/module"; +import { Parameter } from "../nn/base"; import { Tensor } from "../tensor"; import { zeros_like } from "../creation"; From ac76c5822743c6452ce2e186cca382dbf1b3d6ae Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 14:40:15 +0800 Subject: [PATCH 088/128] feat: Convolutions --- scripts/generate_tests.py | 58 + src/functions/functional.ts | 2 +- src/functions/ops.ts | 405 ++ src/nn/functional.ts | 6 +- src/nn/module.ts | 125 + test/generated.test.js | 36 + test/testcases.gen.js | 7749 +++++++++++++++++++++++++++++++++++ 7 files changed, 8379 insertions(+), 2 deletions(-) diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index ff00d2d3..34c0a0bf 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -243,6 +243,63 @@ def generate_expand_tests(): return tests +def generate_conv_tests(): + tests = [] + cases = [ + ("Conv1d", torch.nn.Conv1d, [ + (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5), "basic"), + (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 6), "stride_padding"), + (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5), "dilation_no_bias"), + (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 6), "groups"), + ]), + ("Conv2d", torch.nn.Conv2d, [ + (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5, 5), "basic"), + (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 6, 6), "stride_padding"), + (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5, 5), "dilation_no_bias"), + (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 4, 4), "groups"), + ]), + ("Conv3d", torch.nn.Conv3d, [ + (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5, 5, 5), "basic"), + (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 4, 4, 4), "stride_padding"), + (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5, 5, 5), "dilation_no_bias"), + (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 4, 4, 4), "groups"), + ]) + ] + for conv_type, conv_class, conv_cases in cases: + for in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, input_shape, desc in conv_cases: + layer = conv_class(in_channels, out_channels, kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias) + x = torch.randn(*input_shape, requires_grad=True) + + out = layer(x) + out.sum().backward() + + test_data = { + "test_name": f"{conv_type.lower()}_{desc}", + "conv_type": conv_type, + "in_channels": in_channels, + "out_channels": out_channels, + "kernel_size": kernel_size, + "stride": stride, + "padding": padding, + "dilation": dilation, + "groups": groups, + "has_bias": bias, + "input": x.detach().numpy().tolist(), + "weight": layer.weight.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_input": x.grad.numpy().tolist(), + "expected_grad_weight": layer.weight.grad.numpy().tolist() + } + if bias: + test_data["bias"] = layer.bias.detach().numpy().tolist() + test_data["expected_grad_bias"] = layer.bias.grad.numpy().tolist() + else: + test_data["bias"] = None + test_data["expected_grad_bias"] = None + + tests.append(test_data) + return tests + if __name__ == "__main__": suite = { "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, @@ -253,6 +310,7 @@ def generate_expand_tests(): "linear": generate_linear_tests(), "optimizers": generate_optimizer_tests(), "expand": generate_expand_tests(), + "conv": generate_conv_tests(), } print("export const testData = ", end="") diff --git a/src/functions/functional.ts b/src/functions/functional.ts index c48974b6..19119d7e 100644 --- a/src/functions/functional.ts +++ b/src/functions/functional.ts @@ -90,4 +90,4 @@ export const gt = generate_binary_function('gt'); export const le = generate_binary_function('le'); export const ge = generate_binary_function('ge'); export const eq = generate_binary_function('eq'); -export const ne = generate_binary_function('ne'); \ No newline at end of file +export const ne = generate_binary_function('ne'); diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 1aeac024..78f0b15a 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -648,6 +648,411 @@ class Matmul extends BinaryFunction { } registerOperation('matmul', Matmul); +function _convNd_forward( + input: Tensor, + weight: Tensor, + bias: Tensor | null, + stride: number | number[], + padding: number | number[], + dilation: number | number[], + groups: number, + dims: number +): Tensor { + let stride_arr = typeof stride === 'number' ? new Array(dims).fill(stride) : stride; + let padding_arr = typeof padding === 'number' ? new Array(dims).fill(padding) : padding; + let dilation_arr = typeof dilation === 'number' ? new Array(dims).fill(dilation) : dilation; + + const batch_size = input.shape[0]; + const in_channels = input.shape[1]; + const out_channels = weight.shape[0]; + const in_dims = input.shape.slice(2); + const kernel_dims = weight.shape.slice(2); + + if (in_channels !== weight.shape[1] * groups) { + throw new Error(`in_channels (${in_channels}) must be divisible by groups (${groups}) and match weight.shape[1] * groups (${weight.shape[1] * groups})`); + } + + const out_dims = in_dims.map((in_dim, i) => { + return Math.floor((in_dim + 2 * padding_arr[i] - dilation_arr[i] * (kernel_dims[i] - 1) - 1) / stride_arr[i] + 1); + }); + + const output_shape = [batch_size, out_channels, ...out_dims]; + const output_size = output_shape.reduce((a, b) => a * b, 1); + const output_data = new Array(output_size).fill(0); + + const get_strides = (shape: number[]) => { + const strides = new Array(shape.length); + let s = 1; + for (let i = shape.length - 1; i >= 0; i--) { + strides[i] = s; + s *= shape[i]; + } + return strides; + }; + + const in_strides = get_strides(input.shape); + const w_strides = get_strides(weight.shape); + const out_strides = get_strides(output_shape); + const in_channels_per_group = in_channels / groups; + const out_channels_per_group = out_channels / groups; + + for (let b = 0; b < batch_size; b++) { + for (let g = 0; g < groups; g++) { + for (let oc_g = 0; oc_g < out_channels_per_group; oc_g++) { + const oc = g * out_channels_per_group + oc_g; + + // Iterate over output spatial dimensions + const out_spatial_size = out_dims.reduce((a, b) => a * b, 1); + for (let os_idx = 0; os_idx < out_spatial_size; os_idx++) { + + // Decode output spatial index + const os_coords = new Array(dims); + let temp_os = os_idx; + for (let d = dims - 1; d >= 0; d--) { + os_coords[d] = temp_os % out_dims[d]; + temp_os = Math.floor(temp_os / out_dims[d]); + } + + let sum = bias ? bias.data[oc] : 0; + + // Iterate over kernel spatial dimensions and in_channels + for (let ic_g = 0; ic_g < in_channels_per_group; ic_g++) { + const ic = g * in_channels_per_group + ic_g; + + const kernel_spatial_size = kernel_dims.reduce((a, b) => a * b, 1); + for (let ks_idx = 0; ks_idx < kernel_spatial_size; ks_idx++) { + // Decode kernel spatial index + const ks_coords = new Array(dims); + let temp_ks = ks_idx; + for (let d = dims - 1; d >= 0; d--) { + ks_coords[d] = temp_ks % kernel_dims[d]; + temp_ks = Math.floor(temp_ks / kernel_dims[d]); + } + + // Calculate input spatial coordinates + let is_valid = true; + const is_coords = new Array(dims); + for (let d = 0; d < dims; d++) { + const in_coord = os_coords[d] * stride_arr[d] + ks_coords[d] * dilation_arr[d] - padding_arr[d]; + if (in_coord < 0 || in_coord >= in_dims[d]) { + is_valid = false; + break; + } + is_coords[d] = in_coord; + } + + if (is_valid) { + // Calculate flattened indices + let in_flat_idx = b * in_strides[0] + ic * in_strides[1]; + for (let d = 0; d < dims; d++) in_flat_idx += is_coords[d] * in_strides[d + 2]; + + let w_flat_idx = oc * w_strides[0] + ic_g * w_strides[1]; + for (let d = 0; d < dims; d++) w_flat_idx += ks_coords[d] * w_strides[d + 2]; + + sum += input.data[in_flat_idx] * weight.data[w_flat_idx]; + } + } + } + + // Calculate output flattened index + let out_flat_idx = b * out_strides[0] + oc * out_strides[1]; + for (let d = 0; d < dims; d++) out_flat_idx += os_coords[d] * out_strides[d + 2]; + + output_data[out_flat_idx] = sum; + } + } + } + } + + return new Tensor(output_data, { requires_grad: false }, { shape: output_shape }); +} + +function _convNd_backward( + dz: Tensor, + input: Tensor, + weight: Tensor, + bias: Tensor | null, + stride: number | number[], + padding: number | number[], + dilation: number | number[], + groups: number, + dims: number, + input_requires_grad: boolean, + weight_requires_grad: boolean +): [Tensor | null, Tensor | null, Tensor | null] { + let stride_arr = typeof stride === 'number' ? new Array(dims).fill(stride) : stride; + let padding_arr = typeof padding === 'number' ? new Array(dims).fill(padding) : padding; + let dilation_arr = typeof dilation === 'number' ? new Array(dims).fill(dilation) : dilation; + + const batch_size = input.shape[0]; + const in_channels = input.shape[1]; + const out_channels = weight.shape[0]; + const in_dims = input.shape.slice(2); + const kernel_dims = weight.shape.slice(2); + const out_dims = dz.shape.slice(2); + + const get_strides = (shape: number[]) => { + const strides = new Array(shape.length); + let s = 1; + for (let i = shape.length - 1; i >= 0; i--) { + strides[i] = s; + s *= shape[i]; + } + return strides; + }; + + const in_strides = get_strides(input.shape); + const w_strides = get_strides(weight.shape); + const dz_strides = get_strides(dz.shape); + + let dInput: Tensor | null = null; + let dWeight: Tensor | null = null; + let dBias: Tensor | null = null; + + let dInput_data: number[] | null = null; + let dWeight_data: number[] | null = null; + + if (input_requires_grad) { + dInput_data = new Array(input.dataLength()).fill(0); + } + if (weight_requires_grad) { + dWeight_data = new Array(weight.dataLength()).fill(0); + } + + const in_channels_per_group = in_channels / groups; + const out_channels_per_group = out_channels / groups; + + for (let b = 0; b < batch_size; b++) { + for (let g = 0; g < groups; g++) { + for (let oc_g = 0; oc_g < out_channels_per_group; oc_g++) { + const oc = g * out_channels_per_group + oc_g; + + const out_spatial_size = out_dims.reduce((a, b) => a * b, 1); + for (let os_idx = 0; os_idx < out_spatial_size; os_idx++) { + + const os_coords = new Array(dims); + let temp_os = os_idx; + for (let d = dims - 1; d >= 0; d--) { + os_coords[d] = temp_os % out_dims[d]; + temp_os = Math.floor(temp_os / out_dims[d]); + } + + let dz_flat_idx = b * dz_strides[0] + oc * dz_strides[1]; + for (let d = 0; d < dims; d++) dz_flat_idx += os_coords[d] * dz_strides[d + 2]; + const dz_val = dz.data[dz_flat_idx]; + + for (let ic_g = 0; ic_g < in_channels_per_group; ic_g++) { + const ic = g * in_channels_per_group + ic_g; + + const kernel_spatial_size = kernel_dims.reduce((a, b) => a * b, 1); + for (let ks_idx = 0; ks_idx < kernel_spatial_size; ks_idx++) { + const ks_coords = new Array(dims); + let temp_ks = ks_idx; + for (let d = dims - 1; d >= 0; d--) { + ks_coords[d] = temp_ks % kernel_dims[d]; + temp_ks = Math.floor(temp_ks / kernel_dims[d]); + } + + let is_valid = true; + const is_coords = new Array(dims); + for (let d = 0; d < dims; d++) { + const in_coord = os_coords[d] * stride_arr[d] + ks_coords[d] * dilation_arr[d] - padding_arr[d]; + if (in_coord < 0 || in_coord >= in_dims[d]) { + is_valid = false; + break; + } + is_coords[d] = in_coord; + } + + if (is_valid) { + let in_flat_idx = b * in_strides[0] + ic * in_strides[1]; + for (let d = 0; d < dims; d++) in_flat_idx += is_coords[d] * in_strides[d + 2]; + + let w_flat_idx = oc * w_strides[0] + ic_g * w_strides[1]; + for (let d = 0; d < dims; d++) w_flat_idx += ks_coords[d] * w_strides[d + 2]; + + if (input_requires_grad) { + dInput_data![in_flat_idx] += dz_val * weight.data[w_flat_idx]; + } + if (weight_requires_grad) { + dWeight_data![w_flat_idx] += dz_val * input.data[in_flat_idx]; + } + } + } + } + } + } + } + } + + if (input_requires_grad) dInput = new Tensor(dInput_data!, { requires_grad: false }, { shape: input.shape }); + if (weight_requires_grad) dWeight = new Tensor(dWeight_data!, { requires_grad: false }, { shape: weight.shape }); + if (bias && bias.requires_grad) { + const sum_dims = [0]; + for(let d=2; d 2 ? this.saved_tensors[2] : null; + const [inputFn, weightFn, biasFn] = this.next_functions; + + const [dInput, dWeight, dBias] = _convNd_backward( + dz, input, weight, bias, this.stride, this.padding, this.dilation, this.groups, 1, + input.requires_grad, weight.requires_grad + ); + + if (input.requires_grad) inputFn.backward(dInput); + if (weight.requires_grad) weightFn.backward(dWeight); + if (bias && bias.requires_grad) biasFn.backward(dBias); + } +} +registerOperation('conv1d', Conv1dOp); + +class Conv2dOp extends TorchFunction { + private stride: number | number[]; + private padding: number | number[]; + private dilation: number | number[]; + private groups: number; + + protected _forward( + input: Tensor, + weight: Tensor, + bias: Tensor | null, + stride: number | number[] = 1, + padding: number | number[] = 0, + dilation: number | number[] = 1, + groups: number = 1 + ): Tensor { + if (input.requires_grad || weight.requires_grad || bias?.requires_grad) { + this.saved_tensors = [input, weight]; + if (bias) this.saved_tensors.push(bias); + } + this.next_functions.push(input.grad_fn ? input.grad_fn : nullOp); + this.next_functions.push(weight.grad_fn ? weight.grad_fn : nullOp); + if (bias) this.next_functions.push(bias.grad_fn ? bias.grad_fn : nullOp); + + this.stride = stride; + this.padding = padding; + this.dilation = dilation; + this.groups = groups; + + const res = _convNd_forward(input, weight, bias, stride, padding, dilation, groups, 2); + res.requires_grad = input.requires_grad || weight.requires_grad || (bias?.requires_grad ?? false); + res.grad_fn = res.requires_grad ? this : null; + return res; + } + + protected _backward(dz: Tensor): void { + const input = this.saved_tensors[0]; + const weight = this.saved_tensors[1]; + const bias = this.saved_tensors.length > 2 ? this.saved_tensors[2] : null; + const [inputFn, weightFn, biasFn] = this.next_functions; + + const [dInput, dWeight, dBias] = _convNd_backward( + dz, input, weight, bias, this.stride, this.padding, this.dilation, this.groups, 2, + input.requires_grad, weight.requires_grad + ); + + if (input.requires_grad) inputFn.backward(dInput); + if (weight.requires_grad) weightFn.backward(dWeight); + if (bias && bias.requires_grad) biasFn.backward(dBias); + } +} +registerOperation('conv2d', Conv2dOp); + +class Conv3dOp extends TorchFunction { + private stride: number | number[]; + private padding: number | number[]; + private dilation: number | number[]; + private groups: number; + + protected _forward( + input: Tensor, + weight: Tensor, + bias: Tensor | null, + stride: number | number[] = 1, + padding: number | number[] = 0, + dilation: number | number[] = 1, + groups: number = 1 + ): Tensor { + if (input.requires_grad || weight.requires_grad || bias?.requires_grad) { + this.saved_tensors = [input, weight]; + if (bias) this.saved_tensors.push(bias); + } + this.next_functions.push(input.grad_fn ? input.grad_fn : nullOp); + this.next_functions.push(weight.grad_fn ? weight.grad_fn : nullOp); + if (bias) this.next_functions.push(bias.grad_fn ? bias.grad_fn : nullOp); + + this.stride = stride; + this.padding = padding; + this.dilation = dilation; + this.groups = groups; + + const res = _convNd_forward(input, weight, bias, stride, padding, dilation, groups, 3); + res.requires_grad = input.requires_grad || weight.requires_grad || (bias?.requires_grad ?? false); + res.grad_fn = res.requires_grad ? this : null; + return res; + } + + protected _backward(dz: Tensor): void { + const input = this.saved_tensors[0]; + const weight = this.saved_tensors[1]; + const bias = this.saved_tensors.length > 2 ? this.saved_tensors[2] : null; + const [inputFn, weightFn, biasFn] = this.next_functions; + + const [dInput, dWeight, dBias] = _convNd_backward( + dz, input, weight, bias, this.stride, this.padding, this.dilation, this.groups, 3, + input.requires_grad, weight.requires_grad + ); + + if (input.requires_grad) inputFn.backward(dInput); + if (weight.requires_grad) weightFn.backward(dWeight); + if (bias && bias.requires_grad) biasFn.backward(dBias); + } +} +registerOperation('conv3d', Conv3dOp); + + // comparison const Lt = BinaryFunctionMixin( diff --git a/src/nn/functional.ts b/src/nn/functional.ts index c24b2d42..7c20c632 100644 --- a/src/nn/functional.ts +++ b/src/nn/functional.ts @@ -2,7 +2,7 @@ import { Tensor } from "../tensor"; import { getOperation } from "../functions/registry"; function generate_function(opname: string) { - return (...args: (Tensor | number)[]) => { + return (...args: (Tensor | number | number[] | null)[]) => { const operation = new (getOperation(opname))(); return operation.forward(...args); }; @@ -36,3 +36,7 @@ function generate_binary_function(opname: string) { export const relu = generate_unary_function('relu'); export const sigmoid = generate_unary_function('sigmoid'); + +export const conv1d = generate_function('conv1d'); +export const conv2d = generate_function('conv2d'); +export const conv3d = generate_function('conv3d'); diff --git a/src/nn/module.ts b/src/nn/module.ts index 17fe14f2..7b0157ad 100644 --- a/src/nn/module.ts +++ b/src/nn/module.ts @@ -50,3 +50,128 @@ export class Sigmoid extends Module { return functional.sigmoid(input); } } + +abstract class _ConvNd extends Module { + public weight: Parameter; + public bias: Parameter | null; + + public in_channels: number; + public out_channels: number; + public kernel_size: number | number[]; + public stride: number | number[]; + public padding: number | number[]; + public dilation: number | number[]; + public groups: number; + + constructor( + in_channels: number, + out_channels: number, + kernel_size: number | number[], + stride: number | number[], + padding: number | number[], + dilation: number | number[], + groups: number, + bias: boolean, + dims: number + ) { + super(); + + this.in_channels = in_channels; + this.out_channels = out_channels; + this.kernel_size = kernel_size; + this.stride = stride; + this.padding = padding; + this.dilation = dilation; + this.groups = groups; + + if (in_channels % groups !== 0) { + throw new Error('in_channels must be divisible by groups'); + } + if (out_channels % groups !== 0) { + throw new Error('out_channels must be divisible by groups'); + } + + let kernel_arr = typeof kernel_size === 'number' ? new Array(dims).fill(kernel_size) : kernel_size; + const kernel_vol = kernel_arr.reduce((a: number, b: number) => a * b, 1); + + const k = Math.sqrt(groups / (in_channels * kernel_vol)); + + this.weight = new Parameter( + rand([out_channels, in_channels / groups, ...kernel_arr]) + .mul(2 * k) + .sub(k) + ); + + this.register('weight', this.weight); + + if (bias) { + this.bias = new Parameter( + rand([out_channels]) + .mul(2 * k) + .sub(k) + ); + this.register('bias', this.bias); + } else { + this.bias = null; + } + } + + abstract forward(input: Tensor): Tensor; +} + +export class Conv1d extends _ConvNd { + constructor( + in_channels: number, + out_channels: number, + kernel_size: number | number[], + stride: number | number[] = 1, + padding: number | number[] = 0, + dilation: number | number[] = 1, + groups: number = 1, + bias: boolean = true + ) { + super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 1); + } + + forward(input: Tensor) { + return functional.conv1d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups); + } +} + +export class Conv2d extends _ConvNd { + constructor( + in_channels: number, + out_channels: number, + kernel_size: number | number[], + stride: number | number[] = 1, + padding: number | number[] = 0, + dilation: number | number[] = 1, + groups: number = 1, + bias: boolean = true + ) { + super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 2); + } + + forward(input: Tensor) { + return functional.conv2d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups); + } +} + +export class Conv3d extends _ConvNd { + constructor( + in_channels: number, + out_channels: number, + kernel_size: number | number[], + stride: number | number[] = 1, + padding: number | number[] = 0, + dilation: number | number[] = 1, + groups: number = 1, + bias: boolean = true + ) { + super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 3); + } + + forward(input: Tensor) { + return functional.conv3d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups); + } +} diff --git a/test/generated.test.js b/test/generated.test.js index 0c32c5f5..e6c99eb1 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -125,6 +125,42 @@ describe('Automated Tests', () => { }); }); }); + + describe('Convolutions', () => { + testData.conv?.forEach(test => { + it(test.test_name, () => { + const ConvClass = torch.nn[test.conv_type]; + const layer = new ConvClass( + test.in_channels, + test.out_channels, + test.kernel_size, + test.stride, + test.padding, + test.dilation, + test.groups, + test.has_bias + ); + + layer.weight = new Tensor(test.weight, { requires_grad: true }); + if (test.has_bias) { + layer.bias = new Tensor(test.bias, { requires_grad: true }); + } + + const x = new Tensor(test.input, { requires_grad: true }); + + const out = layer.forward(x); + assertDeepCloseTo(out.toArray(), test.expected_output); + + out.sum().backward(); + + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_input); + assertDeepCloseTo(layer.weight.grad.toArray(), test.expected_grad_weight); + if (test.has_bias) { + assertDeepCloseTo(layer.bias.grad.toArray(), test.expected_grad_bias); + } + }); + }); + }); }); describe('Optimizers', () => { diff --git a/test/testcases.gen.js b/test/testcases.gen.js index e2339a33..7fc8a0b2 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -12865,5 +12865,7754 @@ export const testData = { ] ] } + ], + "conv": [ + { + "test_name": "conv1d_basic", + "conv_type": "Conv1d", + "in_channels": 1, + "out_channels": 1, + "kernel_size": 3, + "stride": 1, + "padding": 0, + "dilation": 1, + "groups": 1, + "has_bias": true, + "input": [ + [ + [ + 0.6961200833320618, + 1.6817193031311035, + -1.6232244968414307, + 1.4739271402359009, + -0.3031364381313324 + ] + ] + ], + "weight": [ + [ + [ + -0.06942257285118103, + 0.01881338469684124, + 0.28348493576049805 + ] + ] + ], + "expected_output": [ + [ + [ + -0.6306472420692444, + 0.11674860864877701, + -0.0993165373802185 + ] + ] + ], + "expected_grad_input": [ + [ + [ + -0.06942257285118103, + -0.05060918629169464, + 0.2328757494688034, + 0.30229830741882324, + 0.28348493576049805 + ] + ] + ], + "expected_grad_weight": [ + [ + [ + 0.7546148300170898, + 1.5324219465255737, + -0.4524337947368622 + ] + ] + ], + "bias": [ + -0.153799906373024 + ], + "expected_grad_bias": [ + 3.0 + ] + }, + { + "test_name": "conv1d_stride_padding", + "conv_type": "Conv1d", + "in_channels": 2, + "out_channels": 3, + "kernel_size": 2, + "stride": 2, + "padding": 1, + "dilation": 1, + "groups": 1, + "has_bias": true, + "input": [ + [ + [ + 0.6954406499862671, + -0.32303762435913086, + 0.5969774723052979, + -0.6247759461402893, + -0.3959338068962097, + 1.804771900177002 + ], + [ + -0.013955703936517239, + 0.33602362871170044, + -1.6720243692398071, + -0.8870291113853455, + -0.9315488338470459, + 1.888498306274414 + ] + ], + [ + [ + -1.3799183368682861, + -0.21034009754657745, + 0.8919094204902649, + 0.18319325149059296, + -0.811191976070404, + 0.6481902003288269 + ], + [ + -0.6447557210922241, + 1.492192268371582, + -0.16011619567871094, + -1.608611822128296, + 0.1806594282388687, + 1.864193320274353 + ] + ] + ], + "weight": [ + [ + [ + -0.46550750732421875, + 0.4468115568161011 + ], + [ + -0.24810147285461426, + 0.432242751121521 + ] + ], + [ + [ + -0.1569221019744873, + 0.4875195026397705 + ], + [ + 0.14750081300735474, + -0.024153947830200195 + ] + ], + [ + [ + 0.19086652994155884, + -0.015548527240753174 + ], + [ + -0.24799185991287231, + 0.2735045552253723 + ] + ] + ], + "expected_output": [ + [ + [ + 0.6290085911750793, + -0.06466558575630188, + 0.25565797090530396, + -0.9843642115592957 + ], + [ + 0.27673861384391785, + 0.369040310382843, + -0.26596060395240784, + -0.06729292869567871 + ], + [ + 0.4556798040866852, + -0.14126674830913544, + 0.3224104046821594, + 0.34644821286201477 + ] + ], + [ + [ + -0.5709445476531982, + 0.38131606578826904, + 0.35376980900764465, + -0.43993663787841797 + ], + [ + -0.7198030948638916, + 0.6291579008102417, + -0.7284935712814331, + 0.1106153056025505 + ], + [ + 0.3154219388961792, + 0.0024510433431714773, + 0.9662219285964966, + 0.13172286748886108 + ] + ] + ], + "expected_grad_input": [ + [ + [ + 0.9187825322151184, + -0.4315630793571472, + 0.9187825322151184, + -0.4315630793571472, + 0.9187825322151184, + -0.4315630793571472 + ], + [ + 0.6815933585166931, + -0.34859251976013184, + 0.6815933585166931, + -0.34859251976013184, + 0.6815933585166931, + -0.34859251976013184 + ] + ], + [ + [ + 0.9187825322151184, + -0.4315630793571472, + 0.9187825322151184, + -0.4315630793571472, + 0.9187825322151184, + -0.4315630793571472 + ], + [ + 0.6815933585166931, + -0.34859251976013184, + 0.6815933585166931, + -0.34859251976013184, + 0.6815933585166931, + -0.34859251976013184 + ] + ] + ], + "expected_grad_weight": [ + [ + [ + 1.478001594543457, + -0.40271657705307007 + ], + [ + 3.085266590118408, + -3.241741418838501 + ] + ], + [ + [ + 1.478001594543457, + -0.40271657705307007 + ], + [ + 3.085266590118408, + -3.241741418838501 + ] + ], + [ + [ + 1.478001594543457, + -0.40271657705307007 + ], + [ + 3.085266590118408, + -3.241741418838501 + ] + ] + ], + "bias": [ + 0.3243098855018616, + -0.06263935565948486, + 0.470309853553772 + ], + "expected_grad_bias": [ + 8.0, + 8.0, + 8.0 + ] + }, + { + "test_name": "conv1d_dilation_no_bias", + "conv_type": "Conv1d", + "in_channels": 2, + "out_channels": 2, + "kernel_size": 2, + "stride": 1, + "padding": 0, + "dilation": 2, + "groups": 1, + "has_bias": false, + "input": [ + [ + [ + 0.6144998073577881, + 0.4801225960254669, + 0.07178732752799988, + -1.3224995136260986, + -0.5643792152404785 + ], + [ + 1.2230476140975952, + -1.3995004892349243, + -0.4572429955005646, + -0.4214997887611389, + -0.7015021443367004 + ] + ] + ], + "weight": [ + [ + [ + 0.3132607340812683, + 0.011339008808135986 + ], + [ + -0.01703113317489624, + 0.05102437734603882 + ] + ], + [ + [ + -0.224409818649292, + 0.4134613871574402 + ], + [ + -0.04957634210586548, + -0.18205493688583374 + ] + ] + ], + "expected_output": [ + [ + [ + 0.1491522192955017, + 0.13773603737354279, + -0.01191769540309906 + ], + [ + -0.08560937643051147, + -0.5084284543991089, + -0.09907843172550201 + ] + ] + ], + "expected_grad_input": [ + [ + [ + 0.08885091543197632, + 0.08885091543197632, + 0.5136513113975525, + 0.42480039596557617, + 0.42480039596557617 + ], + [ + -0.06660747528076172, + -0.06660747528076172, + -0.19763803482055664, + -0.13103055953979492, + -0.13103055953979492 + ] + ] + ], + "expected_grad_weight": [ + [ + [ + 1.1664097309112549, + -1.8150913715362549 + ], + [ + -0.6336958408355713, + -1.580245018005371 + ] + ], + [ + [ + 1.1664097309112549, + -1.8150913715362549 + ], + [ + -0.6336958408355713, + -1.580245018005371 + ] + ] + ], + "bias": null, + "expected_grad_bias": null + }, + { + "test_name": "conv1d_groups", + "conv_type": "Conv1d", + "in_channels": 4, + "out_channels": 4, + "kernel_size": 3, + "stride": 1, + "padding": 1, + "dilation": 1, + "groups": 2, + "has_bias": true, + "input": [ + [ + [ + -1.5568547248840332, + -1.2001843452453613, + 0.2736855447292328, + -0.6129935383796692, + 0.14779093861579895, + -0.5190516710281372 + ], + [ + 0.2923465669155121, + -0.5539951920509338, + -1.2117003202438354, + 0.23923887312412262, + -0.7021881937980652, + 1.0326601266860962 + ], + [ + 0.9352383017539978, + 0.30303436517715454, + -0.5343928933143616, + -0.2886335253715515, + 0.7341271638870239, + -1.3263294696807861 + ], + [ + 0.24674031138420105, + 1.4741090536117554, + -1.2584627866744995, + 0.08387812972068787, + 0.9973886609077454, + -0.7661278247833252 + ] + ] + ], + "weight": [ + [ + [ + 0.12207754701375961, + 0.40559911727905273, + 0.1231803372502327 + ], + [ + -0.393903911113739, + -0.13032309710979462, + 0.38015538454055786 + ] + ], + [ + [ + -0.14388829469680786, + -0.19640615582466125, + -0.3254093527793884 + ], + [ + -0.2253584861755371, + -0.22320778667926788, + 0.09750071167945862 + ] + ], + [ + [ + 0.16310562193393707, + 0.3896220326423645, + 0.26792049407958984 + ], + [ + 0.006032273638993502, + 0.2201666384935379, + 0.2333495020866394 + ] + ], + [ + [ + -0.3521243631839752, + 0.20600011944770813, + -0.27926933765411377 + ], + [ + 0.3152562081813812, + -0.17756487429141998, + 0.08470655232667923 + ] + ] + ], + "expected_output": [ + [ + [ + -1.0323456525802612, + -1.1510744094848633, + 0.3517197370529175, + -0.0221832487732172, + 0.3066757321357727, + -0.05481366068124771 + ], + [ + 0.7664621472358704, + 0.49971258640289307, + 0.9264512658119202, + 0.37353020906448364, + 0.6209883689880371, + 0.1978299468755722 + ], + [ + 0.9073842167854309, + 0.22331207990646362, + -0.4212228059768677, + 0.3041822016239166, + -0.011575311422348022, + -0.4961872100830078 + ], + [ + -0.10705599188804626, + -0.7043604254722595, + 0.2629602551460266, + -0.6995928883552551, + 0.11157292127609253, + -0.3773989677429199 + ] + ] + ], + "expected_grad_input": [ + [ + [ + 0.18738222122192383, + -0.0148468017578125, + -0.0148468017578125, + -0.0148468017578125, + -0.0148468017578125, + 0.006963938474655151 + ], + [ + -0.9727932810783386, + -0.49513718485832214, + -0.49513718485832214, + -0.49513718485832214, + -0.49513718485832214, + 0.12412521243095398 + ], + [ + 0.40660345554351807, + 0.39525461196899414, + 0.39525461196899414, + 0.39525461196899414, + 0.39525461196899414, + 0.5842733383178711 + ], + [ + 0.36389026045799255, + 0.6819462776184082, + 0.6819462776184082, + 0.6819462776184082, + 0.6819462776184082, + 0.36065781116485596 + ] + ] + ], + "expected_grad_weight": [ + [ + [ + -2.9485559463500977, + -3.4676079750061035, + -1.9107531309127808 + ], + [ + -1.9362983703613281, + -0.9036381840705872, + -1.1959846019744873 + ] + ], + [ + [ + -2.9485559463500977, + -3.4676079750061035, + -1.9107531309127808 + ], + [ + -1.9362983703613281, + -0.9036381840705872, + -1.1959846019744873 + ] + ], + [ + [ + 1.1493734121322632, + -0.17695605754852295, + -1.112194299697876 + ], + [ + 1.5436534881591797, + 0.7775256037712097, + 0.5307852625846863 + ] + ], + [ + [ + 1.1493734121322632, + -0.17695605754852295, + -1.112194299697876 + ], + [ + 1.5436534881591797, + 0.7775256037712097, + 0.5307852625846863 + ] + ] + ], + "bias": [ + -0.0043439180590212345, + 0.18940408527851105, + 0.06349903345108032, + -0.29614126682281494 + ], + "expected_grad_bias": [ + 6.0, + 6.0, + 6.0, + 6.0 + ] + }, + { + "test_name": "conv2d_basic", + "conv_type": "Conv2d", + "in_channels": 1, + "out_channels": 1, + "kernel_size": 3, + "stride": 1, + "padding": 0, + "dilation": 1, + "groups": 1, + "has_bias": true, + "input": [ + [ + [ + [ + -0.15365807712078094, + 1.032126545906067, + 0.36852389574050903, + 2.4601800441741943, + 0.13030865788459778 + ], + [ + -0.9205528497695923, + 1.5234228372573853, + 1.3897676467895508, + -1.6782877445220947, + 1.655027985572815 + ], + [ + 0.5495442748069763, + 0.1979023516178131, + -0.33105704188346863, + -1.3217003345489502, + -0.24350062012672424 + ], + [ + -0.4956028163433075, + 1.6506794691085815, + -0.8902555108070374, + 0.6958364844322205, + -0.9322998523712158 + ], + [ + 0.18523266911506653, + 0.039212681353092194, + -1.0234346389770508, + 0.31960463523864746, + -0.8433935046195984 + ] + ] + ] + ], + "weight": [ + [ + [ + [ + 0.29462969303131104, + 0.3235141932964325, + -0.07830675691366196 + ], + [ + 0.1112322062253952, + -0.2927438020706177, + -0.06486010551452637 + ], + [ + -0.10368549823760986, + 0.0946246013045311, + -0.21840083599090576 + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + -0.2726651728153229, + 0.4109613299369812, + 1.467284083366394 + ], + [ + 0.6114932298660278, + 0.8991829752922058, + 0.5365865230560303 + ], + [ + 0.0512884259223938, + 0.3551037609577179, + -0.3557467460632324 + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + 0.29462969303131104, + 0.6181439161300659, + 0.5398371815681458, + 0.24520742893218994, + -0.07830675691366196 + ], + [ + 0.40586191415786743, + 0.43663233518600464, + 0.2934654951095581, + -0.1123964786529541, + -0.14316686987876892 + ], + [ + 0.30217641592025757, + 0.42757144570350647, + 0.06600376963615417, + -0.23617270588874817, + -0.3615677058696747 + ], + [ + 0.007546707987785339, + -0.19057247042655945, + -0.4738334119319916, + -0.4813801348209381, + -0.28326094150543213 + ], + [ + -0.10368549823760986, + -0.009060896933078766, + -0.22746172547340393, + -0.12377623468637466, + -0.21840083599090576 + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + 3.656019449234009, + 3.640878438949585, + 2.429262399673462 + ], + [ + 2.6738481521606445, + 1.2363080978393555, + -1.6564688682556152 + ], + [ + -0.11777856945991516, + -0.6632119417190552, + -4.570200443267822 + ] + ] + ] + ], + "bias": [ + 0.07201576232910156 + ], + "expected_grad_bias": [ + 9.0 + ] + }, + { + "test_name": "conv2d_stride_padding", + "conv_type": "Conv2d", + "in_channels": 2, + "out_channels": 3, + "kernel_size": 2, + "stride": 2, + "padding": 1, + "dilation": 1, + "groups": 1, + "has_bias": true, + "input": [ + [ + [ + [ + 0.7696021795272827, + 0.582319974899292, + 0.2216803878545761, + -0.1759732961654663, + 0.42830219864845276, + 1.2776193618774414 + ], + [ + 0.9624823927879333, + 0.04533285275101662, + -0.7639250159263611, + -0.6143314838409424, + 0.6616799235343933, + -0.05819060653448105 + ], + [ + -0.7563550472259521, + 0.20380251109600067, + 0.36853712797164917, + -0.2603956162929535, + -1.0269054174423218, + 0.5982120633125305 + ], + [ + 0.8188145160675049, + -1.2973971366882324, + 1.243552803993225, + -0.6079679131507874, + -0.36244451999664307, + -0.12838764488697052 + ], + [ + 0.5408645272254944, + -1.3398406505584717, + 0.14272356033325195, + 0.3211787939071655, + -1.4200862646102905, + 0.7608973383903503 + ], + [ + 0.8337363600730896, + 0.1786288470029831, + 0.3121674954891205, + 1.2302255630493164, + 0.12507683038711548, + 1.026518702507019 + ] + ], + [ + [ + -0.03989891707897186, + 0.8457168936729431, + 0.8489260077476501, + 0.4735972583293915, + 0.7800946235656738, + 0.3574816882610321 + ], + [ + 0.14799346029758453, + 1.138214111328125, + 0.9666075706481934, + -0.6567904949188232, + 0.7314628958702087, + 1.6726516485214233 + ], + [ + -0.3307901918888092, + 0.752140462398529, + -1.1388487815856934, + 0.601990818977356, + 0.8349303603172302, + -0.1024642139673233 + ], + [ + 0.2129386067390442, + 0.8061029314994812, + -0.29064902663230896, + -0.08062736690044403, + 0.18424205482006073, + -0.26781368255615234 + ], + [ + -0.842875063419342, + -1.4834386110305786, + -1.013265609741211, + 1.365964651107788, + 0.5897303223609924, + 0.05003054440021515 + ], + [ + -0.7778317928314209, + -2.4351913928985596, + 0.11171633005142212, + 0.9481878280639648, + -1.2265124320983887, + 0.7861263155937195 + ] + ] + ], + [ + [ + [ + -0.11475960910320282, + 1.580405592918396, + 1.2975212335586548, + -0.33260318636894226, + -1.0625550746917725, + 0.38694456219673157 + ], + [ + 1.4818024635314941, + -0.9132123589515686, + -0.9041587114334106, + 0.8335179090499878, + 0.8654338121414185, + -0.4001701772212982 + ], + [ + -0.22977444529533386, + -0.1719079464673996, + 0.2926573157310486, + 0.9981994032859802, + -1.0177124738693237, + 1.7738550901412964 + ], + [ + -0.23209598660469055, + -0.4985274374485016, + -0.5410075187683105, + 0.6815518140792847, + -0.4239010512828827, + 1.3261003494262695 + ], + [ + 0.6056780219078064, + -0.019913967698812485, + -1.0039576292037964, + -0.8306655287742615, + 1.1431289911270142, + -0.35668206214904785 + ], + [ + 1.0129450559616089, + -0.07218152284622192, + 1.905303955078125, + 0.7196555137634277, + 1.2182841300964355, + -0.2805838882923126 + ] + ], + [ + [ + -1.4755696058273315, + 0.2024499773979187, + -0.06308790296316147, + 0.9503589868545532, + -0.6049215793609619, + 1.088989019393921 + ], + [ + -0.5790899395942688, + 1.3511621952056885, + -0.02688431739807129, + -1.4886178970336914, + -0.40090087056159973, + -0.08886078000068665 + ], + [ + 0.43563491106033325, + 0.3141688108444214, + -0.8474487066268921, + -0.5701133608818054, + -2.5571954250335693, + 0.09272336214780807 + ], + [ + 0.0977560505270958, + 0.8891482949256897, + -0.7126783132553101, + 2.1329596042633057, + -0.21151213347911835, + 0.760424017906189 + ], + [ + 0.5244688391685486, + -0.921648383140564, + 0.7664128541946411, + 0.4324735403060913, + -0.8171257972717285, + 1.0141600370407104 + ], + [ + 0.7154613733291626, + -1.0755102634429932, + -0.1033744290471077, + 0.23104271292686462, + 0.958231508731842, + 0.2724153697490692 + ] + ] + ] + ], + "weight": [ + [ + [ + [ + 0.2175293266773224, + -0.22950278222560883 + ], + [ + -0.2151593267917633, + -0.35030069947242737 + ] + ], + [ + [ + 0.11319576948881149, + -0.2659381926059723 + ], + [ + -0.29634103178977966, + -0.22661609947681427 + ] + ] + ], + [ + [ + [ + -0.34954825043678284, + -0.2878783941268921 + ], + [ + 0.3153572082519531, + 0.19748975336551666 + ] + ], + [ + [ + 0.31325748562812805, + -0.17150205373764038 + ], + [ + -0.14501044154167175, + -0.12405052036046982 + ] + ] + ], + [ + [ + [ + 0.006905086804181337, + -0.2537684142589569 + ], + [ + 0.05183164402842522, + -0.22659194469451904 + ] + ], + [ + [ + 0.05586855486035347, + 0.3238540291786194 + ], + [ + 0.05971483513712883, + 0.25789743661880493 + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + -0.5123543739318848, + -0.8977512121200562, + -0.6811044812202454, + -0.6326321363449097 + ], + [ + -0.17213934659957886, + -0.3325940668582916, + -0.7580173015594482, + -0.17347155511379242 + ], + [ + -0.49480879306793213, + 0.2566264569759369, + -0.46907752752304077, + -0.4885876476764679 + ], + [ + -0.23629358410835266, + -0.5899532437324524, + 0.4206080734729767, + 0.060480158776044846 + ] + ], + [ + [ + 0.10704323649406433, + -0.05042387172579765, + -0.18625164031982422, + 0.3011731207370758 + ], + [ + -0.46069151163101196, + 0.5142151117324829, + -0.8326210379600525, + 0.6979251503944397 + ], + [ + -0.11075891554355621, + 0.2944490909576416, + -0.24029767513275146, + 0.14378775656223297 + ], + [ + -0.15650972723960876, + -0.984201967716217, + -0.008548552170395851, + -0.16245263814926147 + ] + ], + [ + [ + -0.4029870927333832, + 0.031077677384018898, + -0.09501723945140839, + -0.13074353337287903 + ], + [ + -0.32855695486068726, + 0.03075524792075157, + 0.280192106962204, + -0.10037711262702942 + ], + [ + -0.6970707178115845, + -1.043624758720398, + 0.4967159032821655, + -0.19173437356948853 + ], + [ + -0.6817915439605713, + -0.39616724848747253, + -0.5857944488525391, + -0.167303666472435 + ] + ] + ], + [ + [ + [ + 0.12278426438570023, + -1.0920629501342773, + 0.04742713272571564, + -0.6577708125114441 + ], + [ + -0.4561113715171814, + -0.04943810775876045, + 0.5591838955879211, + -0.7580505609512329 + ], + [ + -0.5555568337440491, + 0.509503185749054, + 0.1267319768667221, + -0.10105518996715546 + ], + [ + -0.6745461225509644, + -0.799030065536499, + -0.6035346388816833, + -0.28200289607048035 + ] + ], + [ + [ + 0.11048654466867447, + 0.6832133531570435, + -0.4273984730243683, + -0.08578380942344666 + ], + [ + -0.47657740116119385, + 1.0206303596496582, + -0.4742591083049774, + 0.6080998182296753 + ], + [ + 0.054709840565919876, + 0.5148905515670776, + 0.5407938361167908, + -0.5347684025764465 + ], + [ + -0.464202880859375, + -0.8923424482345581, + -0.7441295981407166, + 0.1335189789533615 + ] + ], + [ + [ + -0.5728536248207092, + -0.4345853924751282, + -0.09404174983501434, + -0.13322682678699493 + ], + [ + -0.6174727082252502, + -0.20340797305107117, + -1.056370735168457, + -0.12856057286262512 + ], + [ + -0.12973688542842865, + 0.10348469763994217, + -0.5423545837402344, + -0.12459800392389297 + ], + [ + -0.24366001784801483, + -0.7958813905715942, + -0.19926922023296356, + -0.20502960681915283 + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533 + ], + [ + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598 + ], + [ + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533 + ], + [ + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598 + ], + [ + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533 + ], + [ + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598 + ] + ], + [ + [ + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935 + ], + [ + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445 + ], + [ + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935 + ], + [ + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445 + ], + [ + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935 + ], + [ + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445 + ] + ] + ], + [ + [ + [ + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533 + ], + [ + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598 + ], + [ + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533 + ], + [ + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598 + ], + [ + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533, + -0.37940287590026855, + 0.15202952921390533 + ], + [ + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598, + -0.7711496353149414, + -0.1251138299703598 + ] + ], + [ + [ + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935 + ], + [ + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445 + ], + [ + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935 + ], + [ + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445 + ], + [ + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935, + -0.09276917576789856, + -0.3816366493701935 + ], + [ + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445, + -0.11358621716499329, + 0.4823218286037445 + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + 1.1705816984176636, + 8.213747024536133 + ], + [ + 4.995451927185059, + -0.8214102387428284 + ] + ], + [ + [ + 4.895022869110107, + -0.20302361249923706 + ], + [ + 5.464581489562988, + -4.95082950592041 + ] + ] + ], + [ + [ + [ + 1.1705816984176636, + 8.213747024536133 + ], + [ + 4.995451927185059, + -0.8214102387428284 + ] + ], + [ + [ + 4.895022869110107, + -0.20302361249923706 + ], + [ + 5.464581489562988, + -4.95082950592041 + ] + ] + ], + [ + [ + [ + 1.1705816984176636, + 8.213747024536133 + ], + [ + 4.995451927185059, + -0.8214102387428284 + ] + ], + [ + [ + 4.895022869110107, + -0.20302361249923706 + ], + [ + 5.464581489562988, + -4.95082950592041 + ] + ] + ] + ], + "bias": [ + -0.2518039345741272, + -0.0498947873711586, + -0.218311607837677 + ], + "expected_grad_bias": [ + 32.0, + 32.0, + 32.0 + ] + }, + { + "test_name": "conv2d_dilation_no_bias", + "conv_type": "Conv2d", + "in_channels": 2, + "out_channels": 2, + "kernel_size": 2, + "stride": 1, + "padding": 0, + "dilation": 2, + "groups": 1, + "has_bias": false, + "input": [ + [ + [ + [ + 0.03995849937200546, + 1.5177383422851562, + -2.1199755668640137, + -0.600395917892456, + 0.22108443081378937 + ], + [ + 1.921225905418396, + 0.7144214510917664, + 1.472544550895691, + -0.1465783715248108, + 0.9949571490287781 + ], + [ + -2.086519479751587, + -1.8325921297073364, + 0.6720287203788757, + -0.46412497758865356, + -0.5884720087051392 + ], + [ + -0.8352398872375488, + 0.9850609302520752, + -0.23145577311515808, + 0.6784274578094482, + -1.0587496757507324 + ], + [ + 0.07416296005249023, + -1.5832154750823975, + -2.017490863800049, + 0.856982946395874, + 0.6308630108833313 + ] + ], + [ + [ + -0.6896459460258484, + -0.23252737522125244, + 1.0665576457977295, + 1.0091438293457031, + 1.4308871030807495 + ], + [ + -0.9748004078865051, + 0.9013839960098267, + -1.6900079250335693, + -1.1190448999404907, + -0.0805031880736351 + ], + [ + -0.6609653830528259, + -1.0767394304275513, + -1.3419830799102783, + 0.40884074568748474, + -0.13771961629390717 + ], + [ + -0.48222219944000244, + -0.9596375823020935, + -1.219414472579956, + 0.036487940698862076, + -1.5120867490768433 + ], + [ + 2.1745407581329346, + -0.059072766453027725, + 1.432356357574463, + -0.3214779198169708, + -0.32065340876579285 + ] + ] + ] + ], + "weight": [ + [ + [ + [ + -0.08688648790121078, + -0.1804211288690567 + ], + [ + 0.28104352951049805, + -0.2520372271537781 + ] + ], + [ + [ + 0.21281561255455017, + 0.0672207698225975 + ], + [ + -0.10753397643566132, + 0.2881980836391449 + ] + ] + ], + [ + [ + [ + 0.19674864411354065, + -0.01236567460000515 + ], + [ + -0.23963071405887604, + -0.10405980795621872 + ] + ], + [ + [ + 0.1139952540397644, + 0.3063434362411499 + ], + [ + -0.1193094253540039, + -0.14693082869052887 + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + -0.7675158381462097, + -0.16964507102966309, + 0.9092788100242615 + ], + [ + -1.2296440601348877, + 0.30054324865341187, + -0.7753838896751404 + ], + [ + 0.5374605059623718, + -0.7059400081634521, + -1.2195123434066772 + ] + ], + [ + [ + 0.9882943630218506, + 1.1445107460021973, + 0.22063326835632324 + ], + [ + 0.19188177585601807, + -0.29519984126091003, + 0.5934002995491028 + ], + [ + -1.1830170154571533, + -0.007825799286365509, + 0.23835396766662598 + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + 0.10986215621232986, + 0.10986215621232986, + -0.08292464166879654, + -0.1927867978811264, + -0.1927867978811264 + ], + [ + 0.10986215621232986, + 0.10986215621232986, + -0.08292464166879654, + -0.1927867978811264, + -0.1927867978811264 + ], + [ + 0.15127497911453247, + 0.15127497911453247, + -0.3976088762283325, + -0.548883855342865, + -0.548883855342865 + ], + [ + 0.04141281545162201, + 0.04141281545162201, + -0.3146842122077942, + -0.3560970425605774, + -0.3560970425605774 + ], + [ + 0.04141281545162201, + 0.04141281545162201, + -0.3146842122077942, + -0.3560970425605774, + -0.3560970425605774 + ] + ], + [ + [ + 0.3268108665943146, + 0.3268108665943146, + 0.7003750801086426, + 0.373564213514328, + 0.373564213514328 + ], + [ + 0.3268108665943146, + 0.3268108665943146, + 0.7003750801086426, + 0.373564213514328, + 0.373564213514328 + ], + [ + 0.09996746480464935, + 0.09996746480464935, + 0.614798903465271, + 0.5148314833641052, + 0.5148314833641052 + ], + [ + -0.22684340178966522, + -0.22684340178966522, + -0.0855761468410492, + 0.14126725494861603, + 0.14126725494861603 + ], + [ + -0.22684340178966522, + -0.22684340178966522, + -0.0855761468410492, + 0.14126725494861603, + 0.14126725494861603 + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + 0.29883068799972534, + -0.5589319467544556 + ], + [ + -6.855260372161865, + -1.52199125289917 + ] + ], + [ + [ + -4.698728084564209, + -0.45382946729660034 + ], + [ + -2.1931378841400146, + -2.9756503105163574 + ] + ] + ], + [ + [ + [ + 0.29883068799972534, + -0.5589319467544556 + ], + [ + -6.855260372161865, + -1.52199125289917 + ] + ], + [ + [ + -4.698728084564209, + -0.45382946729660034 + ], + [ + -2.1931378841400146, + -2.9756503105163574 + ] + ] + ] + ], + "bias": null, + "expected_grad_bias": null + }, + { + "test_name": "conv2d_groups", + "conv_type": "Conv2d", + "in_channels": 4, + "out_channels": 4, + "kernel_size": 3, + "stride": 1, + "padding": 1, + "dilation": 1, + "groups": 2, + "has_bias": true, + "input": [ + [ + [ + [ + 0.30319663882255554, + -0.4958910644054413, + -0.7257808446884155, + -1.3323580026626587 + ], + [ + 1.375339150428772, + 2.910996437072754, + -1.52516508102417, + -0.5475828647613525 + ], + [ + 1.3771235942840576, + 1.2624166011810303, + -0.018705634400248528, + 0.3129563331604004 + ], + [ + -1.563161849975586, + 0.908475399017334, + -0.4392400085926056, + 0.8512726426124573 + ] + ], + [ + [ + 0.42560550570487976, + 0.5939986109733582, + -0.7561457753181458, + -0.43741750717163086 + ], + [ + 0.5924250483512878, + -0.040707770735025406, + -0.14659816026687622, + 1.4060865640640259 + ], + [ + 1.1744377613067627, + -2.7486398220062256, + 0.9348365664482117, + -0.935459554195404 + ], + [ + -0.6719938516616821, + -0.020147060975432396, + -0.273457407951355, + -0.7440562844276428 + ] + ], + [ + [ + 0.8459939956665039, + -0.37988412380218506, + 0.06514627486467361, + 2.3749144077301025 + ], + [ + 0.289336234331131, + 0.6385092735290527, + 1.729801893234253, + 0.6545563340187073 + ], + [ + -0.35224831104278564, + 1.9751471281051636, + 0.40175172686576843, + -0.832302451133728 + ], + [ + 0.8574435114860535, + -0.951160728931427, + -0.2013353407382965, + -1.0537327527999878 + ] + ], + [ + [ + -0.5371747016906738, + -1.025568962097168, + 0.31649506092071533, + -0.7055220007896423 + ], + [ + 0.8945609927177429, + 0.593503475189209, + -0.7963547110557556, + 1.6775418519973755 + ], + [ + 0.6755470037460327, + 0.5524077415466309, + -0.03397471085190773, + 0.138251394033432 + ], + [ + -0.45805519819259644, + -0.1399012804031372, + 1.572408676147461, + 0.23830513656139374 + ] + ] + ] + ], + "weight": [ + [ + [ + [ + 0.16055501997470856, + 0.024069391191005707, + 0.14210942387580872 + ], + [ + 0.06072945147752762, + 0.15028801560401917, + 0.002978995442390442 + ], + [ + 0.07864969968795776, + 0.23250140249729156, + -0.07679080218076706 + ] + ], + [ + [ + -0.09591394662857056, + 0.1710985004901886, + 0.09013232588768005 + ], + [ + -0.2224813848733902, + 0.08383052796125412, + -0.23116599023342133 + ], + [ + -0.12796811759471893, + 0.09224065393209457, + 0.12416206300258636 + ] + ] + ], + [ + [ + [ + -0.05322037264704704, + 0.1995139867067337, + 0.23423711955547333 + ], + [ + 0.18379464745521545, + -0.2164824903011322, + -0.0857338011264801 + ], + [ + 0.014340324327349663, + 0.19157220423221588, + -0.039538465440273285 + ] + ], + [ + [ + 0.04923802614212036, + 0.12405998259782791, + -0.12331926077604294 + ], + [ + -0.14274021983146667, + 0.2330939918756485, + -0.00525936484336853 + ], + [ + 0.16678005456924438, + -0.22983136773109436, + -0.089967280626297 + ] + ] + ], + [ + [ + [ + 0.16538912057876587, + -0.022819316014647484, + 0.07939044386148453 + ], + [ + -0.19745250046253204, + 0.22941529750823975, + -0.11764149367809296 + ], + [ + -0.0119181452319026, + -0.15438413619995117, + -0.10457484424114227 + ] + ], + [ + [ + -0.20206452906131744, + -0.2063073366880417, + -0.048152972012758255 + ], + [ + -0.10396576672792435, + 0.17411290109157562, + -0.0011403813259676099 + ], + [ + 0.18328124284744263, + -0.03947766125202179, + 0.050005409866571426 + ] + ] + ], + [ + [ + [ + 0.22636906802654266, + -0.18238647282123566, + -0.1021074578166008 + ], + [ + 0.20150226354599, + -0.05403875187039375, + -0.06347790360450745 + ], + [ + 0.018916010856628418, + -0.12653489410877228, + 0.01695120893418789 + ] + ], + [ + [ + -0.09796470403671265, + 0.07477407157421112, + -0.0500338152050972 + ], + [ + -0.07909317314624786, + -0.08879054337739944, + 0.061237432062625885 + ], + [ + 0.11828479170799255, + -0.21548843383789062, + -0.16438578069210052 + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + -0.1379297971725464, + 0.6497488617897034, + -0.38112884759902954, + -0.437771201133728 + ], + [ + 0.10171595215797424, + 0.23069876432418823, + -0.7280157804489136, + -0.5361753106117249 + ], + [ + 0.7651550769805908, + -0.49138355255126953, + 1.0020471811294556, + -0.3403889834880829 + ], + [ + -0.34435099363327026, + -0.22472456097602844, + 0.5050238370895386, + -0.37167200446128845 + ] + ], + [ + [ + 0.1988697499036789, + 1.176051139831543, + -0.2968924045562744, + -0.20334996283054352 + ], + [ + -0.18382324278354645, + 0.6787427663803101, + -0.041671231389045715, + 0.40882623195648193 + ], + [ + 0.8475394248962402, + -0.4431191086769104, + 0.17501917481422424, + 0.10867039859294891 + ], + [ + 1.2691245079040527, + -0.4678799510002136, + 0.34053659439086914, + -0.295981228351593 + ] + ], + [ + [ + 0.20610792934894562, + -0.3903793394565582, + 0.03086024522781372, + 0.21915286779403687 + ], + [ + 0.28264015913009644, + 0.29007643461227417, + 0.5793764591217041, + 0.5104618072509766 + ], + [ + -0.21027329564094543, + 0.74181067943573, + 0.07184755802154541, + 0.46394896507263184 + ], + [ + 0.4046594500541687, + -0.4858566224575043, + 0.8705565929412842, + -0.08342111110687256 + ] + ], + [ + [ + -0.5792911648750305, + 0.1761595904827118, + -0.6771392822265625, + -0.8098530769348145 + ], + [ + -0.5884037613868713, + -0.5537676811218262, + -0.2649165391921997, + -0.4222998023033142 + ], + [ + -0.4426496624946594, + -0.9145894050598145, + -0.6739007234573364, + 0.6296873688697815 + ], + [ + -0.294874370098114, + -0.3487393856048584, + -0.059063732624053955, + -0.09920541942119598 + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + 0.5092476010322571, + 0.8028393983840942, + 0.8028393983840942, + 0.45098066329956055 + ], + [ + 1.0263112783432007, + 1.2035737037658691, + 1.2035737037658691, + 0.7587249875068665 + ], + [ + 1.0263112783432007, + 1.2035737037658691, + 1.2035737037658691, + 0.7587249875068665 + ], + [ + 0.6953932046890259, + 0.49630922079086304, + 0.49630922079086304, + 0.1587950438261032 + ] + ], + [ + [ + 0.20018544793128967, + -0.06942684948444366, + -0.06942684948444366, + 0.3424707055091858 + ], + [ + 0.10140667855739594, + -0.13401083648204803, + -0.13401083648204803, + 0.23907478153705597 + ], + [ + 0.10140667855739594, + -0.13401083648204803, + -0.13401083648204803, + 0.23907478153705597 + ], + [ + -0.14707587659358978, + -0.34930646419525146, + -0.34930646419525146, + -0.022896766662597656 + ] + ], + [ + [ + 0.3659787178039551, + 0.1621423214673996, + 0.1621423214673996, + -0.23366564512252808 + ], + [ + 0.09205755591392517, + -0.19940245151519775, + -0.19940245151519775, + -0.6022083163261414 + ], + [ + 0.09205755591392517, + -0.19940245151519775, + -0.19940245151519775, + -0.6022083163261414 + ], + [ + -0.09449483454227448, + -0.3632378578186035, + -0.3632378578186035, + -0.374285489320755 + ] + ], + [ + [ + -0.5292990207672119, + -0.5673888325691223, + -0.5673888325691223, + -0.08430065214633942 + ], + [ + -0.48269906640052795, + -0.635169267654419, + -0.635169267654419, + -0.45364707708358765 + ], + [ + -0.48269906640052795, + -0.635169267654419, + -0.635169267654419, + -0.45364707708358765 + ], + [ + -0.05113664269447327, + -0.10541994869709015, + -0.10541994869709015, + -0.22392705082893372 + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + 4.463529586791992, + 2.89654541015625, + -0.15911412239074707 + ], + [ + 3.3696036338806152, + 2.6538915634155273, + 1.1613938808441162 + ], + [ + 4.288078784942627, + 4.904724597930908, + 3.715423822402954 + ] + ], + [ + [ + 0.029211997985839844, + 0.062421560287475586, + -2.130046844482422 + ], + [ + -0.9363863468170166, + -1.647233009338379, + -3.1677074432373047 + ], + [ + -1.1998448371887207, + -1.4732739925384521, + -2.568142890930176 + ] + ] + ], + [ + [ + [ + 4.463529586791992, + 2.89654541015625, + -0.15911412239074707 + ], + [ + 3.3696036338806152, + 2.6538915634155273, + 1.1613938808441162 + ], + [ + 4.288078784942627, + 4.904724597930908, + 3.715423822402954 + ] + ], + [ + [ + 0.029211997985839844, + 0.062421560287475586, + -2.130046844482422 + ], + [ + -0.9363863468170166, + -1.647233009338379, + -3.1677074432373047 + ], + [ + -1.1998448371887207, + -1.4732739925384521, + -2.568142890930176 + ] + ] + ], + [ + [ + [ + 5.213554382324219, + 7.410722732543945, + 6.627640724182129 + ], + [ + 4.918501853942871, + 6.06193733215332, + 4.421411991119385 + ], + [ + 4.387245178222656, + 3.155766487121582, + 2.3612351417541504 + ] + ], + [ + [ + 0.639441192150116, + 1.7497124671936035, + 0.7167791128158569 + ], + [ + 1.6138933897018433, + 2.9624695777893066, + 2.387591600418091 + ], + [ + 2.8601419925689697, + 4.91424036026001, + 3.802187442779541 + ] + ] + ], + [ + [ + [ + 5.213554382324219, + 7.410722732543945, + 6.627640724182129 + ], + [ + 4.918501853942871, + 6.06193733215332, + 4.421411991119385 + ], + [ + 4.387245178222656, + 3.155766487121582, + 2.3612351417541504 + ] + ], + [ + [ + 0.639441192150116, + 1.7497124671936035, + 0.7167791128158569 + ], + [ + 1.6138933897018433, + 2.9624695777893066, + 2.387591600418091 + ], + [ + 2.8601419925689697, + 4.91424036026001, + 3.802187442779541 + ] + ] + ] + ], + "bias": [ + -0.22620761394500732, + 0.11002491414546967, + 0.17677107453346252, + -0.22646307945251465 + ], + "expected_grad_bias": [ + 16.0, + 16.0, + 16.0, + 16.0 + ] + }, + { + "test_name": "conv3d_basic", + "conv_type": "Conv3d", + "in_channels": 1, + "out_channels": 1, + "kernel_size": 3, + "stride": 1, + "padding": 0, + "dilation": 1, + "groups": 1, + "has_bias": true, + "input": [ + [ + [ + [ + [ + -0.2605237364768982, + 1.5151708126068115, + -1.521173357963562, + -1.1669979095458984, + 0.0013506141258403659 + ], + [ + -0.05947119742631912, + -0.2440771758556366, + 0.19028306007385254, + -0.19014781713485718, + -0.9898110032081604 + ], + [ + 0.3790753483772278, + 1.921068549156189, + -1.5326861143112183, + 1.1929512023925781, + -0.4898732602596283 + ], + [ + 0.12802691757678986, + -0.23840101063251495, + -0.682720422744751, + 0.46212872862815857, + -0.9165003299713135 + ], + [ + 0.0817260891199112, + 0.5295277833938599, + -0.5030823349952698, + -1.2537989616394043, + 0.1978939324617386 + ] + ], + [ + [ + -0.032255567610263824, + -0.9255485534667969, + 1.1699923276901245, + -1.6703119277954102, + -0.35372135043144226 + ], + [ + -0.871559202671051, + 0.7829732298851013, + -0.5156939625740051, + 0.022917015478014946, + -0.6746217608451843 + ], + [ + 1.309282898902893, + -0.780421257019043, + -1.1116023063659668, + -0.8699957132339478, + 0.7165693044662476 + ], + [ + -0.37322181463241577, + 0.6090918779373169, + -0.7589855194091797, + -0.6492360830307007, + -1.5364243984222412 + ], + [ + -0.23750557005405426, + 1.9767659902572632, + 0.4533178508281708, + -0.4910755455493927, + -0.32521501183509827 + ] + ], + [ + [ + 0.13093096017837524, + 0.624261200428009, + 0.8069661855697632, + 0.22351838648319244, + -0.9217655062675476 + ], + [ + 1.927629828453064, + -0.32004305720329285, + 0.20433473587036133, + -1.9621531963348389, + -0.5470468401908875 + ], + [ + -0.6754456758499146, + 0.23817801475524902, + -0.21150951087474823, + 1.2133946418762207, + -0.19310960173606873 + ], + [ + 1.5767059326171875, + 0.11904352903366089, + 0.2899794280529022, + 0.7022011280059814, + -2.0729122161865234 + ], + [ + 0.11511249840259552, + -0.6224449276924133, + 0.5478768348693848, + -1.3495665788650513, + -0.44743525981903076 + ] + ], + [ + [ + -0.7099960446357727, + -1.4830405712127686, + 2.076340913772583, + -0.12465640902519226, + 0.055092550814151764 + ], + [ + 1.2065165042877197, + 0.1894015073776245, + -0.6532776355743408, + -0.2359209805727005, + -0.8944653868675232 + ], + [ + -2.372612953186035, + -0.9387015104293823, + 0.6141673922538757, + -0.3576895296573639, + -0.9380688667297363 + ], + [ + 1.4365062713623047, + 1.5855119228363037, + -0.6202625036239624, + 0.0565016008913517, + -0.21099819242954254 + ], + [ + -1.262048602104187, + 0.021685972809791565, + 0.28762421011924744, + 0.39912644028663635, + 2.4587013721466064 + ] + ], + [ + [ + -0.2349012941122055, + -0.7608221173286438, + 0.4603550434112549, + 0.9160549640655518, + -1.498667597770691 + ], + [ + 0.6427391171455383, + 0.18222902715206146, + -1.0757185220718384, + -1.0593551397323608, + 1.0983757972717285 + ], + [ + -0.25671127438545227, + -2.2621774673461914, + 0.16864269971847534, + -1.6143133640289307, + -0.011093960143625736 + ], + [ + 1.2098065614700317, + -0.8380993604660034, + 1.3612878322601318, + -1.3062708377838135, + 1.6407432556152344 + ], + [ + -0.33931660652160645, + 0.13347899913787842, + -0.9141297936439514, + -0.15479597449302673, + 1.739033579826355 + ] + ] + ] + ] + ], + "weight": [ + [ + [ + [ + [ + 0.17951110005378723, + -0.1034713163971901, + 0.1840350478887558 + ], + [ + -0.12285948544740677, + 0.03490522876381874, + 0.056901540607213974 + ], + [ + -0.04546049237251282, + 0.15007531642913818, + -0.17448945343494415 + ] + ], + [ + [ + -0.07997027039527893, + -0.0302941482514143, + 0.1473943591117859 + ], + [ + 0.08913317322731018, + 0.12379425019025803, + 0.08283822983503342 + ], + [ + 0.17309513688087463, + -0.047928161919116974, + -0.059411607682704926 + ] + ], + [ + [ + -0.026427024975419044, + 0.07570745050907135, + -0.056436121463775635 + ], + [ + 0.07068327814340591, + 0.052763912826776505, + 0.0452510342001915 + ], + [ + 0.15679700672626495, + 0.030652407556772232, + 0.12770666182041168 + ] + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + [ + 0.5218961834907532, + -0.45145943760871887, + -0.4321322739124298 + ], + [ + 0.012468090280890465, + -0.3760489523410797, + -0.21536529064178467 + ], + [ + -0.5466360449790955, + 0.7558611631393433, + -0.5679531693458557 + ] + ], + [ + [ + 0.02960394322872162, + -0.9709864258766174, + -0.6766385436058044 + ], + [ + -0.2846550941467285, + 0.06001253053545952, + 0.20641230046749115 + ], + [ + 0.4755805432796478, + 0.14038777351379395, + 0.3236936032772064 + ] + ], + [ + [ + -0.15587808191776276, + -1.1645735502243042, + -0.10228501260280609 + ], + [ + 0.337634414434433, + -0.8189818263053894, + 0.5548167824745178 + ], + [ + -0.4976823925971985, + 0.745236873626709, + -0.8393828868865967 + ] + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + [ + 0.17951110005378723, + 0.07603978365659714, + 0.26007482409477234, + 0.0805637314915657, + 0.1840350478887558 + ], + [ + 0.05665161460638046, + -0.01191447302699089, + 0.22902211546897888, + 0.17237050831317902, + 0.24093659222126007 + ], + [ + 0.011191122233867645, + 0.09270034730434418, + 0.1591474860906601, + 0.14795635640621185, + 0.06644713878631592 + ], + [ + -0.168319970369339, + 0.016660571098327637, + -0.10092733800411224, + 0.06739263236522675, + -0.11758790910243988 + ], + [ + -0.04546049237251282, + 0.10461482405662537, + -0.06987462937831879, + -0.02441413700580597, + -0.17448945343494415 + ] + ], + [ + [ + 0.0995408296585083, + -0.03422463685274124, + 0.29720476269721985, + 0.19766393303871155, + 0.3314294219017029 + ], + [ + 0.06581451743841171, + 0.09074852615594864, + 0.5619177222251892, + 0.4961032271385193, + 0.4711691737174988 + ], + [ + 0.19344916939735413, + 0.32053032517433167, + 0.5577985048294067, + 0.36434927582740784, + 0.2372681200504303 + ], + [ + 0.09390833973884583, + 0.3547549843788147, + 0.2605936825275421, + 0.1666853427886963, + -0.09416128695011139 + ], + [ + 0.12763464450836182, + 0.22978180646896362, + -0.004119262099266052, + -0.13175390660762787, + -0.23390105366706848 + ] + ], + [ + [ + 0.0731138065457344, + 0.015055790543556213, + 0.29004907608032227, + 0.21693527698516846, + 0.27499330043792725 + ], + [ + 0.11007077246904373, + 0.2634761333465576, + 0.7234602570533752, + 0.6133894920349121, + 0.45998409390449524 + ], + [ + 0.3945024013519287, + 0.6807073354721069, + 1.0344971418380737, + 0.6399946212768555, + 0.35378968715667725 + ], + [ + 0.3213886022567749, + 0.6656515598297119, + 0.7444479465484619, + 0.423059344291687, + 0.07879640907049179 + ], + [ + 0.2844316363334656, + 0.4172312021255493, + 0.3110368251800537, + 0.026605159044265747, + -0.1061943918466568 + ] + ], + [ + [ + -0.10639729350805283, + -0.06098400056362152, + 0.02997424453496933, + 0.13637153804302216, + 0.09095823764801025 + ], + [ + 0.05341915786266327, + 0.275390625, + 0.49443814158439636, + 0.4410189986228943, + 0.21904751658439636 + ], + [ + 0.38331127166748047, + 0.5880069732666016, + 0.8753495216369629, + 0.4920382499694824, + 0.28734254837036133 + ], + [ + 0.4897086024284363, + 0.6489909887313843, + 0.8453752994537354, + 0.3556666970252991, + 0.19638431072235107 + ], + [ + 0.3298921585083008, + 0.31261640787124634, + 0.3809114694595337, + 0.051019296050071716, + 0.06829505413770676 + ] + ], + [ + [ + -0.026427024975419044, + 0.049280427396297455, + -0.00715569406747818, + 0.019271329045295715, + -0.056436121463775635 + ], + [ + 0.04425625503063202, + 0.17272761464118958, + 0.16154253482818604, + 0.11728627234697342, + -0.011185087263584137 + ], + [ + 0.20105326175689697, + 0.36017704010009766, + 0.4766985774040222, + 0.27564534544944763, + 0.11652157455682755 + ], + [ + 0.22748029232025146, + 0.3108966052532196, + 0.4838542938232422, + 0.2563740015029907, + 0.17295768857002258 + ], + [ + 0.15679700672626495, + 0.1874494105577469, + 0.31515607237815857, + 0.15835906565189362, + 0.12770666182041168 + ] + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + [ + 2.138136148452759, + -2.9163527488708496, + -9.179944038391113 + ], + [ + 1.2998350858688354, + -2.119128704071045, + -10.910270690917969 + ], + [ + 2.546753406524658, + -0.8000010251998901, + -9.619416236877441 + ] + ], + [ + [ + -0.32073187828063965, + -3.9941210746765137, + -5.132316589355469 + ], + [ + 1.885986566543579, + -3.3577966690063477, + -11.19390869140625 + ], + [ + 1.2160885334014893, + 0.35297536849975586, + -4.404627323150635 + ] + ], + [ + [ + -2.482264518737793, + -5.141534328460693, + -4.461568832397461 + ], + [ + 2.728120803833008, + -6.530619144439697, + -6.614537239074707 + ], + [ + -1.607851505279541, + -3.451260566711426, + 1.077123999595642 + ] + ] + ] + ] + ], + "bias": [ + -0.05365540832281113 + ], + "expected_grad_bias": [ + 27.0 + ] + }, + { + "test_name": "conv3d_stride_padding", + "conv_type": "Conv3d", + "in_channels": 2, + "out_channels": 3, + "kernel_size": 2, + "stride": 2, + "padding": 1, + "dilation": 1, + "groups": 1, + "has_bias": true, + "input": [ + [ + [ + [ + [ + 0.6205294132232666, + -1.4098610877990723, + -0.41539478302001953, + 3.068681478500366 + ], + [ + -0.9697644114494324, + -0.6346449851989746, + -1.3389408588409424, + -0.8127626180648804 + ], + [ + -0.48385927081108093, + 0.032833296805620193, + -0.10948953032493591, + 0.46667027473449707 + ], + [ + -0.397339403629303, + -1.1817593574523926, + -0.626708984375, + 0.2615565061569214 + ] + ], + [ + [ + -1.9243427515029907, + 0.5441842079162598, + 1.674156904220581, + -0.1457550972700119 + ], + [ + -0.5444673299789429, + 0.276648610830307, + 0.25740426778793335, + 0.7235954999923706 + ], + [ + -0.7049512267112732, + 2.053586959838867, + 0.9570578932762146, + -1.0222344398498535 + ], + [ + -1.2120782136917114, + 0.5006001591682434, + -0.4498424530029297, + 0.7352223992347717 + ] + ], + [ + [ + -0.6102548837661743, + -1.5060930252075195, + -0.7732543349266052, + 1.0847911834716797 + ], + [ + 0.5897902846336365, + -0.1373262107372284, + -1.664083480834961, + -0.6784767508506775 + ], + [ + 1.959293246269226, + -0.7958163619041443, + 0.4539487659931183, + -2.5069937705993652 + ], + [ + -0.3836418688297272, + -0.7841960787773132, + -1.3441016674041748, + -0.6836838722229004 + ] + ], + [ + [ + -0.5332193970680237, + 1.0821458101272583, + 0.6407410502433777, + -1.729612946510315 + ], + [ + -1.380746603012085, + 1.090315580368042, + 1.5219553709030151, + -1.1226063966751099 + ], + [ + -1.0745846033096313, + -0.6819858551025391, + 1.0070197582244873, + -0.8279359936714172 + ], + [ + 1.0574713945388794, + 0.07679933309555054, + 0.135556161403656, + 0.48973140120506287 + ] + ] + ], + [ + [ + [ + -1.9717178344726562, + 0.5998077988624573, + 1.361150860786438, + -0.173064723610878 + ], + [ + -0.19370204210281372, + 1.1805676221847534, + 0.9929208755493164, + 0.3026696443557739 + ], + [ + 0.11924134939908981, + 0.1167483851313591, + -0.5673035979270935, + -1.7532938718795776 + ], + [ + -0.503811240196228, + -1.0558961629867554, + -0.9048318862915039, + -0.006893915124237537 + ] + ], + [ + [ + 1.0234973430633545, + -0.5307855606079102, + 2.509202480316162, + 0.9496951103210449 + ], + [ + -0.6222965717315674, + -0.6353561282157898, + -2.6204559803009033, + 1.2924344539642334 + ], + [ + -1.1843920946121216, + -0.13271500170230865, + -0.6129738092422485, + 1.0654757022857666 + ], + [ + -0.578273355960846, + -0.59147047996521, + 0.09498756378889084, + -0.4672579765319824 + ] + ], + [ + [ + 0.33264845609664917, + 1.1230510473251343, + 1.8761743307113647, + 0.273639976978302 + ], + [ + 1.1153037548065186, + -0.0976748913526535, + 1.1017417907714844, + 0.7865778803825378 + ], + [ + -1.3129955530166626, + -0.48624828457832336, + 0.4012764096260071, + 1.0767757892608643 + ], + [ + -0.1310465782880783, + 0.4173567295074463, + -0.39924731850624084, + -0.03817286342382431 + ] + ], + [ + [ + -0.879487931728363, + -0.33060166239738464, + 0.6457027792930603, + 0.17840361595153809 + ], + [ + -2.1722629070281982, + 0.387355238199234, + 0.8891183733940125, + -0.09997355192899704 + ], + [ + -0.4065081775188446, + -0.30150434374809265, + -1.5348396301269531, + 1.6021355390548706 + ], + [ + 0.8561490178108215, + 1.2442771196365356, + 1.471459150314331, + -0.3713514506816864 + ] + ] + ] + ], + [ + [ + [ + [ + 0.19821691513061523, + 0.38515371084213257, + -0.07315804064273834, + 0.8780375719070435 + ], + [ + 0.5718429088592529, + 0.11539655178785324, + 0.4864003360271454, + -1.3612200021743774 + ], + [ + -1.2953417301177979, + -1.5002580881118774, + 1.1558160781860352, + -0.7528656125068665 + ], + [ + 0.9919346570968628, + -1.7107722759246826, + -0.31297874450683594, + -0.1376810520887375 + ] + ], + [ + [ + 1.4542961120605469, + 0.21978320181369781, + -0.26515746116638184, + 0.7749262452125549 + ], + [ + 0.2638930678367615, + -0.34526365995407104, + 1.8549134731292725, + -0.44352102279663086 + ], + [ + -0.05403977632522583, + 0.07127834856510162, + -0.8058504462242126, + -0.35074129700660706 + ], + [ + -0.023307736963033676, + 0.9396457672119141, + 0.5839836597442627, + 1.0035940408706665 + ] + ], + [ + [ + 1.9742354154586792, + -0.4404173791408539, + 2.3815414905548096, + -0.34589144587516785 + ], + [ + 0.12100548297166824, + -0.12694284319877625, + 0.2732967436313629, + -0.4074859023094177 + ], + [ + -0.43923330307006836, + 1.1729096174240112, + 1.397361159324646, + -0.41255858540534973 + ], + [ + 0.6318085193634033, + 1.6719400882720947, + 1.4667576551437378, + -0.46806567907333374 + ] + ], + [ + [ + 1.5237687826156616, + 1.2984881401062012, + 0.6588833928108215, + -0.8222662210464478 + ], + [ + -2.1720073223114014, + -0.23861387372016907, + 0.29227569699287415, + 0.5224646925926208 + ], + [ + 0.5731524229049683, + 1.3903805017471313, + -0.23513318598270416, + -0.5386273264884949 + ], + [ + -1.4448024034500122, + -0.7072859406471252, + -0.8268908262252808, + -0.8726862072944641 + ] + ] + ], + [ + [ + [ + 1.9504122734069824, + 1.0814120769500732, + 0.7843427658081055, + 1.8615505695343018 + ], + [ + 0.7698028087615967, + -0.9483721852302551, + -0.046345002949237823, + 0.4453408420085907 + ], + [ + -0.3184575140476227, + 1.1182889938354492, + 1.8907326459884644, + 0.19988827407360077 + ], + [ + 0.6960347890853882, + -0.821993350982666, + -0.7360109686851501, + 0.25674745440483093 + ] + ], + [ + [ + -0.9977543950080872, + 0.45807182788848877, + 0.7924372553825378, + -0.9643475413322449 + ], + [ + -0.27225175499916077, + 0.5005932450294495, + 1.8431296348571777, + -0.17798323929309845 + ], + [ + 0.7460726499557495, + 0.26590028405189514, + -1.0854178667068481, + -1.5084643363952637 + ], + [ + 0.8140530586242676, + -0.6385701298713684, + -0.3107047379016876, + -0.5998176336288452 + ] + ], + [ + [ + 0.5251074433326721, + -0.8383287787437439, + 1.7227904796600342, + -1.1731188297271729 + ], + [ + 0.1619594246149063, + 1.0863298177719116, + 0.29311972856521606, + -1.1984928846359253 + ], + [ + -0.20503655076026917, + -0.5375787019729614, + 1.2967820167541504, + -1.6138769388198853 + ], + [ + -0.8897020220756531, + -1.540779709815979, + 0.5420194268226624, + 0.7579821944236755 + ] + ], + [ + [ + -1.1333380937576294, + -0.7435185313224792, + -0.7013434171676636, + -0.42178988456726074 + ], + [ + -1.4793615341186523, + -1.5361236333847046, + -0.3792397677898407, + 0.2467799037694931 + ], + [ + 0.019135747104883194, + -0.7149955034255981, + -0.7025302648544312, + 0.7700265645980835 + ], + [ + 0.2053217887878418, + 0.5622282028198242, + -0.9420557022094727, + 2.099351644515991 + ] + ] + ] + ] + ], + "weight": [ + [ + [ + [ + [ + -0.24626165628433228, + 0.23581910133361816 + ], + [ + -0.13763979077339172, + 0.057132333517074585 + ] + ], + [ + [ + 0.15548455715179443, + -0.038823604583740234 + ], + [ + 0.19538354873657227, + 0.16201353073120117 + ] + ] + ], + [ + [ + [ + -0.050332069396972656, + 0.06554695963859558 + ], + [ + 0.018945902585983276, + 0.2445722222328186 + ] + ], + [ + [ + 0.17308229207992554, + -0.1665104329586029 + ], + [ + 0.024087965488433838, + 0.13483983278274536 + ] + ] + ] + ], + [ + [ + [ + [ + 0.1911259889602661, + 0.08535802364349365 + ], + [ + 0.10622924566268921, + -0.046158403158187866 + ] + ], + [ + [ + 0.005422472953796387, + -0.17302614450454712 + ], + [ + 0.20581024885177612, + 0.19685980677604675 + ] + ] + ], + [ + [ + [ + -0.1376614272594452, + -0.2140360176563263 + ], + [ + 0.19494691491127014, + -0.22157776355743408 + ] + ], + [ + [ + 0.16033044457435608, + -0.2435099482536316 + ], + [ + -0.12781327962875366, + -0.10584864020347595 + ] + ] + ] + ], + [ + [ + [ + [ + 0.23495128750801086, + -0.042303770780563354 + ], + [ + 0.21564671397209167, + 0.07263556122779846 + ] + ], + [ + [ + 0.242195725440979, + 0.165586918592453 + ], + [ + 0.1841185986995697, + 0.21796229481697083 + ] + ] + ], + [ + [ + [ + -0.07386279106140137, + -0.06873634457588196 + ], + [ + 0.08055216073989868, + 0.22023555636405945 + ] + ], + [ + [ + -0.0920020043849945, + -0.1966536045074463 + ], + [ + -0.19556531310081482, + -0.11550003290176392 + ] + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + [ + -0.12544064223766327, + -0.10488642007112503, + 0.6352924108505249 + ], + [ + 0.04748120158910751, + -0.05280660092830658, + 0.014852432534098625 + ], + [ + 0.13920727372169495, + -0.1516159176826477, + 0.07936608046293259 + ] + ], + [ + [ + 0.12625285983085632, + 0.5247550010681152, + 0.29648762941360474 + ], + [ + -0.527458667755127, + -0.6843790411949158, + -0.4757048189640045 + ], + [ + -0.24712897837162018, + -0.08450428396463394, + -0.23055703938007355 + ] + ], + [ + [ + -0.20567108690738678, + 0.07920943200588226, + 0.28133490681648254 + ], + [ + -0.5889145135879517, + -0.06061249226331711, + 0.46568891406059265 + ], + [ + 0.3453812003135681, + 0.08676793426275253, + -0.06201987341046333 + ] + ] + ], + [ + [ + [ + 0.30193081498146057, + -0.6216078996658325, + 0.6247559785842896 + ], + [ + 0.07815887033939362, + 0.17712479829788208, + 0.3353296220302582 + ], + [ + 0.16250303387641907, + 0.1241421103477478, + -0.028617149218916893 + ] + ], + [ + [ + -0.3222348392009735, + -1.5121803283691406, + 0.3290128707885742 + ], + [ + 0.5038116574287415, + 0.9266672134399414, + -0.5005884766578674 + ], + [ + 0.08967182040214539, + 0.481889933347702, + 0.1660858392715454 + ] + ], + [ + [ + 0.19055739045143127, + -0.15107333660125732, + -0.17788636684417725 + ], + [ + 0.4578288495540619, + 0.22812111675739288, + -0.005346504505723715 + ], + [ + -0.12191318720579147, + -0.48891517519950867, + 0.11579104512929916 + ] + ] + ], + [ + [ + [ + 0.29631558060646057, + -0.6913065314292908, + 0.5321769118309021 + ], + [ + -0.3083934485912323, + -0.7210930585861206, + 0.13744239509105682 + ], + [ + -0.03338782861828804, + -0.18157877027988434, + -0.002687789499759674 + ] + ], + [ + [ + -0.15246857702732086, + -0.20002339780330658, + 0.12461421638727188 + ], + [ + 0.1441238522529602, + 0.0658457800745964, + -1.0355932712554932 + ], + [ + -0.013401327654719353, + -0.2652435004711151, + -0.021488817408680916 + ] + ], + [ + [ + -0.29909512400627136, + 0.32880789041519165, + -0.4252844750881195 + ], + [ + -0.026526324450969696, + -0.40084484219551086, + -0.3725295960903168 + ], + [ + -0.17025350034236908, + -0.24740883708000183, + 0.07582216709852219 + ] + ] + ] + ], + [ + [ + [ + [ + 0.33499839901924133, + 0.23510107398033142, + 0.2562863826751709 + ], + [ + -0.3632935583591461, + 0.05853582173585892, + -0.23695941269397736 + ], + [ + -0.1145162284374237, + -0.23367537558078766, + 0.06292246282100677 + ] + ], + [ + [ + 0.2696138620376587, + 0.7088768482208252, + -0.1808793544769287 + ], + [ + 0.13318367302417755, + 1.0680162906646729, + -0.21250930428504944 + ], + [ + 0.21136917173862457, + -0.19593563675880432, + -0.11864905059337616 + ] + ], + [ + [ + -0.15023523569107056, + -0.28680452704429626, + 0.1450766623020172 + ], + [ + -0.5318515300750732, + -0.17013579607009888, + -0.012467258609831333 + ], + [ + -0.2873624861240387, + -0.0709749385714531, + 0.14913572371006012 + ] + ] + ], + [ + [ + [ + -0.19635766744613647, + -0.18530386686325073, + -0.08615187555551529 + ], + [ + -0.5366209745407104, + -0.6775302886962891, + -0.14540544152259827 + ], + [ + -0.37005215883255005, + 0.06338219344615936, + 0.011487733572721481 + ] + ], + [ + [ + 0.4580877721309662, + 0.2233516424894333, + -0.05585471913218498 + ], + [ + -0.23609213531017303, + 0.4398602545261383, + -0.4935249388217926 + ], + [ + -0.09782442450523376, + -0.26882562041282654, + 0.3644440770149231 + ] + ], + [ + [ + 0.1518576592206955, + 0.08904975652694702, + -0.1985054910182953 + ], + [ + 0.0716124176979065, + 0.41787996888160706, + 0.12985070049762726 + ], + [ + -0.1962018609046936, + -0.11045592278242111, + -0.48472288250923157 + ] + ] + ], + [ + [ + [ + -0.24873878061771393, + -0.31377995014190674, + -0.2690615952014923 + ], + [ + -0.3689185082912445, + -0.3231930732727051, + -0.6150315999984741 + ], + [ + -0.03929625824093819, + -0.3124725818634033, + -0.12363695353269577 + ] + ], + [ + [ + 0.18888165056705475, + 0.5758501887321472, + 0.1884964108467102 + ], + [ + 0.01739897020161152, + -0.3179147243499756, + -0.10364465415477753 + ], + [ + 0.15794339776039124, + 0.8808969855308533, + 0.030330616980791092 + ] + ], + [ + [ + -0.20559145510196686, + 0.04685036838054657, + -0.2779650092124939 + ], + [ + 0.1727457195520401, + 0.07486840337514877, + -0.016269924119114876 + ], + [ + -0.019662391394376755, + -0.17464134097099304, + -0.4267726540565491 + ] + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ], + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ] + ], + [ + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ], + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ] + ], + [ + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ], + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ] + ], + [ + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ], + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ] + ] + ], + [ + [ + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ], + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ] + ], + [ + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ], + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ] + ], + [ + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ], + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ] + ], + [ + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ], + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ] + ] + ] + ], + [ + [ + [ + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ], + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ] + ], + [ + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ], + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ] + ], + [ + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ], + [ + 0.5768356323242188, + 0.5853123664855957, + 0.5768356323242188, + 0.5853123664855957 + ], + [ + -0.04626283049583435, + 0.4031027555465698, + -0.04626283049583435, + 0.4031027555465698 + ] + ], + [ + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ], + [ + 0.08360949158668518, + 0.18423616886138916, + 0.08360949158668518, + 0.18423616886138916 + ], + [ + 0.27887335419654846, + 0.1798156201839447, + 0.27887335419654846, + 0.1798156201839447 + ] + ] + ], + [ + [ + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ], + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ] + ], + [ + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ], + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ] + ], + [ + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ], + [ + -0.0865088403224945, + -0.29929062724113464, + -0.0865088403224945, + -0.29929062724113464 + ], + [ + -0.6066739559173584, + 0.2414107322692871, + -0.6066739559173584, + 0.2414107322692871 + ] + ], + [ + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ], + [ + 0.24323001503944397, + 0.2944449782371521, + 0.24323001503944397, + 0.2944449782371521 + ], + [ + -0.21722540259361267, + -0.2618562877178192, + -0.21722540259361267, + -0.2618562877178192 + ] + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + [ + 2.6286404132843018, + -2.0866897106170654 + ], + [ + 1.3156142234802246, + 2.8917975425720215 + ] + ], + [ + [ + -7.076124668121338, + -1.9047226905822754 + ], + [ + -2.5816783905029297, + 5.9409565925598145 + ] + ] + ], + [ + [ + [ + 1.2151155471801758, + -3.202683687210083 + ], + [ + -0.35901355743408203, + -3.502537488937378 + ] + ], + [ + [ + -0.4747035503387451, + 1.8682055473327637 + ], + [ + 0.875652551651001, + 7.885148048400879 + ] + ] + ] + ], + [ + [ + [ + [ + 2.6286404132843018, + -2.0866897106170654 + ], + [ + 1.3156142234802246, + 2.8917975425720215 + ] + ], + [ + [ + -7.076124668121338, + -1.9047226905822754 + ], + [ + -2.5816783905029297, + 5.9409565925598145 + ] + ] + ], + [ + [ + [ + 1.2151155471801758, + -3.202683687210083 + ], + [ + -0.35901355743408203, + -3.502537488937378 + ] + ], + [ + [ + -0.4747035503387451, + 1.8682055473327637 + ], + [ + 0.875652551651001, + 7.885148048400879 + ] + ] + ] + ], + [ + [ + [ + [ + 2.6286404132843018, + -2.0866897106170654 + ], + [ + 1.3156142234802246, + 2.8917975425720215 + ] + ], + [ + [ + -7.076124668121338, + -1.9047226905822754 + ], + [ + -2.5816783905029297, + 5.9409565925598145 + ] + ] + ], + [ + [ + [ + 1.2151155471801758, + -3.202683687210083 + ], + [ + -0.35901355743408203, + -3.502537488937378 + ] + ], + [ + [ + -0.4747035503387451, + 1.8682055473327637 + ], + [ + 0.875652551651001, + 7.885148048400879 + ] + ] + ] + ] + ], + "bias": [ + 0.03989130258560181, + -0.02893012762069702, + -0.06666991114616394 + ], + "expected_grad_bias": [ + 54.0, + 54.0, + 54.0 + ] + }, + { + "test_name": "conv3d_dilation_no_bias", + "conv_type": "Conv3d", + "in_channels": 2, + "out_channels": 2, + "kernel_size": 2, + "stride": 1, + "padding": 0, + "dilation": 2, + "groups": 1, + "has_bias": false, + "input": [ + [ + [ + [ + [ + -2.0308878421783447, + 0.6461803913116455, + 1.217452883720398, + 0.03121299482882023, + -0.5765647292137146 + ], + [ + -1.4563747644424438, + 1.5021625757217407, + 1.0934816598892212, + -0.6195639967918396, + 1.8281400203704834 + ], + [ + 0.4877544343471527, + 0.1366790533065796, + -0.013499530963599682, + -0.6400911808013916, + -1.3593297004699707 + ], + [ + 1.311326026916504, + 0.8920031785964966, + 1.8720558881759644, + 0.24501417577266693, + 0.7017510533332825 + ], + [ + 0.43805480003356934, + -1.3179324865341187, + -2.430510997772217, + -1.3101704120635986, + -1.439155101776123 + ] + ], + [ + [ + -1.2797472476959229, + -0.19622953236103058, + 0.19903564453125, + 0.8379256725311279, + 0.27458760142326355 + ], + [ + 0.02786351554095745, + -0.3553343415260315, + -1.2540193796157837, + -1.2696188688278198, + 0.6492337584495544 + ], + [ + 0.2340298593044281, + -1.1880178451538086, + 0.7492989897727966, + 0.9463486075401306, + -1.4556224346160889 + ], + [ + -1.865479826927185, + -2.1207547187805176, + -0.6719433665275574, + -0.7559810280799866, + 0.37926021218299866 + ], + [ + 1.0466166734695435, + -1.5519970655441284, + 0.3812021315097809, + 0.350207656621933, + -0.2644238770008087 + ] + ], + [ + [ + -1.0631657838821411, + -0.7474985122680664, + 0.5845747590065002, + 1.3839225769042969, + -1.3397178649902344 + ], + [ + 0.6717097163200378, + 0.4279913902282715, + 1.0040385723114014, + 1.708235263824463, + -0.2667044997215271 + ], + [ + 0.927609920501709, + -0.5422874093055725, + -1.4597265720367432, + 0.8100371360778809, + 1.5311497449874878 + ], + [ + 0.44362834095954895, + -2.4579336643218994, + 0.6496618390083313, + 0.8869423866271973, + -0.07573819905519485 + ], + [ + 0.21659345924854279, + 1.0110455751419067, + -0.7884382605552673, + 1.1371253728866577, + -1.7366209030151367 + ] + ], + [ + [ + 0.9614791870117188, + 0.7572482824325562, + 0.17160733044147491, + 0.36760959029197693, + 0.609169602394104 + ], + [ + 0.5307507514953613, + 1.0079243183135986, + 1.6095112562179565, + 1.6016820669174194, + 1.1434932947158813 + ], + [ + -0.8632990717887878, + -1.0004771947860718, + 0.19994869828224182, + -0.754463255405426, + -0.3379971385002136 + ], + [ + 0.41659975051879883, + 0.22890278697013855, + 0.2294260412454605, + 0.4791496992111206, + 0.007589681074023247 + ], + [ + 0.38356420397758484, + 0.7159355282783508, + 0.3418067395687103, + -0.6778577566146851, + 0.17783714830875397 + ] + ], + [ + [ + 1.4312905073165894, + -3.104058265686035, + 1.1158103942871094, + 0.28317660093307495, + -1.5755101442337036 + ], + [ + -1.1856271028518677, + 0.3281179666519165, + -0.03522142022848129, + 1.5343668460845947, + 1.1684390306472778 + ], + [ + -0.5797900557518005, + 0.7235100865364075, + -0.48095330595970154, + 0.13058727979660034, + 0.8354679346084595 + ], + [ + 1.6123450994491577, + 0.3398834466934204, + -0.18680495023727417, + -0.4996188282966614, + 1.1609336137771606 + ], + [ + 0.7856671810150146, + 0.8128212690353394, + 0.04477962106466293, + -1.7439521551132202, + -1.7851803302764893 + ] + ] + ], + [ + [ + [ + -0.24107103049755096, + 0.42683982849121094, + 0.11223956197500229, + 0.7528783082962036, + -0.8849666118621826 + ], + [ + 0.8982152342796326, + -1.6744109392166138, + -0.7241051197052002, + 0.8363932371139526, + 1.5363035202026367 + ], + [ + -0.7425072193145752, + 0.8354768753051758, + -1.2516489028930664, + 0.26434803009033203, + 1.2949540615081787 + ], + [ + 1.175123691558838, + -0.7680397629737854, + 0.178359717130661, + -1.5190868377685547, + -0.20686893165111542 + ], + [ + 1.5211719274520874, + -1.2341058254241943, + -0.7871248126029968, + -1.4083248376846313, + -1.2565326690673828 + ] + ], + [ + [ + -1.2300301790237427, + -0.29269593954086304, + 0.21912771463394165, + -0.45708730816841125, + -0.651996910572052 + ], + [ + -0.32107922434806824, + -0.3210636079311371, + 2.49674916267395, + 1.3230384588241577, + -0.061925552785396576 + ], + [ + 0.9091914892196655, + -0.6015433669090271, + 0.8525826930999756, + -0.6866192817687988, + -0.21939978003501892 + ], + [ + 0.21570608019828796, + 2.041553020477295, + -0.4606938660144806, + 1.8315014839172363, + -0.7265217900276184 + ], + [ + -0.44100794196128845, + -1.1563644409179688, + -0.845207929611206, + 2.3356547355651855, + 0.0955897644162178 + ] + ], + [ + [ + 1.1224497556686401, + -1.0052590370178223, + 1.2696419954299927, + 1.212203025817871, + -0.3618496060371399 + ], + [ + 0.5468137264251709, + 0.9894823431968689, + 0.7208108901977539, + -0.4930783212184906, + -0.6638585925102234 + ], + [ + -2.0399112701416016, + -0.6206883192062378, + -0.9584940075874329, + 0.7993512749671936, + -0.23935280740261078 + ], + [ + -0.07818234711885452, + 0.6661496162414551, + 1.0709624290466309, + 1.3384746313095093, + 0.27829068899154663 + ], + [ + -1.328766107559204, + 0.09645214676856995, + -1.5012465715408325, + -1.362809658050537, + 1.5265393257141113 + ] + ], + [ + [ + -0.5563327670097351, + 2.0752601623535156, + -0.8403553366661072, + 0.9517558813095093, + 1.3194047212600708 + ], + [ + -0.8734123110771179, + 0.6210753917694092, + 2.9574992656707764, + 0.13751773536205292, + -0.15331187844276428 + ], + [ + 1.2169883251190186, + 1.7785981893539429, + -1.6149650812149048, + -0.5684998035430908, + 2.5527584552764893 + ], + [ + -0.04084712266921997, + 0.3193606436252594, + -0.6905565857887268, + 0.3500501811504364, + -0.32124459743499756 + ], + [ + -0.7468457221984863, + 1.2974729537963867, + -0.8983440399169922, + -0.38374435901641846, + 0.6814237833023071 + ] + ], + [ + [ + 2.0168917179107666, + 0.481290727853775, + 0.313506156206131, + 0.41611549258232117, + 1.0470067262649536 + ], + [ + -1.400732398033142, + -0.47914406657218933, + 2.1447153091430664, + -0.34384623169898987, + 0.41149622201919556 + ], + [ + 0.41322529315948486, + -2.1648738384246826, + 0.9794597625732422, + 0.38047143816947937, + -1.9277540445327759 + ], + [ + 0.9197121858596802, + -1.6067678928375244, + -1.425918698310852, + 0.783023476600647, + 0.0861901044845581 + ], + [ + -0.37659966945648193, + 0.9756653904914856, + -0.8411983847618103, + -0.9621247053146362, + -0.5808306932449341 + ] + ] + ] + ] + ], + "weight": [ + [ + [ + [ + [ + -0.11476090550422668, + -0.24131369590759277 + ], + [ + -0.10875487327575684, + 0.07968631386756897 + ] + ], + [ + [ + 0.20207053422927856, + -0.2464660108089447 + ], + [ + -0.0899374783039093, + 0.15728631615638733 + ] + ] + ], + [ + [ + [ + -0.1351938247680664, + 0.16879567503929138 + ], + [ + 0.010089278221130371, + -0.2350514531135559 + ] + ], + [ + [ + 0.042271971702575684, + -0.149849534034729 + ], + [ + 0.04858878254890442, + -0.22400259971618652 + ] + ] + ] + ], + [ + [ + [ + [ + 0.23491546511650085, + -0.10666635632514954 + ], + [ + 0.15988940000534058, + -0.15729418396949768 + ] + ], + [ + [ + -0.20952555537223816, + 0.09835821390151978 + ], + [ + 0.15029987692832947, + -0.002248615026473999 + ] + ] + ], + [ + [ + [ + -0.21142640709877014, + -0.06857553124427795 + ], + [ + -0.17324388027191162, + 0.07081684470176697 + ] + ], + [ + [ + 0.04048082232475281, + 0.1737305223941803 + ], + [ + 0.24955525994300842, + -0.11556816101074219 + ] + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + [ + -0.4757484495639801, + -0.8812041282653809, + 0.3463735580444336 + ], + [ + -0.7419395446777344, + 0.4907858073711395, + 0.01124744862318039 + ], + [ + 0.5282792448997498, + 0.37058907747268677, + -0.13969454169273376 + ] + ], + [ + [ + 0.9295258522033691, + 0.3352668285369873, + -1.4362306594848633 + ], + [ + 0.40583908557891846, + 0.1808263659477234, + 0.11902815103530884 + ], + [ + 0.17801764607429504, + -0.36842218041419983, + -0.5066997408866882 + ] + ], + [ + [ + -0.13931676745414734, + -0.9522701501846313, + 1.475050449371338 + ], + [ + -0.9424186944961548, + -1.2914557456970215, + -0.5469567775726318 + ], + [ + 0.5914638042449951, + 0.26857104897499084, + -0.7077885270118713 + ] + ] + ], + [ + [ + [ + -0.15289494395256042, + 0.13514970242977142, + 0.2045574188232422 + ], + [ + -0.8474478125572205, + 0.5180610418319702, + 0.26316726207733154 + ], + [ + -0.2188991904258728, + 0.6530547142028809, + -0.0868012011051178 + ] + ], + [ + [ + -0.24735553562641144, + 0.16227149963378906, + -0.24669215083122253 + ], + [ + 0.4316696226596832, + -0.3470993936061859, + -1.2586170434951782 + ], + [ + -0.2081446349620819, + 0.44266369938850403, + 0.47282782196998596 + ] + ], + [ + [ + -0.1232089102268219, + 0.05044287443161011, + -0.08964276313781738 + ], + [ + 1.141706943511963, + -1.2464135885238647, + -0.00848311185836792 + ], + [ + 1.535451889038086, + 0.05266711115837097, + -0.016254477202892303 + ] + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + [ + 0.12015455961227417, + 0.12015455961227417, + -0.22782549262046814, + -0.3479800522327423, + -0.3479800522327423 + ], + [ + 0.12015455961227417, + 0.12015455961227417, + -0.22782549262046814, + -0.3479800522327423, + -0.3479800522327423 + ], + [ + 0.1712890863418579, + 0.1712890863418579, + -0.2542988359928131, + -0.425587922334671, + -0.425587922334671 + ], + [ + 0.05113452672958374, + 0.05113452672958374, + -0.02647334337234497, + -0.07760787010192871, + -0.07760787010192871 + ], + [ + 0.05113452672958374, + 0.05113452672958374, + -0.02647334337234497, + -0.07760787010192871, + -0.07760787010192871 + ] + ], + [ + [ + 0.12015455961227417, + 0.12015455961227417, + -0.22782549262046814, + -0.3479800522327423, + -0.3479800522327423 + ], + [ + 0.12015455961227417, + 0.12015455961227417, + -0.22782549262046814, + -0.3479800522327423, + -0.3479800522327423 + ], + [ + 0.1712890863418579, + 0.1712890863418579, + -0.2542988359928131, + -0.425587922334671, + -0.425587922334671 + ], + [ + 0.05113452672958374, + 0.05113452672958374, + -0.02647334337234497, + -0.07760787010192871, + -0.07760787010192871 + ], + [ + 0.05113452672958374, + 0.05113452672958374, + -0.02647334337234497, + -0.07760787010192871, + -0.07760787010192871 + ] + ], + [ + [ + 0.11269953846931458, + 0.11269953846931458, + -0.38338831067085266, + -0.49608784914016724, + -0.49608784914016724 + ], + [ + 0.11269953846931458, + 0.11269953846931458, + -0.38338831067085266, + -0.49608784914016724, + -0.49608784914016724 + ], + [ + 0.22419646382331848, + 0.22419646382331848, + -0.19446155428886414, + -0.4186580181121826, + -0.4186580181121826 + ], + [ + 0.1114969253540039, + 0.1114969253540039, + 0.18892675638198853, + 0.07742983102798462, + 0.07742983102798462 + ], + [ + 0.1114969253540039, + 0.1114969253540039, + 0.18892675638198853, + 0.07742983102798462, + 0.07742983102798462 + ] + ], + [ + [ + -0.007455021142959595, + -0.007455021142959595, + -0.15556281805038452, + -0.14810779690742493, + -0.14810779690742493 + ], + [ + -0.007455021142959595, + -0.007455021142959595, + -0.15556281805038452, + -0.14810779690742493, + -0.14810779690742493 + ], + [ + 0.05290737748146057, + 0.05290737748146057, + 0.059837281703948975, + 0.006929904222488403, + 0.006929904222488403 + ], + [ + 0.060362398624420166, + 0.060362398624420166, + 0.2154000997543335, + 0.15503770112991333, + 0.15503770112991333 + ], + [ + 0.060362398624420166, + 0.060362398624420166, + 0.2154000997543335, + 0.15503770112991333, + 0.15503770112991333 + ] + ], + [ + [ + -0.007455021142959595, + -0.007455021142959595, + -0.15556281805038452, + -0.14810779690742493, + -0.14810779690742493 + ], + [ + -0.007455021142959595, + -0.007455021142959595, + -0.15556281805038452, + -0.14810779690742493, + -0.14810779690742493 + ], + [ + 0.05290737748146057, + 0.05290737748146057, + 0.059837281703948975, + 0.006929904222488403, + 0.006929904222488403 + ], + [ + 0.060362398624420166, + 0.060362398624420166, + 0.2154000997543335, + 0.15503770112991333, + 0.15503770112991333 + ], + [ + 0.060362398624420166, + 0.060362398624420166, + 0.2154000997543335, + 0.15503770112991333, + 0.15503770112991333 + ] + ] + ], + [ + [ + [ + -0.34662023186683655, + -0.34662023186683655, + -0.24640008807182312, + 0.10022014379501343, + 0.10022014379501343 + ], + [ + -0.34662023186683655, + -0.34662023186683655, + -0.24640008807182312, + 0.10022014379501343, + 0.10022014379501343 + ], + [ + -0.5097748041152954, + -0.5097748041152954, + -0.5737892985343933, + -0.06401446461677551, + -0.06401446461677551 + ], + [ + -0.16315460205078125, + -0.16315460205078125, + -0.3273892104625702, + -0.16423460841178894, + -0.16423460841178894 + ], + [ + -0.16315460205078125, + -0.16315460205078125, + -0.3273892104625702, + -0.16423460841178894, + -0.16423460841178894 + ] + ], + [ + [ + -0.34662023186683655, + -0.34662023186683655, + -0.24640008807182312, + 0.10022014379501343, + 0.10022014379501343 + ], + [ + -0.34662023186683655, + -0.34662023186683655, + -0.24640008807182312, + 0.10022014379501343, + 0.10022014379501343 + ], + [ + -0.5097748041152954, + -0.5097748041152954, + -0.5737892985343933, + -0.06401446461677551, + -0.06401446461677551 + ], + [ + -0.16315460205078125, + -0.16315460205078125, + -0.3273892104625702, + -0.16423460841178894, + -0.16423460841178894 + ], + [ + -0.16315460205078125, + -0.16315460205078125, + -0.3273892104625702, + -0.16423460841178894, + -0.16423460841178894 + ] + ], + [ + [ + -0.26386743783950806, + -0.26386743783950806, + -0.13976630568504333, + 0.12410113215446472, + 0.12410113215446472 + ], + [ + -0.26386743783950806, + -0.26386743783950806, + -0.13976630568504333, + 0.12410113215446472, + 0.12410113215446472 + ], + [ + -0.12887796759605408, + -0.12887796759605408, + -0.5085822343826294, + -0.37970423698425293, + -0.37970423698425293 + ], + [ + 0.1349894404411316, + 0.1349894404411316, + -0.36881592869758606, + -0.50380539894104, + -0.50380539894104 + ], + [ + 0.1349894404411316, + 0.1349894404411316, + -0.36881592869758606, + -0.50380539894104, + -0.50380539894104 + ] + ], + [ + [ + 0.08275279402732849, + 0.08275279402732849, + 0.10663378238677979, + 0.023880988359451294, + 0.023880988359451294 + ], + [ + 0.08275279402732849, + 0.08275279402732849, + 0.10663378238677979, + 0.023880988359451294, + 0.023880988359451294 + ], + [ + 0.38089683651924133, + 0.38089683651924133, + 0.06520706415176392, + -0.3156897723674774, + -0.3156897723674774 + ], + [ + 0.29814404249191284, + 0.29814404249191284, + -0.04142671823501587, + -0.3395707607269287, + -0.3395707607269287 + ], + [ + 0.29814404249191284, + 0.29814404249191284, + -0.04142671823501587, + -0.3395707607269287, + -0.3395707607269287 + ] + ], + [ + [ + 0.08275279402732849, + 0.08275279402732849, + 0.10663378238677979, + 0.023880988359451294, + 0.023880988359451294 + ], + [ + 0.08275279402732849, + 0.08275279402732849, + 0.10663378238677979, + 0.023880988359451294, + 0.023880988359451294 + ], + [ + 0.38089683651924133, + 0.38089683651924133, + 0.06520706415176392, + -0.3156897723674774, + -0.3156897723674774 + ], + [ + 0.29814404249191284, + 0.29814404249191284, + -0.04142671823501587, + -0.3395707607269287, + -0.3395707607269287 + ], + [ + 0.29814404249191284, + 0.29814404249191284, + -0.04142671823501587, + -0.3395707607269287, + -0.3395707607269287 + ] + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + [ + -1.6769251823425293, + 4.594216823577881 + ], + [ + -5.610960960388184, + -3.7611963748931885 + ] + ], + [ + [ + 1.391018271446228, + 11.542533874511719 + ], + [ + 1.7240196466445923, + -1.9049088954925537 + ] + ] + ], + [ + [ + [ + -0.6248869299888611, + 6.0362396240234375 + ], + [ + -5.252803325653076, + -1.563323974609375 + ] + ], + [ + [ + 7.093540191650391, + 9.448348045349121 + ], + [ + -7.200158596038818, + -3.4500885009765625 + ] + ] + ] + ], + [ + [ + [ + [ + -1.6769251823425293, + 4.594216823577881 + ], + [ + -5.610960960388184, + -3.7611963748931885 + ] + ], + [ + [ + 1.391018271446228, + 11.542533874511719 + ], + [ + 1.7240196466445923, + -1.9049088954925537 + ] + ] + ], + [ + [ + [ + -0.6248869299888611, + 6.0362396240234375 + ], + [ + -5.252803325653076, + -1.563323974609375 + ] + ], + [ + [ + 7.093540191650391, + 9.448348045349121 + ], + [ + -7.200158596038818, + -3.4500885009765625 + ] + ] + ] + ] + ], + "bias": null, + "expected_grad_bias": null + }, + { + "test_name": "conv3d_groups", + "conv_type": "Conv3d", + "in_channels": 4, + "out_channels": 4, + "kernel_size": 3, + "stride": 1, + "padding": 1, + "dilation": 1, + "groups": 2, + "has_bias": true, + "input": [ + [ + [ + [ + [ + -0.6010674834251404, + -0.1635483205318451, + 0.540489673614502, + -0.3672035038471222 + ], + [ + -1.2631161212921143, + 0.8303362727165222, + 0.7788206934928894, + -0.08426624536514282 + ], + [ + 0.27795618772506714, + -0.8656967282295227, + 0.370025634765625, + 0.027097342535853386 + ], + [ + 0.05418866500258446, + 0.5362043380737305, + -0.19528378546237946, + 1.0318245887756348 + ] + ], + [ + [ + -1.1645411252975464, + 1.4430084228515625, + 0.34732240438461304, + -0.6022811532020569 + ], + [ + 0.0974288359284401, + -1.0450509786605835, + 0.3688916862010956, + 0.5232675075531006 + ], + [ + -1.7843447923660278, + -1.4876283407211304, + 1.1491626501083374, + 1.937359094619751 + ], + [ + 0.5046956539154053, + 0.2925446927547455, + 0.2171924114227295, + 0.4019394814968109 + ] + ], + [ + [ + -0.9391453862190247, + 1.2694876194000244, + 0.15634684264659882, + 0.6024797558784485 + ], + [ + 1.209511637687683, + -1.2663702964782715, + 1.7024855613708496, + -0.9683796763420105 + ], + [ + 0.33257901668548584, + -2.500622034072876, + -1.3190810680389404, + -0.5720829367637634 + ], + [ + -1.4600306749343872, + 1.5690288543701172, + -0.88787841796875, + -0.6835475564002991 + ] + ], + [ + [ + 0.12993256747722626, + 2.3204126358032227, + -2.147797107696533, + -1.3236184120178223 + ], + [ + -0.34333336353302, + 0.7385661005973816, + -0.8320447206497192, + 0.9133552312850952 + ], + [ + 3.494849681854248, + -2.554791212081909, + -0.6495603322982788, + 1.3511242866516113 + ], + [ + 2.08429217338562, + 0.2650778293609619, + -0.19079573452472687, + -0.364820271730423 + ] + ] + ], + [ + [ + [ + 0.5880279541015625, + -0.649803102016449, + 0.29551762342453003, + 0.1007673516869545 + ], + [ + 0.4674225151538849, + 0.5173186659812927, + -1.4732903242111206, + -0.10355143249034882 + ], + [ + 1.7842795848846436, + -2.0273475646972656, + -1.8968849182128906, + 1.5710992813110352 + ], + [ + -1.054054856300354, + 0.10566096007823944, + -1.3687875270843506, + -0.5567623376846313 + ] + ], + [ + [ + -1.1206839084625244, + -0.48504650592803955, + 0.5147204995155334, + -0.3676562011241913 + ], + [ + -1.3724169731140137, + -0.13087055087089539, + -0.4163765013217926, + -0.9129456877708435 + ], + [ + 0.7357478141784668, + -0.5081192851066589, + -0.29886385798454285, + 2.1124520301818848 + ], + [ + -0.021738804876804352, + 0.8089306950569153, + 2.7958858013153076, + 0.41675102710723877 + ] + ], + [ + [ + 1.1353410482406616, + 1.1538640260696411, + -0.44356340169906616, + -1.7530438899993896 + ], + [ + -0.17104516923427582, + -0.2808971405029297, + -0.12884187698364258, + 0.9388713836669922 + ], + [ + 0.30860263109207153, + -1.2615443468093872, + 0.2716897130012512, + -0.2226782888174057 + ], + [ + -2.0968735218048096, + -1.0447371006011963, + 1.0945836305618286, + 1.0349615812301636 + ] + ], + [ + [ + 0.16704672574996948, + 0.19502827525138855, + 0.6036193370819092, + -0.22532868385314941 + ], + [ + -0.823324978351593, + 0.5321081876754761, + 1.690338134765625, + 1.8711999654769897 + ], + [ + -0.08777227252721786, + 0.36624786257743835, + 0.8002102971076965, + -0.43177542090415955 + ], + [ + 0.7183605432510376, + -0.5048002004623413, + 0.4487703740596771, + -0.43473342061042786 + ] + ] + ], + [ + [ + [ + -0.5347977876663208, + -0.41083934903144836, + 0.1554419845342636, + 0.7992386817932129 + ], + [ + 0.08938626199960709, + 1.624720811843872, + 1.8527616262435913, + -1.680544137954712 + ], + [ + -0.21575696766376495, + 0.19951215386390686, + 1.077291488647461, + -0.11855955421924591 + ], + [ + 0.6329800486564636, + 0.6623784899711609, + -0.9556253552436829, + 0.43514177203178406 + ] + ], + [ + [ + -1.8895906209945679, + 0.870172917842865, + -0.40558135509490967, + 0.4322058856487274 + ], + [ + -1.7878626585006714, + 1.9938184022903442, + -0.08736804872751236, + -1.1191902160644531 + ], + [ + -0.21153147518634796, + 0.23635204136371613, + -2.0590813159942627, + 0.36353930830955505 + ], + [ + -0.17709049582481384, + 0.6511173844337463, + 1.162279486656189, + 1.5198776721954346 + ] + ], + [ + [ + 0.8131258487701416, + 0.07307689636945724, + 0.5557780861854553, + 0.22815753519535065 + ], + [ + 0.40518879890441895, + -0.04436149075627327, + -0.46283742785453796, + 0.1497601568698883 + ], + [ + -0.2617298364639282, + 0.09828201681375504, + 0.5204787254333496, + 0.150835320353508 + ], + [ + -0.08319627493619919, + 0.018847988918423653, + 0.5120656490325928, + -0.9795308709144592 + ] + ], + [ + [ + -0.08465366065502167, + 0.5634167790412903, + -2.517653226852417, + 1.5532352924346924 + ], + [ + -0.32487261295318604, + 0.9450231790542603, + -1.232080101966858, + 1.510047435760498 + ], + [ + 0.6712618470191956, + -0.7744964957237244, + -0.12379023432731628, + 0.7035301327705383 + ], + [ + -0.36376747488975525, + 0.08706109970808029, + -0.27385643124580383, + 0.052069131284952164 + ] + ] + ], + [ + [ + [ + -0.8765193223953247, + 0.9824013710021973, + -0.32311075925827026, + -0.09268321096897125 + ], + [ + -0.7539657950401306, + 0.5708315372467041, + 0.7370786666870117, + -1.690212607383728 + ], + [ + -0.34074920415878296, + 0.05697745084762573, + 0.0032076085917651653, + 0.9378344416618347 + ], + [ + -0.9413528442382812, + 0.4082898497581482, + 1.0719655752182007, + 0.17691805958747864 + ] + ], + [ + [ + -0.2889143228530884, + -0.5668610334396362, + 0.20414040982723236, + -0.9038130640983582 + ], + [ + -0.10176023095846176, + 0.9885962009429932, + 0.9275448322296143, + 0.1871725618839264 + ], + [ + -1.7383617162704468, + -0.7690361142158508, + -1.114380121231079, + 0.6168888807296753 + ], + [ + 0.4690037965774536, + -0.5066404342651367, + -0.6858885884284973, + -1.308877944946289 + ] + ], + [ + [ + 1.9061840772628784, + -1.6183137893676758, + 1.6300877332687378, + -0.2200150340795517 + ], + [ + -0.034228239208459854, + 0.23624566197395325, + -0.6087417602539062, + 0.9832689762115479 + ], + [ + -0.6000643372535706, + -0.3363756835460663, + 1.7426948547363281, + 2.327395439147949 + ], + [ + -0.4416877329349518, + -0.051642946898937225, + -0.4240947961807251, + 1.8199645280838013 + ] + ], + [ + [ + -2.704969644546509, + 0.25391218066215515, + 0.8111586570739746, + -0.5477031469345093 + ], + [ + -0.7678541541099548, + 0.14641381800174713, + 1.7945916652679443, + -0.8427640199661255 + ], + [ + 0.1157287210226059, + 2.351787567138672, + 0.02904084324836731, + -0.4715009927749634 + ], + [ + 1.5835394859313965, + 0.5264506936073303, + -1.3288897275924683, + -0.5552407503128052 + ] + ] + ] + ] + ], + "weight": [ + [ + [ + [ + [ + -0.030513359233736992, + 0.049209609627723694, + -0.11256053298711777 + ], + [ + 0.11180425435304642, + 0.10690176486968994, + -0.03810763359069824 + ], + [ + -0.0492289662361145, + -0.026618685573339462, + 0.13539858162403107 + ] + ], + [ + [ + -0.052236780524253845, + 0.04074903205037117, + -0.1291959285736084 + ], + [ + 0.04113350436091423, + 0.08245334774255753, + 0.044047243893146515 + ], + [ + -0.006466334220021963, + 0.009931002743542194, + 0.11784464865922928 + ] + ], + [ + [ + 0.059138908982276917, + -0.03144518658518791, + -0.10930255800485611 + ], + [ + 0.09917846322059631, + -0.050664398819208145, + 0.08484464883804321 + ], + [ + -0.027349485084414482, + 0.0022585864644497633, + -0.10731968283653259 + ] + ] + ], + [ + [ + [ + -0.051842495799064636, + 0.011228075250983238, + -0.1315104365348816 + ], + [ + -0.028004510328173637, + 0.0790708139538765, + 0.09564515203237534 + ], + [ + 0.10023753345012665, + -0.04150017723441124, + 0.010712042450904846 + ] + ], + [ + [ + -0.1091998890042305, + 0.07049248367547989, + 0.024094296619296074 + ], + [ + 0.11390487849712372, + -0.021170107647776604, + 0.13014858961105347 + ], + [ + 0.06742006540298462, + 0.1161346584558487, + -0.00885622389614582 + ] + ], + [ + [ + -0.10677414387464523, + -0.10672265291213989, + -0.1283109188079834 + ], + [ + 0.022619053721427917, + -0.1052321121096611, + -0.04445267096161842 + ], + [ + 0.06914974004030228, + 0.12371136248111725, + -0.03412988409399986 + ] + ] + ] + ], + [ + [ + [ + [ + 0.09421706944704056, + -0.01031185407191515, + -0.027232328429818153 + ], + [ + -0.016104474663734436, + -0.06170425936579704, + 0.037245430052280426 + ], + [ + -0.0007366397767327726, + -0.0663040354847908, + 0.086556576192379 + ] + ], + [ + [ + -0.06079341098666191, + -0.09216593950986862, + 0.047240495681762695 + ], + [ + -0.008356397971510887, + -0.07491207867860794, + -0.11108863353729248 + ], + [ + -0.04077182710170746, + -0.1041940450668335, + 0.07401486486196518 + ] + ], + [ + [ + -0.016950387507677078, + 0.07009042799472809, + 0.06624048203229904 + ], + [ + 0.010960990563035011, + -0.020952291786670685, + -0.07018402963876724 + ], + [ + 0.030636340379714966, + -0.11833041161298752, + -0.06631190329790115 + ] + ] + ], + [ + [ + [ + 0.10852135717868805, + -0.02641327865421772, + 0.10978111624717712 + ], + [ + 0.08058465272188187, + -0.02868703380227089, + -0.10953208804130554 + ], + [ + 0.10928711295127869, + 0.011463882401585579, + 0.12860336899757385 + ] + ], + [ + [ + -0.12307491153478622, + 0.028042973950505257, + -0.11724753677845001 + ], + [ + -0.01652207039296627, + -0.1192781999707222, + -0.12385933846235275 + ], + [ + 0.0068649169988930225, + 0.13416090607643127, + 0.010427097789943218 + ] + ], + [ + [ + -0.012607605196535587, + 0.12684836983680725, + 0.012456738390028477 + ], + [ + -0.07598394900560379, + 0.08653328567743301, + 0.09710167348384857 + ], + [ + 0.11799715459346771, + 0.10701807588338852, + 0.12649768590927124 + ] + ] + ] + ], + [ + [ + [ + [ + -0.05047071725130081, + 0.019567115232348442, + -0.049657005816698074 + ], + [ + -0.018113935366272926, + 0.10758863389492035, + -0.10752318054437637 + ], + [ + 0.07436436414718628, + -0.07862627506256104, + 0.0007462596404366195 + ] + ], + [ + [ + -0.016202278435230255, + -0.06129545718431473, + 0.011604465544223785 + ], + [ + -0.06893385201692581, + 0.12325625866651535, + -0.04926367849111557 + ], + [ + 0.08613324165344238, + -0.03241463378071785, + -0.10714203119277954 + ] + ], + [ + [ + 0.10563848167657852, + -0.037575751543045044, + -0.05637470632791519 + ], + [ + 0.010202044621109962, + -0.0013864414067938924, + 0.03840000927448273 + ], + [ + -0.033017437905073166, + -0.039262499660253525, + 0.0744556114077568 + ] + ] + ], + [ + [ + [ + 0.06237300857901573, + 0.1202826276421547, + 0.01501829270273447 + ], + [ + -0.03532655909657478, + -0.028991753235459328, + -0.027731310576200485 + ], + [ + -0.04300585016608238, + -0.04644265025854111, + -0.038341689854860306 + ] + ], + [ + [ + 0.04103976860642433, + 0.05384436249732971, + 0.10357610881328583 + ], + [ + -0.1324263960123062, + 0.10552726686000824, + -0.02741682529449463 + ], + [ + -0.13297802209854126, + 0.08896347135305405, + -0.07715301215648651 + ] + ], + [ + [ + -0.06132258102297783, + 0.04516405239701271, + 0.0222906656563282 + ], + [ + 0.09276392310857773, + -0.0949527695775032, + 0.07392872869968414 + ], + [ + 0.07092973589897156, + 0.08423259854316711, + -0.04529407620429993 + ] + ] + ] + ], + [ + [ + [ + [ + 0.02311135269701481, + 0.040055301040410995, + 0.12830914556980133 + ], + [ + -0.08269394189119339, + -0.12494990229606628, + -0.12307319045066833 + ], + [ + 0.018023155629634857, + -0.10342481732368469, + -0.02519121766090393 + ] + ], + [ + [ + -0.06361400336027145, + 0.024651339277625084, + -0.09643067419528961 + ], + [ + 0.08391905575990677, + -0.13368600606918335, + -0.07455432415008545 + ], + [ + 0.02808072417974472, + -0.13384917378425598, + 0.03354187309741974 + ] + ], + [ + [ + -0.05091074854135513, + -0.06872890144586563, + 0.0975482165813446 + ], + [ + -0.04394025728106499, + 0.03216959536075592, + -0.05254532769322395 + ], + [ + 0.06366001069545746, + 0.12392594665288925, + 0.1306309849023819 + ] + ] + ], + [ + [ + [ + -0.08231638371944427, + -0.1352720409631729, + -0.09515999257564545 + ], + [ + 0.038335442543029785, + 0.054630495607852936, + 0.07147255539894104 + ], + [ + 0.059092968702316284, + 0.13238413631916046, + -0.10319491475820541 + ] + ], + [ + [ + -0.10668620467185974, + -0.042614519596099854, + 0.10562329739332199 + ], + [ + -0.10449402779340744, + 0.10202737897634506, + 0.022643063217401505 + ], + [ + 0.0841764360666275, + 0.13482370972633362, + 0.13245315849781036 + ] + ], + [ + [ + 0.13064035773277283, + -0.033394865691661835, + -0.05806885287165642 + ], + [ + 0.057771969586610794, + 0.11604811251163483, + 0.003388179698958993 + ], + [ + -0.03221295773983002, + -0.02200985699892044, + -0.048572737723588943 + ] + ] + ] + ] + ], + "expected_output": [ + [ + [ + [ + [ + 0.31455111503601074, + 0.08514947444200516, + -0.15354058146476746, + -0.06375192850828171 + ], + [ + 0.5849013328552246, + -0.2777863144874573, + -0.07062370330095291, + 0.24299079179763794 + ], + [ + -0.3012371063232422, + 0.1636168658733368, + 0.14740002155303955, + -0.028624363243579865 + ], + [ + 0.5005623698234558, + -1.00490140914917, + -0.4954855442047119, + 0.131992906332016 + ] + ], + [ + [ + -0.11682949215173721, + -0.44103288650512695, + 0.5741671323776245, + 0.024398483335971832 + ], + [ + -0.774344801902771, + 0.11496435850858688, + 0.17903274297714233, + 0.36282312870025635 + ], + [ + -0.6987835168838501, + -0.37187090516090393, + 0.6472610235214233, + 0.7521082162857056 + ], + [ + 1.5605796575546265, + 0.2675955891609192, + -0.03801131248474121, + 0.6034815907478333 + ] + ], + [ + [ + -0.42367294430732727, + 0.03318726271390915, + 0.5253119468688965, + 0.3473888635635376 + ], + [ + -0.5904951095581055, + -0.18561586737632751, + 0.2454434335231781, + -0.6931743621826172 + ], + [ + -0.39125943183898926, + -1.108742356300354, + -0.507588267326355, + 0.37696021795272827 + ], + [ + 0.5191097855567932, + 0.6672462224960327, + -0.15240344405174255, + 0.13204294443130493 + ] + ], + [ + [ + 0.0351962074637413, + 0.40326881408691406, + -0.0105043426156044, + 0.13288968801498413 + ], + [ + -0.9662636518478394, + 0.4197092056274414, + 0.7768668532371521, + 0.5667317509651184 + ], + [ + 0.8745118379592896, + -0.4432828426361084, + -0.7016594409942627, + 0.06813762336969376 + ], + [ + 0.628696858882904, + 0.23590031266212463, + 0.35417571663856506, + -0.06674491614103317 + ] + ] + ], + [ + [ + [ + -0.12724320590496063, + -0.1676921546459198, + -0.6764430999755859, + -0.4281846880912781 + ], + [ + 0.14261625707149506, + -0.189521923661232, + -0.5238783359527588, + -0.11030559241771698 + ], + [ + -0.08100511133670807, + 0.5715047121047974, + 0.03456680476665497, + 0.0896516889333725 + ], + [ + 0.04384508728981018, + 0.2983396053314209, + 0.44286680221557617, + 0.33616024255752563 + ] + ], + [ + [ + 0.0530446320772171, + -0.274275541305542, + -0.7193563580513, + -0.2518726587295532 + ], + [ + 0.35049742460250854, + 0.9664632678031921, + -0.10006172209978104, + -0.31052252650260925 + ], + [ + -0.006888136267662048, + -0.15175409615039825, + 0.33437609672546387, + -0.7952547669410706 + ], + [ + -0.8238822221755981, + -0.5533866286277771, + -0.32959437370300293, + -0.821625292301178 + ] + ], + [ + [ + -0.8099207878112793, + -0.16976004838943481, + 0.34372830390930176, + 0.3888295292854309 + ], + [ + -0.3730044364929199, + 0.6971028447151184, + 0.4578671455383301, + -0.4588431119918823 + ], + [ + 0.11398746073246002, + 1.0882223844528198, + -0.17739616334438324, + 0.4957335591316223 + ], + [ + 0.08251698315143585, + -0.796347439289093, + 0.35041654109954834, + 0.03478327393531799 + ] + ], + [ + [ + -0.7430188059806824, + 0.027915969491004944, + 0.6628812551498413, + 0.2345527857542038 + ], + [ + -1.0526297092437744, + -0.45693933963775635, + -0.5519452095031738, + -0.37496161460876465 + ], + [ + -0.1880352944135666, + -0.4893310070037842, + -0.38091444969177246, + 0.00243164598941803 + ], + [ + -0.5911522507667542, + -0.4146895408630371, + -0.36692339181900024, + -0.22563600540161133 + ] + ] + ], + [ + [ + [ + -0.1505451649427414, + 0.18801279366016388, + 0.22355595231056213, + 0.43067818880081177 + ], + [ + 0.05739826709032059, + -0.27782684564590454, + 0.32386404275894165, + -0.40201282501220703 + ], + [ + 0.0747055634856224, + 0.013080373406410217, + 0.3785865306854248, + -0.5415412783622742 + ], + [ + -0.10402481257915497, + 0.5471309423446655, + 0.09130645543336868, + 0.08788447082042694 + ] + ], + [ + [ + -0.7555528879165649, + 0.4644201993942261, + -0.12831014394760132, + 0.6371702551841736 + ], + [ + -0.4957234263420105, + 0.6983954906463623, + 0.4560081362724304, + -0.25263774394989014 + ], + [ + -0.059423789381980896, + 0.35423970222473145, + -0.13772667944431305, + 0.2738529443740845 + ], + [ + -0.06502597033977509, + -0.15657509863376617, + 0.3571682870388031, + 0.09371341019868851 + ] + ], + [ + [ + 0.5735805630683899, + -0.9974273443222046, + 0.6931644678115845, + 0.23308917880058289 + ], + [ + -0.6186490058898926, + 1.0131170749664307, + 0.24364443123340607, + -0.21681837737560272 + ], + [ + 0.08148512244224548, + 0.7624080181121826, + 0.6038268804550171, + 0.22795037925243378 + ], + [ + -0.34718501567840576, + 0.3617039918899536, + 0.07529257237911224, + 0.5715086460113525 + ] + ], + [ + [ + -0.3552524447441101, + 0.6428000330924988, + -0.014569178223609924, + -0.2555174231529236 + ], + [ + 0.0480840727686882, + 0.47359269857406616, + -0.4183531403541565, + -0.15669973194599152 + ], + [ + 0.31845390796661377, + 0.2326236367225647, + -0.42830348014831543, + 0.2483210265636444 + ], + [ + 0.33505934476852417, + 0.1318371742963791, + 0.30133748054504395, + 0.40604573488235474 + ] + ] + ], + [ + [ + [ + -0.10241574048995972, + 0.24514983594417572, + -0.7703133225440979, + -0.20298685133457184 + ], + [ + 0.12950509786605835, + -0.0905580073595047, + -0.2170005887746811, + 0.3739772439002991 + ], + [ + -0.1046983003616333, + -0.05653303861618042, + 0.18341003358364105, + 0.6786373853683472 + ], + [ + -0.07671500742435455, + -0.2652748227119446, + 0.2162427455186844, + -0.629124641418457 + ] + ], + [ + [ + 0.7663935422897339, + -0.6792891025543213, + 0.5431439876556396, + -0.024241341277956963 + ], + [ + -0.6712461709976196, + -0.766162633895874, + -0.4784229099750519, + 0.4438798725605011 + ], + [ + -0.4010832607746124, + 0.14694184064865112, + -0.109443798661232, + -0.2974053621292114 + ], + [ + -0.14182105660438538, + 0.0485818013548851, + -0.3780379295349121, + 0.2742367386817932 + ] + ], + [ + [ + -0.1508481353521347, + -0.6024109125137329, + 0.4804859757423401, + 0.2117317169904709 + ], + [ + -0.4901675283908844, + -0.5975161790847778, + 1.059933066368103, + 0.9510890245437622 + ], + [ + 0.12868791818618774, + -0.5460107326507568, + 0.37731510400772095, + 0.3430858552455902 + ], + [ + 0.10134606063365936, + 0.15810571610927582, + 0.1015453189611435, + -0.47414088249206543 + ] + ], + [ + [ + -0.5066900849342346, + 0.5150911808013916, + 0.4745583236217499, + -0.7174737453460693 + ], + [ + 0.07770748436450958, + 0.8527685403823853, + 0.05662144720554352, + -0.23491783440113068 + ], + [ + 0.2234104871749878, + 0.8177720904350281, + -1.0931587219238281, + -0.031021563336253166 + ], + [ + 0.6408951282501221, + -0.44277966022491455, + -0.7188045382499695, + -0.18751439452171326 + ] + ] + ] + ] + ], + "expected_grad_input": [ + [ + [ + [ + [ + 0.11937001347541809, + -0.17028185725212097, + -0.17028185725212097, + -0.2494322657585144 + ], + [ + -0.16501948237419128, + -0.040856726467609406, + -0.040856726467609406, + -0.022803347557783127 + ], + [ + -0.16501948237419128, + -0.040856726467609406, + -0.040856726467609406, + -0.022803347557783127 + ], + [ + -0.10317385941743851, + 0.24273720383644104, + 0.24273720383644104, + 0.211464062333107 + ] + ], + [ + [ + 0.23872655630111694, + -0.0793268159031868, + -0.0793268159031868, + -0.31080520153045654 + ], + [ + -0.15844789147377014, + -0.23631811141967773, + -0.23631811141967773, + -0.37387970089912415 + ], + [ + -0.15844789147377014, + -0.23631811141967773, + -0.23631811141967773, + -0.37387970089912415 + ], + [ + -0.17743602395057678, + 0.009504087269306183, + 0.009504087269306183, + -0.13519541919231415 + ] + ], + [ + [ + 0.23872655630111694, + -0.0793268159031868, + -0.0793268159031868, + -0.31080520153045654 + ], + [ + -0.15844789147377014, + -0.23631811141967773, + -0.23631811141967773, + -0.37387970089912415 + ], + [ + -0.15844789147377014, + -0.23631811141967773, + -0.23631811141967773, + -0.37387970089912415 + ], + [ + -0.17743602395057678, + 0.009504087269306183, + 0.009504087269306183, + -0.13519541919231415 + ] + ], + [ + [ + -0.004772186279296875, + -0.18217048048973083, + -0.18217048048973083, + -0.2542453706264496 + ], + [ + -0.2590583562850952, + -0.4182286560535431, + -0.4182286560535431, + -0.4463523328304291 + ], + [ + -0.2590583562850952, + -0.4182286560535431, + -0.4182286560535431, + -0.4463523328304291 + ], + [ + -0.17544502019882202, + -0.20959782600402832, + -0.20959782600402832, + -0.30856314301490784 + ] + ] + ], + [ + [ + [ + -0.032347261905670166, + -0.15482750535011292, + -0.15482750535011292, + -0.12919452786445618 + ], + [ + 0.4717216491699219, + 0.49012768268585205, + 0.49012768268585205, + 0.2319510579109192 + ], + [ + 0.4717216491699219, + 0.49012768268585205, + 0.49012768268585205, + 0.2319510579109192 + ], + [ + 0.5639673471450806, + 0.6972559690475464, + 0.6972559690475464, + 0.26348334550857544 + ] + ], + [ + [ + -0.20366701483726501, + -0.3893524706363678, + -0.3893524706363678, + -0.19097280502319336 + ], + [ + 0.7182782888412476, + 0.7658469676971436, + 0.7658469676971436, + 0.4932699501514435 + ], + [ + 0.7182782888412476, + 0.7658469676971436, + 0.7658469676971436, + 0.4932699501514435 + ], + [ + 0.909779965877533, + 1.1880854368209839, + 1.1880854368209839, + 0.6205307841300964 + ] + ], + [ + [ + -0.20366701483726501, + -0.3893524706363678, + -0.3893524706363678, + -0.19097280502319336 + ], + [ + 0.7182782888412476, + 0.7658469676971436, + 0.7658469676971436, + 0.4932699501514435 + ], + [ + 0.7182782888412476, + 0.7658469676971436, + 0.7658469676971436, + 0.4932699501514435 + ], + [ + 0.909779965877533, + 1.1880854368209839, + 1.1880854368209839, + 0.6205307841300964 + ] + ], + [ + [ + -0.34812459349632263, + -0.49819377064704895, + -0.49819377064704895, + -0.1905551254749298 + ], + [ + 0.39433231949806213, + 0.3382018506526947, + 0.3382018506526947, + 0.38440853357315063 + ], + [ + 0.39433231949806213, + 0.3382018506526947, + 0.3382018506526947, + 0.38440853357315063 + ], + [ + 0.6273276805877686, + 0.7802046537399292, + 0.7802046537399292, + 0.47475478053092957 + ] + ] + ], + [ + [ + [ + -0.1978110373020172, + -0.5583994388580322, + -0.5583994388580322, + -0.36540114879608154 + ], + [ + -0.33952441811561584, + -0.7981580495834351, + -0.7981580495834351, + -0.811761200428009 + ], + [ + -0.33952441811561584, + -0.7981580495834351, + -0.7981580495834351, + -0.811761200428009 + ], + [ + -0.25532710552215576, + -0.7077865600585938, + -0.7077865600585938, + -0.8285654187202454 + ] + ], + [ + [ + -0.25234299898147583, + -0.5859032869338989, + -0.5859032869338989, + -0.4138944745063782 + ], + [ + -0.2787504196166992, + -0.5052691698074341, + -0.5052691698074341, + -0.5705044269561768 + ], + [ + -0.2787504196166992, + -0.5052691698074341, + -0.5052691698074341, + -0.5705044269561768 + ], + [ + -0.14297613501548767, + -0.40449437499046326, + -0.40449437499046326, + -0.5221775770187378 + ] + ], + [ + [ + -0.25234299898147583, + -0.5859032869338989, + -0.5859032869338989, + -0.4138944745063782 + ], + [ + -0.2787504196166992, + -0.5052691698074341, + -0.5052691698074341, + -0.5705044269561768 + ], + [ + -0.2787504196166992, + -0.5052691698074341, + -0.5052691698074341, + -0.5705044269561768 + ], + [ + -0.14297613501548767, + -0.40449437499046326, + -0.40449437499046326, + -0.5221775770187378 + ] + ], + [ + [ + -0.16643691062927246, + -0.3480529189109802, + -0.3480529189109802, + -0.3042113780975342 + ], + [ + -0.10318074375391006, + -0.15331032872200012, + -0.15331032872200012, + -0.254325270652771 + ], + [ + -0.10318074375391006, + -0.15331032872200012, + -0.15331032872200012, + -0.254325270652771 + ], + [ + 0.06485657393932343, + 0.058379679918289185, + 0.058379679918289185, + -0.0677238404750824 + ] + ] + ], + [ + [ + [ + -0.0900675356388092, + 0.0779576450586319, + 0.0779576450586319, + 0.3974590003490448 + ], + [ + 0.18694667518138885, + 0.2687353491783142, + 0.2687353491783142, + 0.6209511756896973 + ], + [ + 0.18694667518138885, + 0.2687353491783142, + 0.2687353491783142, + 0.6209511756896973 + ], + [ + 0.2762960195541382, + 0.22902704775333405, + 0.22902704775333405, + 0.49565309286117554 + ] + ], + [ + [ + 0.1626506894826889, + 0.37221455574035645, + 0.37221455574035645, + 0.471862256526947 + ], + [ + 0.5406043529510498, + 0.5700650215148926, + 0.5700650215148926, + 0.663710355758667 + ], + [ + 0.5406043529510498, + 0.5700650215148926, + 0.5700650215148926, + 0.663710355758667 + ], + [ + 0.548866868019104, + 0.48504796624183655, + 0.48504796624183655, + 0.5624213218688965 + ] + ], + [ + [ + 0.1626506894826889, + 0.37221455574035645, + 0.37221455574035645, + 0.471862256526947 + ], + [ + 0.5406043529510498, + 0.5700650215148926, + 0.5700650215148926, + 0.663710355758667 + ], + [ + 0.5406043529510498, + 0.5700650215148926, + 0.5700650215148926, + 0.663710355758667 + ], + [ + 0.548866868019104, + 0.48504796624183655, + 0.48504796624183655, + 0.5624213218688965 + ] + ], + [ + [ + 0.1689358353614807, + 0.41490018367767334, + 0.41490018367767334, + 0.4976133704185486 + ], + [ + 0.44486090540885925, + 0.6522586345672607, + 0.6522586345672607, + 0.7450566291809082 + ], + [ + 0.44486090540885925, + 0.6522586345672607, + 0.6522586345672607, + 0.7450566291809082 + ], + [ + 0.418190598487854, + 0.4521670937538147, + 0.4521670937538147, + 0.5486364364624023 + ] + ] + ] + ] + ], + "expected_grad_weight": [ + [ + [ + [ + [ + -3.5263595581054688, + -3.030369520187378, + 0.8043696880340576 + ], + [ + -2.895697832107544, + -1.649491310119629, + 3.0863945484161377 + ], + [ + -3.784050226211548, + -2.1708388328552246, + -0.1397075653076172 + ] + ], + [ + [ + -3.3701252937316895, + -1.9332741498947144, + -1.379983901977539 + ], + [ + -0.5808892250061035, + 1.2413580417633057, + 0.6115028858184814 + ], + [ + -1.771789789199829, + 1.7410807609558105, + -1.4635964632034302 + ] + ], + [ + [ + -3.274324893951416, + -1.413101315498352, + -2.4460387229919434 + ], + [ + -0.8801982402801514, + 0.3345968723297119, + -1.8272972106933594 + ], + [ + -2.295225143432617, + 0.24299001693725586, + -3.8926587104797363 + ] + ] + ], + [ + [ + [ + -4.893064022064209, + -3.5297491550445557, + -5.885024547576904 + ], + [ + -5.674193859100342, + -3.415929079055786, + -2.598536968231201 + ], + [ + -6.66256856918335, + -2.3843705654144287, + -0.9642940759658813 + ] + ], + [ + [ + -1.4495625495910645, + 1.1278483867645264, + -0.48337650299072266 + ], + [ + -1.568361759185791, + 1.4692656993865967, + 2.312347888946533 + ], + [ + -3.522430658340454, + 1.7604587078094482, + 3.373271942138672 + ] + ], + [ + [ + 0.945197582244873, + 1.9542927742004395, + 3.182798147201538 + ], + [ + 3.1435790061950684, + 5.16965389251709, + 7.798410892486572 + ], + [ + 1.423252820968628, + 5.795356750488281, + 8.605817794799805 + ] + ] + ] + ], + [ + [ + [ + [ + -3.5263595581054688, + -3.030369520187378, + 0.8043696880340576 + ], + [ + -2.895697832107544, + -1.649491310119629, + 3.0863945484161377 + ], + [ + -3.784050226211548, + -2.1708388328552246, + -0.1397075653076172 + ] + ], + [ + [ + -3.3701252937316895, + -1.9332741498947144, + -1.379983901977539 + ], + [ + -0.5808892250061035, + 1.2413580417633057, + 0.6115028858184814 + ], + [ + -1.771789789199829, + 1.7410807609558105, + -1.4635964632034302 + ] + ], + [ + [ + -3.274324893951416, + -1.413101315498352, + -2.4460387229919434 + ], + [ + -0.8801982402801514, + 0.3345968723297119, + -1.8272972106933594 + ], + [ + -2.295225143432617, + 0.24299001693725586, + -3.8926587104797363 + ] + ] + ], + [ + [ + [ + -4.893064022064209, + -3.5297491550445557, + -5.885024547576904 + ], + [ + -5.674193859100342, + -3.415929079055786, + -2.598536968231201 + ], + [ + -6.66256856918335, + -2.3843705654144287, + -0.9642940759658813 + ] + ], + [ + [ + -1.4495625495910645, + 1.1278483867645264, + -0.48337650299072266 + ], + [ + -1.568361759185791, + 1.4692656993865967, + 2.312347888946533 + ], + [ + -3.522430658340454, + 1.7604587078094482, + 3.373271942138672 + ] + ], + [ + [ + 0.945197582244873, + 1.9542927742004395, + 3.182798147201538 + ], + [ + 3.1435790061950684, + 5.16965389251709, + 7.798410892486572 + ], + [ + 1.423252820968628, + 5.795356750488281, + 8.605817794799805 + ] + ] + ] + ], + [ + [ + [ + [ + 2.19404935836792, + 1.3994925022125244, + 4.993061065673828 + ], + [ + 4.617806434631348, + 4.7987380027771, + 8.019613265991211 + ], + [ + 5.39102029800415, + 4.112349510192871, + 5.7219624519348145 + ] + ], + [ + [ + -0.6837949752807617, + 2.2884609699249268, + 5.620293617248535 + ], + [ + 1.1893994808197021, + 5.189212799072266, + 8.51211929321289 + ], + [ + 4.001502990722656, + 4.988478660583496, + 6.615469932556152 + ] + ], + [ + [ + -4.521514892578125, + -0.5493941307067871, + 2.121269702911377 + ], + [ + -2.988053798675537, + 1.5764827728271484, + 4.8712005615234375 + ], + [ + -0.9661457538604736, + 1.3847923278808594, + 3.518392562866211 + ] + ] + ], + [ + [ + [ + -0.08539199829101562, + 2.0604448318481445, + 4.888823986053467 + ], + [ + -1.1874403953552246, + 1.6464009284973145, + 5.388817310333252 + ], + [ + -2.236534595489502, + 1.8138175010681152, + 6.296984672546387 + ] + ], + [ + [ + 1.9444174766540527, + 2.2282862663269043, + 8.413761138916016 + ], + [ + 1.623469591140747, + 2.040102005004883, + 7.556074142456055 + ], + [ + 2.2142739295959473, + 4.395120620727539, + 7.946873664855957 + ] + ], + [ + [ + 1.8882660865783691, + 3.0171961784362793, + 7.231435775756836 + ], + [ + 1.0284156799316406, + 2.113191604614258, + 4.716576099395752 + ], + [ + 1.4019911289215088, + 4.158297538757324, + 5.673982620239258 + ] + ] + ] + ], + [ + [ + [ + [ + 2.19404935836792, + 1.3994925022125244, + 4.993061065673828 + ], + [ + 4.617806434631348, + 4.7987380027771, + 8.019613265991211 + ], + [ + 5.39102029800415, + 4.112349510192871, + 5.7219624519348145 + ] + ], + [ + [ + -0.6837949752807617, + 2.2884609699249268, + 5.620293617248535 + ], + [ + 1.1893994808197021, + 5.189212799072266, + 8.51211929321289 + ], + [ + 4.001502990722656, + 4.988478660583496, + 6.615469932556152 + ] + ], + [ + [ + -4.521514892578125, + -0.5493941307067871, + 2.121269702911377 + ], + [ + -2.988053798675537, + 1.5764827728271484, + 4.8712005615234375 + ], + [ + -0.9661457538604736, + 1.3847923278808594, + 3.518392562866211 + ] + ] + ], + [ + [ + [ + -0.08539199829101562, + 2.0604448318481445, + 4.888823986053467 + ], + [ + -1.1874403953552246, + 1.6464009284973145, + 5.388817310333252 + ], + [ + -2.236534595489502, + 1.8138175010681152, + 6.296984672546387 + ] + ], + [ + [ + 1.9444174766540527, + 2.2282862663269043, + 8.413761138916016 + ], + [ + 1.623469591140747, + 2.040102005004883, + 7.556074142456055 + ], + [ + 2.2142739295959473, + 4.395120620727539, + 7.946873664855957 + ] + ], + [ + [ + 1.8882660865783691, + 3.0171961784362793, + 7.231435775756836 + ], + [ + 1.0284156799316406, + 2.113191604614258, + 4.716576099395752 + ], + [ + 1.4019911289215088, + 4.158297538757324, + 5.673982620239258 + ] + ] + ] + ] + ], + "bias": [ + 0.06534195691347122, + -0.13534505665302277, + 0.11579547822475433, + -0.004997386131435633 + ], + "expected_grad_bias": [ + 64.0, + 64.0, + 64.0, + 64.0 + ] + } ] }; From 3c9e8a1bd3cd6561cd7178ebb4b4fd551509530b Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 15:11:02 +0800 Subject: [PATCH 089/128] docs: package scripts --- package.json | 8 ++++---- tsconfig.build.json | 10 ++++++++++ vite.config.browser.ts | 11 ++++------- vite.config.node.ts | 3 +++ 4 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 tsconfig.build.json diff --git a/package.json b/package.json index 0355d6ae..3397a9e1 100644 --- a/package.json +++ b/package.json @@ -31,14 +31,14 @@ "build:browser:watch": "vite build --config vite.config.browser.ts --watch", "build:node": "vite build --config vite.config.node.ts", "build:node:watch": "vite build --config vite.config.node.ts --watch", - "build": "yarn clean && yarn build:node && yarn build:browser", + "build:types": "tsc -p tsconfig.build.json", + "build": "yarn clean && concurrently \"yarn build:node\" \"yarn build:browser\" \"yarn build:types\"", + "dev": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\" \"yarn:serve\"", "docs": "typedoc --out docs src", - "generate": "python3 scripts/generate.py", "serve": "http-server -p 8080 -c-1", "test": "mocha test/**/*.test.ts test/**/*.test.js", "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js --watch-files build", - "update-tests": "python3 scripts/generate_tests.py > test/testcases.gen.js", - "watch": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\"" + "update-tests": "python3 scripts/generate_tests.py > test/testcases.gen.js" }, "devDependencies": { "@eslint/js": "^9.37.0", diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..23bf1dc0 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "build/types", + "declaration": true, + "emitDeclarationOnly": true, + "noEmit": false + }, + "include": ["src"] +} diff --git a/vite.config.browser.ts b/vite.config.browser.ts index 4340ab5b..ce51d5ac 100644 --- a/vite.config.browser.ts +++ b/vite.config.browser.ts @@ -1,13 +1,7 @@ import { defineConfig } from 'vite'; import path from 'path'; -import dts from 'vite-plugin-dts'; export default defineConfig({ - plugins: [ - dts({ - outDir: 'build/types' - }) - ], build: { minify: true, sourcemap: true, @@ -25,7 +19,10 @@ export default defineConfig({ inlineDynamicImports: false, minifyInternalExports: false, } - } + }, + watch: { + include: 'src/**', + }, }, esbuild: { keepNames: true, diff --git a/vite.config.node.ts b/vite.config.node.ts index 4d071889..6f366572 100644 --- a/vite.config.node.ts +++ b/vite.config.node.ts @@ -11,5 +11,8 @@ export default defineConfig({ outDir: 'build/node', target: 'node20', minify: true, + watch: { + include: 'src/**', + }, }, }); From 2d536426b893a1340cc978a2478fbb5a5ae78d81 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 15:12:02 +0800 Subject: [PATCH 090/128] style: reformat code --- examples/basic_backpropagation.js | 4 +- examples/browser/index.html | 36 +++---- src/broadcasting.ts | 2 +- src/creation/ranges.ts | 2 +- src/functions/base.ts | 2 +- src/functions/ops.ts | 24 ++--- src/functions/util.ts | 4 +- src/nn/index.ts | 2 +- src/nn/loss.ts | 2 +- src/nn/module.ts | 156 +++++++++++++++--------------- src/optim/index.ts | 2 +- src/optim/optimizers.ts | 2 +- src/util.ts | 2 +- test/broadcast.test.js | 2 +- test/chai-esm.js | 2 - test/event_listener.test.js | 2 +- test/index.html | 52 +++++----- test/template.test.js | 2 +- 18 files changed, 149 insertions(+), 151 deletions(-) diff --git a/examples/basic_backpropagation.js b/examples/basic_backpropagation.js index 31339ae6..8274ac2d 100644 --- a/examples/basic_backpropagation.js +++ b/examples/basic_backpropagation.js @@ -1,4 +1,4 @@ -import { Tensor } from "../build/node/torch.node.es.js"; +import { Tensor } from '../build/node/torch.node.es.js'; const x = new Tensor([2.0], { requires_grad: true }); const y = x.pow(new Tensor([2.0])); @@ -6,4 +6,4 @@ const y = x.pow(new Tensor([2.0])); console.log(y.item()); y.backward(); -console.log(x.grad?.item()); \ No newline at end of file +console.log(x.grad?.item()); diff --git a/examples/browser/index.html b/examples/browser/index.html index 65030fc1..58c29572 100644 --- a/examples/browser/index.html +++ b/examples/browser/index.html @@ -2,31 +2,31 @@ - - - torch.js browser backprop example - + + + torch.js browser backprop example + -

+    

 
-  
+        log(y.item());
+        y.backward();
+        log(x.grad && x.grad.item());
+    
 
 
 
diff --git a/src/broadcasting.ts b/src/broadcasting.ts
index d26e1b9a..42c169b2 100644
--- a/src/broadcasting.ts
+++ b/src/broadcasting.ts
@@ -24,7 +24,7 @@ export function _broadcast_shape(a_shape: number[], b_shape: number[]): number[]
 export function _unbroadcast(result_shape: number[], original_shape: number[], result: number[]) {
   const this_shape = _pad_shape(original_shape, result_shape)
   const unbroadcasted_result = new Array(original_shape.reduce((acc, cur) => acc * cur, 1)).fill(0);
-  for(let i = 0; i < result.length; i++){
+  for (let i = 0; i < result.length; i++) {
     unbroadcasted_result[_get_original_index(this_shape, result_shape, i)] += result[i];
   }
   return unbroadcasted_result;
diff --git a/src/creation/ranges.ts b/src/creation/ranges.ts
index 7a92a403..0d8965c0 100644
--- a/src/creation/ranges.ts
+++ b/src/creation/ranges.ts
@@ -16,4 +16,4 @@ export function arange(start: number, end: number = undefined, step: number = 1)
     data.push(i);
   }
   return new Tensor(data);
-}
\ No newline at end of file
+}
diff --git a/src/functions/base.ts b/src/functions/base.ts
index bb548c7d..44059cf6 100644
--- a/src/functions/base.ts
+++ b/src/functions/base.ts
@@ -95,7 +95,7 @@ export class AccumulateGrad extends UnaryFunction {
       this.variable.grad = zeros_like(this.variable);
     }
     eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_ACCUMULATE_GRAD, { detail: { operation: this, dz } }));
-    if(typeof dz === "number") {
+    if (typeof dz === "number") {
       this.variable.grad = this.variable.grad.add(dz);
     } else {
       const unbroadcasted_dz = _unbroadcast(dz.shape, this.variable.shape, dz.data);
diff --git a/src/functions/ops.ts b/src/functions/ops.ts
index 78f0b15a..698b2962 100644
--- a/src/functions/ops.ts
+++ b/src/functions/ops.ts
@@ -333,7 +333,7 @@ class Expand extends TorchFunction {
     } else {
       this.next_functions.push(nullOp);
     }
-  
+
     const offset = expanded_shape.length - a.shape.length;
     const target_shape = expanded_shape.map((dim, i) => {
       if (dim === -1) {
@@ -406,7 +406,7 @@ export const Mean = ReductionFunctionMixin(
     const out_size = target_shape.length > 0 ? target_shape.reduce((acc, v) => acc * v, 1) : 1;
     const N = a.dataLength() / out_size;
 
-    return expanded_dz.mul(new Tensor([1 / N])); 
+    return expanded_dz.mul(new Tensor([1 / N]));
   },
   'mean',
   (acc, count) => acc / count
@@ -667,7 +667,7 @@ function _convNd_forward(
   const out_channels = weight.shape[0];
   const in_dims = input.shape.slice(2);
   const kernel_dims = weight.shape.slice(2);
-  
+
   if (in_channels !== weight.shape[1] * groups) {
     throw new Error(`in_channels (${in_channels}) must be divisible by groups (${groups}) and match weight.shape[1] * groups (${weight.shape[1] * groups})`);
   }
@@ -700,11 +700,11 @@ function _convNd_forward(
     for (let g = 0; g < groups; g++) {
       for (let oc_g = 0; oc_g < out_channels_per_group; oc_g++) {
         const oc = g * out_channels_per_group + oc_g;
-        
+
         // Iterate over output spatial dimensions
         const out_spatial_size = out_dims.reduce((a, b) => a * b, 1);
         for (let os_idx = 0; os_idx < out_spatial_size; os_idx++) {
-          
+
           // Decode output spatial index
           const os_coords = new Array(dims);
           let temp_os = os_idx;
@@ -718,7 +718,7 @@ function _convNd_forward(
           // Iterate over kernel spatial dimensions and in_channels
           for (let ic_g = 0; ic_g < in_channels_per_group; ic_g++) {
             const ic = g * in_channels_per_group + ic_g;
-            
+
             const kernel_spatial_size = kernel_dims.reduce((a, b) => a * b, 1);
             for (let ks_idx = 0; ks_idx < kernel_spatial_size; ks_idx++) {
               // Decode kernel spatial index
@@ -757,7 +757,7 @@ function _convNd_forward(
           // Calculate output flattened index
           let out_flat_idx = b * out_strides[0] + oc * out_strides[1];
           for (let d = 0; d < dims; d++) out_flat_idx += os_coords[d] * out_strides[d + 2];
-          
+
           output_data[out_flat_idx] = sum;
         }
       }
@@ -818,7 +818,7 @@ function _convNd_backward(
   if (weight_requires_grad) {
     dWeight_data = new Array(weight.dataLength()).fill(0);
   }
-  
+
   const in_channels_per_group = in_channels / groups;
   const out_channels_per_group = out_channels / groups;
 
@@ -826,10 +826,10 @@ function _convNd_backward(
     for (let g = 0; g < groups; g++) {
       for (let oc_g = 0; oc_g < out_channels_per_group; oc_g++) {
         const oc = g * out_channels_per_group + oc_g;
-        
+
         const out_spatial_size = out_dims.reduce((a, b) => a * b, 1);
         for (let os_idx = 0; os_idx < out_spatial_size; os_idx++) {
-          
+
           const os_coords = new Array(dims);
           let temp_os = os_idx;
           for (let d = dims - 1; d >= 0; d--) {
@@ -843,7 +843,7 @@ function _convNd_backward(
 
           for (let ic_g = 0; ic_g < in_channels_per_group; ic_g++) {
             const ic = g * in_channels_per_group + ic_g;
-            
+
             const kernel_spatial_size = kernel_dims.reduce((a, b) => a * b, 1);
             for (let ks_idx = 0; ks_idx < kernel_spatial_size; ks_idx++) {
               const ks_coords = new Array(dims);
@@ -889,7 +889,7 @@ function _convNd_backward(
   if (weight_requires_grad) dWeight = new Tensor(dWeight_data!, { requires_grad: false }, { shape: weight.shape });
   if (bias && bias.requires_grad) {
     const sum_dims = [0];
-    for(let d=2; d 1) : [];
-  
+
   const dims = Array.isArray(dim) ? dim : [dim];
   const normalized_dims = dims.map((d) => (d < 0 ? d + shape.length : d));
 
@@ -33,4 +33,4 @@ export function _get_reduction_shape(
   } else {
     return shape.filter((_, i) => !normalized_dims.includes(i));
   }
-}
\ No newline at end of file
+}
diff --git a/src/nn/index.ts b/src/nn/index.ts
index 7b0fd77b..d1d383b0 100644
--- a/src/nn/index.ts
+++ b/src/nn/index.ts
@@ -3,4 +3,4 @@ import './ops';
 export * from './base';
 export * from './loss';
 export * from './module';
-export * as functional from './functional';
\ No newline at end of file
+export * as functional from './functional';
diff --git a/src/nn/loss.ts b/src/nn/loss.ts
index 3651c720..e7608d4d 100644
--- a/src/nn/loss.ts
+++ b/src/nn/loss.ts
@@ -41,4 +41,4 @@ export class BCELoss extends Loss {
     }
     return loss;
   }
-}
\ No newline at end of file
+}
diff --git a/src/nn/module.ts b/src/nn/module.ts
index 7b0157ad..e2fbd8c1 100644
--- a/src/nn/module.ts
+++ b/src/nn/module.ts
@@ -64,56 +64,56 @@ abstract class _ConvNd extends Module {
   public groups: number;
 
   constructor(
-      in_channels: number,
-      out_channels: number,
-      kernel_size: number | number[],
-      stride: number | number[],
-      padding: number | number[],
-      dilation: number | number[],
-      groups: number,
-      bias: boolean,
-      dims: number
+    in_channels: number,
+    out_channels: number,
+    kernel_size: number | number[],
+    stride: number | number[],
+    padding: number | number[],
+    dilation: number | number[],
+    groups: number,
+    bias: boolean,
+    dims: number
   ) {
-      super();
-      
-      this.in_channels = in_channels;
-      this.out_channels = out_channels;
-      this.kernel_size = kernel_size;
-      this.stride = stride;
-      this.padding = padding;
-      this.dilation = dilation;
-      this.groups = groups;
-
-      if (in_channels % groups !== 0) {
-          throw new Error('in_channels must be divisible by groups');
-      }
-      if (out_channels % groups !== 0) {
-          throw new Error('out_channels must be divisible by groups');
-      }
-
-      let kernel_arr = typeof kernel_size === 'number' ? new Array(dims).fill(kernel_size) : kernel_size;
-      const kernel_vol = kernel_arr.reduce((a: number, b: number) => a * b, 1);
-      
-      const k = Math.sqrt(groups / (in_channels * kernel_vol));
-
-      this.weight = new Parameter(
-          rand([out_channels, in_channels / groups, ...kernel_arr])
-              .mul(2 * k)
-              .sub(k)
-      );
+    super();
+
+    this.in_channels = in_channels;
+    this.out_channels = out_channels;
+    this.kernel_size = kernel_size;
+    this.stride = stride;
+    this.padding = padding;
+    this.dilation = dilation;
+    this.groups = groups;
+
+    if (in_channels % groups !== 0) {
+      throw new Error('in_channels must be divisible by groups');
+    }
+    if (out_channels % groups !== 0) {
+      throw new Error('out_channels must be divisible by groups');
+    }
+
+    let kernel_arr = typeof kernel_size === 'number' ? new Array(dims).fill(kernel_size) : kernel_size;
+    const kernel_vol = kernel_arr.reduce((a: number, b: number) => a * b, 1);
+
+    const k = Math.sqrt(groups / (in_channels * kernel_vol));
+
+    this.weight = new Parameter(
+      rand([out_channels, in_channels / groups, ...kernel_arr])
+        .mul(2 * k)
+        .sub(k)
+    );
 
-      this.register('weight', this.weight);
-
-      if (bias) {
-          this.bias = new Parameter(
-              rand([out_channels])
-                  .mul(2 * k)
-                  .sub(k)
-          );
-          this.register('bias', this.bias);
-      } else {
-          this.bias = null;
-      }
+    this.register('weight', this.weight);
+
+    if (bias) {
+      this.bias = new Parameter(
+        rand([out_channels])
+          .mul(2 * k)
+          .sub(k)
+      );
+      this.register('bias', this.bias);
+    } else {
+      this.bias = null;
+    }
   }
 
   abstract forward(input: Tensor): Tensor;
@@ -121,57 +121,57 @@ abstract class _ConvNd extends Module {
 
 export class Conv1d extends _ConvNd {
   constructor(
-      in_channels: number,
-      out_channels: number,
-      kernel_size: number | number[],
-      stride: number | number[] = 1,
-      padding: number | number[] = 0,
-      dilation: number | number[] = 1,
-      groups: number = 1,
-      bias: boolean = true
+    in_channels: number,
+    out_channels: number,
+    kernel_size: number | number[],
+    stride: number | number[] = 1,
+    padding: number | number[] = 0,
+    dilation: number | number[] = 1,
+    groups: number = 1,
+    bias: boolean = true
   ) {
-      super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 1);
+    super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 1);
   }
 
   forward(input: Tensor) {
-      return functional.conv1d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups);
+    return functional.conv1d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups);
   }
 }
 
 export class Conv2d extends _ConvNd {
   constructor(
-      in_channels: number,
-      out_channels: number,
-      kernel_size: number | number[],
-      stride: number | number[] = 1,
-      padding: number | number[] = 0,
-      dilation: number | number[] = 1,
-      groups: number = 1,
-      bias: boolean = true
+    in_channels: number,
+    out_channels: number,
+    kernel_size: number | number[],
+    stride: number | number[] = 1,
+    padding: number | number[] = 0,
+    dilation: number | number[] = 1,
+    groups: number = 1,
+    bias: boolean = true
   ) {
-      super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 2);
+    super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 2);
   }
 
   forward(input: Tensor) {
-      return functional.conv2d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups);
+    return functional.conv2d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups);
   }
 }
 
 export class Conv3d extends _ConvNd {
   constructor(
-      in_channels: number,
-      out_channels: number,
-      kernel_size: number | number[],
-      stride: number | number[] = 1,
-      padding: number | number[] = 0,
-      dilation: number | number[] = 1,
-      groups: number = 1,
-      bias: boolean = true
+    in_channels: number,
+    out_channels: number,
+    kernel_size: number | number[],
+    stride: number | number[] = 1,
+    padding: number | number[] = 0,
+    dilation: number | number[] = 1,
+    groups: number = 1,
+    bias: boolean = true
   ) {
-      super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 3);
+    super(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, 3);
   }
 
   forward(input: Tensor) {
-      return functional.conv3d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups);
+    return functional.conv3d(input, this.weight, this.bias, this.stride, this.padding, this.dilation, this.groups);
   }
 }
diff --git a/src/optim/index.ts b/src/optim/index.ts
index 6d4aff54..3f38deda 100644
--- a/src/optim/index.ts
+++ b/src/optim/index.ts
@@ -1,2 +1,2 @@
 export * from './base';
-export * from './optimizers';
\ No newline at end of file
+export * from './optimizers';
diff --git a/src/optim/optimizers.ts b/src/optim/optimizers.ts
index cf55400a..48034801 100644
--- a/src/optim/optimizers.ts
+++ b/src/optim/optimizers.ts
@@ -141,4 +141,4 @@ export class Adam extends Optimizer {
       param.data = newParam.data;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/util.ts b/src/util.ts
index 23a0048c..34355a30 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -14,4 +14,4 @@ export const events = {
   OPERATION_AFTER_BACKWARD: 'operation.afterBackward',
   OPERATION_BEFORE_ACCUMULATE_GRAD: 'operation.beforeAccumulateGrad',
   OPERATION_AFTER_ACCUMULATE_GRAD: 'operation.afterAccumulateGrad',
-}
\ No newline at end of file
+}
diff --git a/test/broadcast.test.js b/test/broadcast.test.js
index 359bae58..524a2a81 100644
--- a/test/broadcast.test.js
+++ b/test/broadcast.test.js
@@ -29,4 +29,4 @@ describe('Broadcast Index', () => {
         assert.deepStrictEqual(add(arr, zeros).toFlatArray(), [1, 2, 3, 4, 5, 6]);
         assert.deepStrictEqual(add(zeros, arr).toFlatArray(), [1, 2, 3, 4, 5, 6]);
     });
-});
\ No newline at end of file
+});
diff --git a/test/chai-esm.js b/test/chai-esm.js
index df0f85c5..8104557e 100644
--- a/test/chai-esm.js
+++ b/test/chai-esm.js
@@ -2,5 +2,3 @@
 const { assert, expect, should, use, config } = window.chai;
 export { assert, expect, should, use, config };
 export default window.chai;
-
-
diff --git a/test/event_listener.test.js b/test/event_listener.test.js
index 8c056638..4a2aa2a1 100644
--- a/test/event_listener.test.js
+++ b/test/event_listener.test.js
@@ -92,4 +92,4 @@ describe('Event Bus', () => {
             assert.isTrue(eventDispatched);
         });
     });
-});
\ No newline at end of file
+});
diff --git a/test/index.html b/test/index.html
index 1b85e075..150979e7 100644
--- a/test/index.html
+++ b/test/index.html
@@ -2,23 +2,23 @@
 
 
 
-  
-  Mocha Tests
-  
-  
+    
+    Mocha Tests
+    
+    
 
 
 
-  
+
- - + + - - + - + diff --git a/test/template.test.js b/test/template.test.js index b31b9c0f..22d1158f 100644 --- a/test/template.test.js +++ b/test/template.test.js @@ -9,4 +9,4 @@ describe('Tensor', () => { assert.deepStrictEqual(tensor.shape, [3]); }); }); -}); \ No newline at end of file +}); From 68edc2ae090690066b1f2fe3bf4d7a5cccc4a603 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 15:20:56 +0800 Subject: [PATCH 091/128] docs: fix build files and add timeout minutes --- .github/workflows/build-test-publish.yml | 1 + .github/workflows/verify-generated-tests.yml | 1 + vite.config.browser.ts | 3 --- vite.config.node.ts | 3 --- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 74704699..81e2ba99 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -6,6 +6,7 @@ jobs: ci: name: Build, test, publish docs, and publish package runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Check out source code uses: actions/checkout@v4 diff --git a/.github/workflows/verify-generated-tests.yml b/.github/workflows/verify-generated-tests.yml index 2f3521d4..b48f3872 100644 --- a/.github/workflows/verify-generated-tests.yml +++ b/.github/workflows/verify-generated-tests.yml @@ -5,6 +5,7 @@ on: [push] jobs: verify-sync: runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Check out source code uses: actions/checkout@v4 diff --git a/vite.config.browser.ts b/vite.config.browser.ts index ce51d5ac..1b825bb6 100644 --- a/vite.config.browser.ts +++ b/vite.config.browser.ts @@ -20,9 +20,6 @@ export default defineConfig({ minifyInternalExports: false, } }, - watch: { - include: 'src/**', - }, }, esbuild: { keepNames: true, diff --git a/vite.config.node.ts b/vite.config.node.ts index 6f366572..4d071889 100644 --- a/vite.config.node.ts +++ b/vite.config.node.ts @@ -11,8 +11,5 @@ export default defineConfig({ outDir: 'build/node', target: 'node20', minify: true, - watch: { - include: 'src/**', - }, }, }); From 3a5504f9b3ae070841346f94e20753e12849ab12 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 15:24:22 +0800 Subject: [PATCH 092/128] style: eslint --- eslint.config.mjs | 22 +++++++++++++--------- package.json | 1 + src/functions/base.ts | 2 +- src/functions/mixin.ts | 4 +--- src/functions/ops.ts | 18 ++++++++---------- src/nn/module.ts | 2 +- src/optim/optimizers.ts | 2 +- src/tensor.ts | 3 +-- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 6f643f29..a175a5ee 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,12 +4,16 @@ import eslint from '@eslint/js'; import { defineConfig } from 'eslint/config'; import tseslint from 'typescript-eslint'; -export default defineConfig( - eslint.configs.recommended, - tseslint.configs.recommended, - { - rules: { - '@typescript-eslint/no-unused-vars': 'warn', // was error - }, - }, -); \ No newline at end of file +export default defineConfig(eslint.configs.recommended, tseslint.configs.recommended, { + rules: { + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + ignoreRestSiblings: true + } + ] + } +}); diff --git a/package.json b/package.json index 3397a9e1..200b1954 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "build": "yarn clean && concurrently \"yarn build:node\" \"yarn build:browser\" \"yarn build:types\"", "dev": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\" \"yarn:serve\"", "docs": "typedoc --out docs src", + "lint": "eslint src", "serve": "http-server -p 8080 -c-1", "test": "mocha test/**/*.test.ts test/**/*.test.js", "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js --watch-files build", diff --git a/src/functions/base.ts b/src/functions/base.ts index 44059cf6..d5d40191 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -1,4 +1,4 @@ -import { _get_original_index, _pad_shape, _unbroadcast } from '../broadcasting'; +import { _unbroadcast } from '../broadcasting'; import { zeros_like } from '../creation'; import { Tensor } from '../tensor'; import { eventBus, getNextId, events } from '../util'; diff --git a/src/functions/mixin.ts b/src/functions/mixin.ts index 5472360a..59da22a8 100644 --- a/src/functions/mixin.ts +++ b/src/functions/mixin.ts @@ -1,9 +1,7 @@ import { Tensor } from '../tensor'; import { _broadcast_shape, - _get_original_index_from_transposed_index, _get_original_index, - _get_original_index_kernel, _pad_shape } from '../broadcasting'; import { TorchFunction, BinaryFunction, UnaryFunction, nullOp } from './base'; @@ -212,7 +210,7 @@ export function ReductionFunctionMixin( restored_dz = dz.reshape(target_shape); } - let expanded_dz = restored_dz.expand(a.shape); + const expanded_dz = restored_dz.expand(a.shape); const grad_a = backward_operations(a, expanded_dz, this.dim, this.keepdim); aFn.backward(grad_a); diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 698b2962..1784e162 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -1,9 +1,7 @@ import { Tensor } from '../tensor'; import { _broadcast_shape, - _get_original_index_from_transposed_index, _get_original_index, - _get_original_index_kernel, _pad_shape, _unbroadcast } from '../broadcasting'; @@ -550,8 +548,8 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = const m = Math.floor(mn_idx / dim_N); const n = mn_idx % dim_N; - let base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n); - let base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N); + const base_a = _get_original_index(padded_a_shape, broadcast_shape, i - n); + const base_b = _get_original_index(padded_b_shape, broadcast_shape, i - m * dim_N); let sum = 0; for (let k = 0; k < dim_K; k++) { @@ -658,9 +656,9 @@ function _convNd_forward( groups: number, dims: number ): Tensor { - let stride_arr = typeof stride === 'number' ? new Array(dims).fill(stride) : stride; - let padding_arr = typeof padding === 'number' ? new Array(dims).fill(padding) : padding; - let dilation_arr = typeof dilation === 'number' ? new Array(dims).fill(dilation) : dilation; + const stride_arr = typeof stride === 'number' ? new Array(dims).fill(stride) : stride; + const padding_arr = typeof padding === 'number' ? new Array(dims).fill(padding) : padding; + const dilation_arr = typeof dilation === 'number' ? new Array(dims).fill(dilation) : dilation; const batch_size = input.shape[0]; const in_channels = input.shape[1]; @@ -780,9 +778,9 @@ function _convNd_backward( input_requires_grad: boolean, weight_requires_grad: boolean ): [Tensor | null, Tensor | null, Tensor | null] { - let stride_arr = typeof stride === 'number' ? new Array(dims).fill(stride) : stride; - let padding_arr = typeof padding === 'number' ? new Array(dims).fill(padding) : padding; - let dilation_arr = typeof dilation === 'number' ? new Array(dims).fill(dilation) : dilation; + const stride_arr = typeof stride === 'number' ? new Array(dims).fill(stride) : stride; + const padding_arr = typeof padding === 'number' ? new Array(dims).fill(padding) : padding; + const dilation_arr = typeof dilation === 'number' ? new Array(dims).fill(dilation) : dilation; const batch_size = input.shape[0]; const in_channels = input.shape[1]; diff --git a/src/nn/module.ts b/src/nn/module.ts index e2fbd8c1..6b7695f3 100644 --- a/src/nn/module.ts +++ b/src/nn/module.ts @@ -91,7 +91,7 @@ abstract class _ConvNd extends Module { throw new Error('out_channels must be divisible by groups'); } - let kernel_arr = typeof kernel_size === 'number' ? new Array(dims).fill(kernel_size) : kernel_size; + const kernel_arr = typeof kernel_size === 'number' ? new Array(dims).fill(kernel_size) : kernel_size; const kernel_vol = kernel_arr.reduce((a: number, b: number) => a * b, 1); const k = Math.sqrt(groups / (in_channels * kernel_vol)); diff --git a/src/optim/optimizers.ts b/src/optim/optimizers.ts index 48034801..fc2eb064 100644 --- a/src/optim/optimizers.ts +++ b/src/optim/optimizers.ts @@ -47,7 +47,7 @@ export class SGD extends Optimizer { this.state.set(param, { velocity: g }); } - let buf = this.state.get(param)!.velocity; + const buf = this.state.get(param)!.velocity; if (this.nesterov) { g = g.add(buf.mul(this.momentum)); diff --git a/src/tensor.ts b/src/tensor.ts index 328da56d..23760b53 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,4 +1,3 @@ -import { _get_original_index } from './broadcasting'; import { AccumulateGrad, TorchFunction } from './functions/base'; import { getOperation, getOperationCache } from './functions/registry'; import { getNextId, eventBus, events } from './util'; @@ -97,7 +96,7 @@ export class Tensor { let flatIndex = 0; const flatData = this.data; - const buildDimension = (currentDim: number): any[] => { + const buildDimension = (currentDim: number): NestedNumberArray => { const size = this.shape[currentDim]; const result = new Array(size); const isLastDimension = currentDim === this.shape.length - 1; From 2da90ed725a44ea01fae7367e539a406261d04ab Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 15:30:12 +0800 Subject: [PATCH 093/128] feat: restrict torch and numpy versions --- scripts/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 5dec6caf..5ecc8ff9 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,4 +1,4 @@ --extra-index-url https://download.pytorch.org/whl/cpu -torch==2.10.0 -numpy +torch==2.10.* +numpy~=2.4.0 From c2c560c41b0e46a728ee1c967b6313dc43fc9108 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 23:22:29 +0800 Subject: [PATCH 094/128] feat: test coverage --- .github/workflows/build-test-publish.yml | 7 +- .gitignore | 2 +- package.json | 16 +- yarn.lock | 199 ++++++++++++++++++++++- 4 files changed, 216 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 81e2ba99..d8aee322 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -23,11 +23,14 @@ jobs: - name: Install dependencies run: yarn install --immutable + - name: Test on src/ + run: yarn test:coverage + - name: Build run: yarn build - - name: Test - run: yarn test + - name: Test on build/ + run: yarn test:build - name: Build docs run: yarn docs diff --git a/.gitignore b/.gitignore index aaf4e907..32aca4cb 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,4 @@ yarn-error.log /.tool-versions .direnv -.idea \ No newline at end of file +.idea diff --git a/package.json b/package.json index 200b1954..9a7e1405 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "types": "./build/types/src/index.d.ts", "exports": { ".": { + "torch-src": "./src/index.ts", "types": "./build/types/src/index.d.ts", "browser": "./build/browser/torch.browser.es.js", "import": "./build/node/torch.node.es.mjs", @@ -37,14 +38,25 @@ "docs": "typedoc --out docs src", "lint": "eslint src", "serve": "http-server -p 8080 -c-1", - "test": "mocha test/**/*.test.ts test/**/*.test.js", - "test:watch": "mocha --watch test/**/*.test.ts test/**/*.test.js --watch-files build", + "test": "mocha --node-option conditions=torch-src test/**/*.test.ts test/**/*.test.js", + "test:build": "mocha test/**/*.test.ts test/**/*.test.js", + "test:coverage": "c8 mocha --node-option conditions=torch-src test/**/*.test.ts test/**/*.test.js", + "test:watch": "mocha --node-option conditions=torch-src --watch test/**/*.test.ts test/**/*.test.js", "update-tests": "python3 scripts/generate_tests.py > test/testcases.gen.js" }, + "scriptsComments": { + "build": "Builds the library for browser and node.", + "dev": "Starts a dev session. Watch and build, test, and serve on localhost:8080", + "test": "Tests on code in src/", + "test:build": "Tests on built library in build/", + "test:coverage": "Provide test coverage", + "update-tests": "Updates test using scripts/generate_tests.py to test/testcases.gen.js" + }, "devDependencies": { "@eslint/js": "^9.37.0", "@types/mocha": "^10.0.10", "@types/node": "^24.6.2", + "c8": "^11.0.0", "chai": "^6.2.0", "concurrently": "^9.2.1", "eslint": "^9.37.0", diff --git a/yarn.lock b/yarn.lock index c5930873..f10f0aaa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -76,6 +76,13 @@ __metadata: languageName: node linkType: hard +"@bcoe/v8-coverage@npm:^1.0.1": + version: 1.0.2 + resolution: "@bcoe/v8-coverage@npm:1.0.2" + checksum: 10c0/1eb1dc93cc17fb7abdcef21a6e7b867d6aa99a7ec88ec8207402b23d9083ab22a8011213f04b2cf26d535f1d22dc26139b7929e6c2134c254bd1e14ba5e678c3 + languageName: node + linkType: hard + "@cspotcode/source-map-support@npm:^0.8.0": version: 0.8.1 resolution: "@cspotcode/source-map-support@npm:0.8.1" @@ -445,14 +452,21 @@ __metadata: languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:^3.0.3": +"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.2 resolution: "@jridgewell/resolve-uri@npm:3.1.2" checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.5.5": +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.5": version: 1.5.5 resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 @@ -469,6 +483,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.12": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 + languageName: node + linkType: hard + "@jsdevtools/ez-spawn@npm:^3.0.4": version: 3.0.4 resolution: "@jsdevtools/ez-spawn@npm:3.0.4" @@ -1078,6 +1102,13 @@ __metadata: languageName: node linkType: hard +"@types/istanbul-lib-coverage@npm:^2.0.1": + version: 2.0.6 + resolution: "@types/istanbul-lib-coverage@npm:2.0.6" + checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7 + languageName: node + linkType: hard + "@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" @@ -1632,6 +1663,13 @@ __metadata: languageName: node linkType: hard +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b + languageName: node + linkType: hard + "basic-auth@npm:^2.0.1": version: 2.0.1 resolution: "basic-auth@npm:2.0.1" @@ -1667,6 +1705,15 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^5.0.2": + version: 5.0.4 + resolution: "brace-expansion@npm:5.0.4" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10c0/359cbcfa80b2eb914ca1f3440e92313fbfe7919ee6b274c35db55bec555aded69dac5ee78f102cec90c35f98c20fa43d10936d0cd9978158823c249257e1643a + languageName: node + linkType: hard + "braces@npm:^3.0.3": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -1683,6 +1730,32 @@ __metadata: languageName: node linkType: hard +"c8@npm:^11.0.0": + version: 11.0.0 + resolution: "c8@npm:11.0.0" + dependencies: + "@bcoe/v8-coverage": "npm:^1.0.1" + "@istanbuljs/schema": "npm:^0.1.3" + find-up: "npm:^5.0.0" + foreground-child: "npm:^3.1.1" + istanbul-lib-coverage: "npm:^3.2.0" + istanbul-lib-report: "npm:^3.0.1" + istanbul-reports: "npm:^3.1.6" + test-exclude: "npm:^8.0.0" + v8-to-istanbul: "npm:^9.0.0" + yargs: "npm:^17.7.2" + yargs-parser: "npm:^21.1.1" + peerDependencies: + monocart-coverage-reports: ^2 + peerDependenciesMeta: + monocart-coverage-reports: + optional: true + bin: + c8: bin/c8.js + checksum: 10c0/94b0cf8756715ca8fedb9331c61ebda0c5bbd63c5eeea523d18904af790f6f197a02f547c066fa2d8d0544bb9f9547a6a67d653f3575953139c74ca915771963 + languageName: node + linkType: hard + "cacache@npm:^19.0.1": version: 19.0.1 resolution: "cacache@npm:19.0.1" @@ -1861,6 +1934,13 @@ __metadata: languageName: node linkType: hard +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b + languageName: node + linkType: hard + "corser@npm:^2.0.1": version: 2.0.1 resolution: "corser@npm:2.0.1" @@ -2641,7 +2721,7 @@ __metadata: languageName: node linkType: hard -"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1": +"foreground-child@npm:^3.1.0, foreground-child@npm:^3.1.1, foreground-child@npm:^3.3.1": version: 3.3.1 resolution: "foreground-child@npm:3.3.1" dependencies: @@ -2833,6 +2913,17 @@ __metadata: languageName: node linkType: hard +"glob@npm:^13.0.6": + version: 13.0.6 + resolution: "glob@npm:13.0.6" + dependencies: + minimatch: "npm:^10.2.2" + minipass: "npm:^7.1.3" + path-scurry: "npm:^2.0.2" + checksum: 10c0/269c236f11a9b50357fe7a8c6aadac667e01deb5242b19c84975628f05f4438d8ee1354bb62c5d6c10f37fd59911b54d7799730633a2786660d8c69f1d18120a + languageName: node + linkType: hard + "globals@npm:^14.0.0": version: 14.0.0 resolution: "globals@npm:14.0.0" @@ -2946,6 +3037,13 @@ __metadata: languageName: node linkType: hard +"html-escaper@npm:^2.0.0": + version: 2.0.2 + resolution: "html-escaper@npm:2.0.2" + checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.2.0 resolution: "http-cache-semantics@npm:4.2.0" @@ -3361,6 +3459,34 @@ __metadata: languageName: node linkType: hard +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b + languageName: node + linkType: hard + +"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: "npm:^3.0.0" + make-dir: "npm:^4.0.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.6": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" + dependencies: + html-escaper: "npm:^2.0.0" + istanbul-lib-report: "npm:^3.0.0" + checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc + languageName: node + linkType: hard + "jackspeak@npm:^3.1.2": version: 3.4.3 resolution: "jackspeak@npm:3.4.3" @@ -3571,6 +3697,15 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: "npm:^7.5.3" + checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 + languageName: node + linkType: hard + "make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" @@ -3662,6 +3797,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.2.2": + version: 10.2.4 + resolution: "minimatch@npm:10.2.4" + dependencies: + brace-expansion: "npm:^5.0.2" + checksum: 10c0/35f3dfb7b99b51efd46afd378486889f590e7efb10e0f6a10ba6800428cf65c9a8dedb74427d0570b318d749b543dc4e85f06d46d2858bc8cac7e1eb49a95945 + languageName: node + linkType: hard + "minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -3754,6 +3898,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^7.1.3": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb + languageName: node + linkType: hard + "minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": version: 3.1.0 resolution: "minizlib@npm:3.1.0" @@ -4070,6 +4221,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" + dependencies: + lru-cache: "npm:^11.0.0" + minipass: "npm:^7.1.2" + checksum: 10c0/b35ad37cf6557a87fd057121ce2be7695380c9138d93e87ae928609da259ea0a170fac6f3ef1eb3ece8a068e8b7f2f3adf5bb2374cf4d4a57fe484954fcc9482 + languageName: node + linkType: hard + "pathe@npm:^2.0.1, pathe@npm:^2.0.3": version: 2.0.3 resolution: "pathe@npm:2.0.3" @@ -4580,6 +4741,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.5.3": + version: 7.7.4 + resolution: "semver@npm:7.7.4" + bin: + semver: bin/semver.js + checksum: 10c0/5215ad0234e2845d4ea5bb9d836d42b03499546ddafb12075566899fc617f68794bb6f146076b6881d755de17d6c6cc73372555879ec7dce2c2feee947866ad2 + languageName: node + linkType: hard + "semver@npm:^7.6.0": version: 7.7.3 resolution: "semver@npm:7.7.3" @@ -4936,6 +5106,17 @@ __metadata: languageName: node linkType: hard +"test-exclude@npm:^8.0.0": + version: 8.0.0 + resolution: "test-exclude@npm:8.0.0" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^13.0.6" + minimatch: "npm:^10.2.2" + checksum: 10c0/f2b613cb5ddc05d1357892f5da965a6f7af42b19a6b2fc30c9b93cb74adf5059a3a9f29818adb75c96c1747b3934caac90a9058f73ce0640ea101de828a11600 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15, tinyglobby@npm:^0.2.9": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" @@ -4962,6 +5143,7 @@ __metadata: "@eslint/js": "npm:^9.37.0" "@types/mocha": "npm:^10.0.10" "@types/node": "npm:^24.6.2" + c8: "npm:^11.0.0" chai: "npm:^6.2.0" concurrently: "npm:^9.2.1" eslint: "npm:^9.37.0" @@ -5340,6 +5522,17 @@ __metadata: languageName: node linkType: hard +"v8-to-istanbul@npm:^9.0.0": + version: 9.3.0 + resolution: "v8-to-istanbul@npm:9.3.0" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.12" + "@types/istanbul-lib-coverage": "npm:^2.0.1" + convert-source-map: "npm:^2.0.0" + checksum: 10c0/968bcf1c7c88c04df1ffb463c179558a2ec17aa49e49376120504958239d9e9dad5281aa05f2a78542b8557f2be0b0b4c325710262f3b838b40d703d5ed30c23 + languageName: node + linkType: hard + "validate-npm-package-name@npm:^5.0.1": version: 5.0.1 resolution: "validate-npm-package-name@npm:5.0.1" From 18380313b380ca9156fd365ed864254fd5ad1007 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 10 Mar 2026 23:28:40 +0800 Subject: [PATCH 095/128] ci: update to node 24 in github actions --- .github/workflows/build-test-publish.yml | 6 +++--- .github/workflows/verify-generated-tests.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index d8aee322..6fa5d4fc 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -9,15 +9,15 @@ jobs: timeout-minutes: 10 steps: - name: Check out source code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Enable Corepack run: corepack enable - name: Use Node.js 💻 - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 24 cache: yarn - name: Install dependencies diff --git a/.github/workflows/verify-generated-tests.yml b/.github/workflows/verify-generated-tests.yml index b48f3872..2b1a3d86 100644 --- a/.github/workflows/verify-generated-tests.yml +++ b/.github/workflows/verify-generated-tests.yml @@ -8,15 +8,15 @@ jobs: timeout-minutes: 10 steps: - name: Check out source code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Enable Corepack run: corepack enable - name: Use Node.js 💻 - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 24 cache: yarn - name: Install dependencies From 62456ef0eafe3689eaa51c8495537d61152418f8 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 00:05:17 +0800 Subject: [PATCH 096/128] fix: maxi/minimum and pow edge cases, and add edge tests, nan_to_num --- scripts/generate_tests.py | 16 +- src/functions/functional.ts | 1 + src/functions/ops.ts | 46 +- src/tensor.ts | 4 + test/generated.test.js | 60 +- test/testcases.gen.js | 18159 ++++++++++++++++++---------------- 6 files changed, 9642 insertions(+), 8644 deletions(-) diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index 34c0a0bf..d7edb08f 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -10,6 +10,11 @@ def generate_unary_tests(op_name, num_tests=3): tests = [] for i in range(num_tests): x = torch.randn(3, 3, requires_grad=True) + with torch.no_grad(): + x[0, 0] = 0 + x[0, 1] = 1 + x[0, 2] = -1 + torch_op = getattr(torch, op_name) y = torch_op(x) y.sum().backward() @@ -24,8 +29,15 @@ def generate_unary_tests(op_name, num_tests=3): def generate_binary_tests(op_name, num_tests=3): tests = [] for i in range(num_tests): - x = torch.randn(3, 3, requires_grad=True) - y = torch.randn(3, 3, requires_grad=True) + x = torch.randn(4, 4, requires_grad=True) + y = torch.randn(4, 4, requires_grad=True) + with torch.no_grad(): + x[0:2, 0] = 0 + x[0:2, 1] = 1 + x[0:2, 2] = -1 + y[0, 0:2] = 0 + y[1, 0:2] = 1 + y[2, 0:2] = -1 torch_op = getattr(torch, op_name) out = torch_op(x, y) diff --git a/src/functions/functional.ts b/src/functions/functional.ts index 19119d7e..9eb40cab 100644 --- a/src/functions/functional.ts +++ b/src/functions/functional.ts @@ -60,6 +60,7 @@ export const abs = generate_unary_function('abs'); export const sign = generate_unary_function('sign'); export const neg = generate_unary_function('neg'); export const reciprocal = generate_unary_function('reciprocal'); +export const nan_to_num = generate_unary_function('nan_to_num'); export const reshape = generate_function('reshape'); export const squeeze = generate_function('squeeze'); export const unsqueeze = generate_function('unsqueeze'); diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 1784e162..c68247d5 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -73,11 +73,23 @@ const Div = BinaryFunctionMixin( "div" ); +function _where(mask: Tensor, x: Tensor, fallback: Tensor | number): Tensor { + const fb = typeof fallback === 'number' ? fallback : null; + const data = new Array(x.dataLength()); + for (let i = 0; i < data.length; i++) { + data[i] = mask.data[i] ? x.data[i] : (fb !== null ? fb : (fallback as Tensor).data[i]); + } + return new Tensor(data, {}, { shape: x.shape }); +} + const Pow = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => Math.pow(a[a_index], b[b_index]), (a, b, aFn, bFn, dz) => { - aFn.backward(dz.mul(b).mul(a.pow(b.sub(new Tensor(1))))); - bFn.backward(dz.mul(a.pow(b)).mul(a.log())); + const ga = dz.mul(b).mul(a.pow(b.sub(new Tensor(1)))); + const gb = dz.mul(a.pow(b)).mul(a.log()); + // When a==0, grads can produce NaN/Inf (from 0*Inf or log(0)); replace with 0 + aFn.backward(_where(a.ne(0), ga, ga.nan_to_num())); + bFn.backward(_where(a.ne(0), gb, 0)); }, "pow" ); @@ -93,8 +105,12 @@ const Fmod = BinaryFunctionMixin( const Maximum = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => Math.max(a[a_index], b[b_index]), (a, b, aFn, bFn, dz) => { - aFn.backward(dz.mul(a.ge(b))); - bFn.backward(dz.mul(b.gt(a))); + // When a == b, PyTorch splits gradient 0.5 each + const eq_mask = a.eq(b); + const a_mask = a.gt(b).add(eq_mask.mul(new Tensor(0.5))); + const b_mask = b.gt(a).add(eq_mask.mul(new Tensor(0.5))); + aFn.backward(dz.mul(a_mask)); + bFn.backward(dz.mul(b_mask)); }, "maximum" ); @@ -102,8 +118,12 @@ const Maximum = BinaryFunctionMixin( const Minimum = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => Math.min(a[a_index], b[b_index]), (a, b, aFn, bFn, dz) => { - aFn.backward(dz.mul(a.le(b))); - bFn.backward(dz.mul(b.lt(a))); + // When a == b, PyTorch splits gradient 0.5 each + const eq_mask = a.eq(b); + const a_mask = a.lt(b).add(eq_mask.mul(new Tensor(0.5))); + const b_mask = b.lt(a).add(eq_mask.mul(new Tensor(0.5))); + aFn.backward(dz.mul(a_mask)); + bFn.backward(dz.mul(b_mask)); }, "minimum" ); @@ -208,6 +228,20 @@ const Reciprocal = UnaryFunctionMixin( "reciprocal" ); +const NanToNum = UnaryFunctionMixin( + (a: number[], x: number) => { + const v = a[x]; + if (Number.isNaN(v)) return 0; + if (v === Infinity) return 3.4028235e+38; + if (v === -Infinity) return -3.4028235e+38; + return v; + }, + (a, aFn, dz) => { + aFn.backward(dz); + }, + "nan_to_num" +); + class Reshape extends TorchFunction { protected _forward(a: Tensor, shape: number[]) { const previous_length = a.dataLength(); diff --git a/src/tensor.ts b/src/tensor.ts index 23760b53..ed3f2c7f 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -264,6 +264,10 @@ export class Tensor { return this._executeUnaryOp('reciprocal'); } + nan_to_num(): Tensor { + return this._executeUnaryOp('nan_to_num'); + } + reshape(shape: number[]): Tensor { return this._executeOpRaw('reshape', shape); } diff --git a/test/generated.test.js b/test/generated.test.js index e6c99eb1..fe6f90fe 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -3,17 +3,19 @@ import { Tensor } from 'torch'; import { assert } from 'chai'; import { testData } from './testcases.gen.js'; -function assertDeepCloseTo(actual, expected, delta = 1e-3, first_call = true) { +function assertDeepCloseTo(actual, expected, name = null, delta = 1e-3, first_call = true) { if (Array.isArray(expected)) { assert.lengthOf(actual, expected.length, 'Array lengths do not match'); for (let i = 0; i < expected.length; i++) { - assertDeepCloseTo(actual[i], expected[i], delta, false); + assertDeepCloseTo(actual[i], expected[i], name, delta, false); } } else { if (Number.isNaN(expected)) { - assert.isTrue(Number.isNaN(actual), `Expected NaN but got ${actual}`); + assert.isTrue(Number.isNaN(actual), `${name}: Expected NaN but got ${actual}`); + } else if(!Number.isFinite(expected)) { + assert.equal(actual, expected, `${name}: Expected ${expected} but got ${actual}`); } else { - assert.closeTo(actual, expected, delta); + assert.closeTo(actual, expected, delta, `${name}: Expected ${expected} but got ${actual}`); } } } @@ -26,9 +28,9 @@ describe('Automated Tests', () => { it(`case ${idx + 1}`, () => { const x = new Tensor(test.input, { requires_grad: true }); const y = x[opName](); - assertDeepCloseTo(y.toArray(), test.expected_output); + assertDeepCloseTo(y.toArray(), test.expected_output, `${opName} output`); y.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad, `${opName} grad`); }); }); }); @@ -43,10 +45,10 @@ describe('Automated Tests', () => { const x = new Tensor(test.input_x, { requires_grad: true }); const y = new Tensor(test.input_y, { requires_grad: true }); const out = x[opName](y); - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${opName} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); - assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x, `${opName} grad x`); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y, `${opName} grad y`); }); }); }); @@ -61,10 +63,10 @@ describe('Automated Tests', () => { const out = x[test.op_name](y); - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${test.test_name} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); - assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x, `${test.test_name} grad x`); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y, `${test.test_name} grad y`); }); }); }); @@ -77,10 +79,10 @@ describe('Automated Tests', () => { const out = x.matmul(y); - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${test.test_name} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x); - assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_x, `${test.test_name} grad x`); + assertDeepCloseTo(y.grad.toArray(), test.expected_grad_y, `${test.test_name} grad y`); }); }); }); @@ -95,9 +97,9 @@ describe('Automated Tests', () => { } else { out = x[test.op_name](test.dim, test.keepdim); } - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${test.test_name} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad, `${test.test_name} grad`); }); }); }); @@ -115,13 +117,13 @@ describe('Automated Tests', () => { const x = new Tensor(test.input, { requires_grad: true }); const out = layer.forward(x); - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${test.test_name} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_input); - assertDeepCloseTo(layer.weight.grad.toArray(), test.expected_grad_weight); - assertDeepCloseTo(layer.bias.grad.toArray(), test.expected_grad_bias); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_input, `${test.test_name} grad input`); + assertDeepCloseTo(layer.weight.grad.toArray(), test.expected_grad_weight, `${test.test_name} grad weight`); + assertDeepCloseTo(layer.bias.grad.toArray(), test.expected_grad_bias, `${test.test_name} grad bias`); }); }); }); @@ -149,14 +151,14 @@ describe('Automated Tests', () => { const x = new Tensor(test.input, { requires_grad: true }); const out = layer.forward(x); - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${test.test_name} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad_input); - assertDeepCloseTo(layer.weight.grad.toArray(), test.expected_grad_weight); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad_input, `${test.test_name} grad input`); + assertDeepCloseTo(layer.weight.grad.toArray(), test.expected_grad_weight, `${test.test_name} grad weight`); if (test.has_bias) { - assertDeepCloseTo(layer.bias.grad.toArray(), test.expected_grad_bias); + assertDeepCloseTo(layer.bias.grad.toArray(), test.expected_grad_bias, `${test.test_name} grad bias`); } }); }); @@ -198,11 +200,11 @@ describe('Automated Tests', () => { const loss = w.mul(x).sum(); loss.backward(); - assertDeepCloseTo(w.grad.toArray(), test.expected_grad); + assertDeepCloseTo(w.grad.toArray(), test.expected_grad, `${test.test_name} grad`); optimizer.step(); - assertDeepCloseTo(w.toArray(), test.expected_updated_weight); + assertDeepCloseTo(w.toArray(), test.expected_updated_weight, `${test.test_name} updated weight`); }); }); }); @@ -212,9 +214,9 @@ describe('Automated Tests', () => { it(test.test_name, () => { const x = new Tensor(test.input, { requires_grad: true }); const out = x.expand(test.expand_shape); - assertDeepCloseTo(out.toArray(), test.expected_output); + assertDeepCloseTo(out.toArray(), test.expected_output, `${test.test_name} output`); out.sum().backward(); - assertDeepCloseTo(x.grad.toArray(), test.expected_grad); + assertDeepCloseTo(x.grad.toArray(), test.expected_grad, `${test.test_name} grad`); }); }); }); diff --git a/test/testcases.gen.js b/test/testcases.gen.js index 7fc8a0b2..ebcfda28 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -4,9 +4,9 @@ export const testData = { { "input": [ [ - 0.33669036626815796, - 0.12880940735340118, - 0.23446236550807953 + 0.0, + 1.0, + -1.0 ], [ 0.23033303022384644, @@ -21,9 +21,9 @@ export const testData = { ], "expected_output": [ [ - -1.0885915756225586, - -2.0494213104248047, - -1.4504601955413818 + -Infinity, + 0.0, + NaN ], [ -1.468229055404663, @@ -38,9 +38,9 @@ export const testData = { ], "expected_grad": [ [ - 2.970088005065918, - 7.763408184051514, - 4.265076637268066 + Infinity, + 1.0, + -1.0 ], [ 4.3415398597717285, @@ -57,9 +57,9 @@ export const testData = { { "input": [ [ - 0.2673508822917938, - 0.5349046587944031, - 0.809357225894928 + 0.0, + 1.0, + -1.0 ], [ 1.110290288925171, @@ -74,9 +74,9 @@ export const testData = { ], "expected_output": [ [ - -1.3191933631896973, - -0.6256667375564575, - -0.2115148901939392 + -Infinity, + 0.0, + NaN ], [ 0.10462149977684021, @@ -91,9 +91,9 @@ export const testData = { ], "expected_grad": [ [ - 3.740402936935425, - 1.8694920539855957, - 1.2355483770370483 + Infinity, + 1.0, + -1.0 ], [ 0.9006653428077698, @@ -110,9 +110,9 @@ export const testData = { { "input": [ [ - -0.765838623046875, - -0.7506223320960999, - 1.3525477647781372 + 0.0, + 1.0, + -1.0 ], [ 0.6863219141960144, @@ -127,9 +127,9 @@ export const testData = { ], "expected_output": [ [ - NaN, - NaN, - 0.3019900321960449 + -Infinity, + 0.0, + NaN ], [ -0.37640848755836487, @@ -144,9 +144,9 @@ export const testData = { ], "expected_grad": [ [ - -1.3057581186294556, - -1.3322278261184692, - 0.7393454313278198 + Infinity, + 1.0, + -1.0 ], [ 1.4570422172546387, @@ -165,9 +165,9 @@ export const testData = { { "input": [ [ - -0.23835687339305878, - -0.049903348088264465, - 0.5263369679450989 + 0.0, + 1.0, + -1.0 ], [ -0.008498823270201683, @@ -182,9 +182,9 @@ export const testData = { ], "expected_output": [ [ - NaN, - NaN, - 0.7254908680915833 + 0.0, + 1.0, + NaN ], [ NaN, @@ -199,9 +199,9 @@ export const testData = { ], "expected_grad": [ [ - NaN, - NaN, - 0.689188539981842 + Infinity, + 0.5, + NaN ], [ NaN, @@ -218,9 +218,9 @@ export const testData = { { "input": [ [ - 0.14977970719337463, - -0.20889392495155334, - -0.38702094554901123 + 0.0, + 1.0, + -1.0 ], [ 0.9912377595901489, @@ -235,8 +235,8 @@ export const testData = { ], "expected_output": [ [ - 0.38701382279396057, - NaN, + 0.0, + 1.0, NaN ], [ @@ -252,8 +252,8 @@ export const testData = { ], "expected_grad": [ [ - 1.2919435501098633, - NaN, + Infinity, + 0.5, NaN ], [ @@ -271,9 +271,9 @@ export const testData = { { "input": [ [ - -0.2253875583410263, - -0.34169748425483704, - 0.3040127456188202 + 0.0, + 1.0, + -1.0 ], [ -0.6890136003494263, @@ -288,9 +288,9 @@ export const testData = { ], "expected_output": [ [ - NaN, - NaN, - 0.5513734817504883 + 0.0, + 1.0, + NaN ], [ NaN, @@ -305,9 +305,9 @@ export const testData = { ], "expected_grad": [ [ - NaN, - NaN, - 0.9068263173103333 + Infinity, + 0.5, + NaN ], [ NaN, @@ -326,9 +326,9 @@ export const testData = { { "input": [ [ - -3.594468832015991, - 0.019150810316205025, - 0.1051730141043663 + 0.0, + 1.0, + -1.0 ], [ 0.960340142250061, @@ -343,9 +343,9 @@ export const testData = { ], "expected_output": [ [ - 0.027475273236632347, - 1.019335389137268, - 1.1109027862548828 + 1.0, + 2.7182817459106445, + 0.3678794503211975 ], [ 2.6125850677490234, @@ -360,9 +360,9 @@ export const testData = { ], "expected_grad": [ [ - 0.027475273236632347, - 1.019335389137268, - 1.1109027862548828 + 1.0, + 2.7182817459106445, + 0.3678794503211975 ], [ 2.6125850677490234, @@ -379,9 +379,9 @@ export const testData = { { "input": [ [ - 1.4111539125442505, - -0.655610978603363, - 0.8576056957244873 + 0.0, + 1.0, + -1.0 ], [ -1.6270242929458618, @@ -396,9 +396,9 @@ export const testData = { ], "expected_output": [ [ - 4.100684642791748, - 0.5191248059272766, - 2.3575093746185303 + 1.0, + 2.7182817459106445, + 0.3678794503211975 ], [ 0.19651347398757935, @@ -413,9 +413,9 @@ export const testData = { ], "expected_grad": [ [ - 4.100684642791748, - 0.5191248059272766, - 2.3575093746185303 + 1.0, + 2.7182817459106445, + 0.3678794503211975 ], [ 0.19651347398757935, @@ -432,9 +432,9 @@ export const testData = { { "input": [ [ - -0.13348686695098877, - 0.34148848056793213, - -0.07157137989997864 + 0.0, + 1.0, + -1.0 ], [ -0.09089037775993347, @@ -449,9 +449,9 @@ export const testData = { ], "expected_output": [ [ - 0.8750389814376831, - 1.4070403575897217, - 0.9309298396110535 + 1.0, + 2.7182817459106445, + 0.3678794503211975 ], [ 0.9131178259849548, @@ -466,9 +466,9 @@ export const testData = { ], "expected_grad": [ [ - 0.8750389814376831, - 1.4070403575897217, - 0.9309298396110535 + 1.0, + 2.7182817459106445, + 0.3678794503211975 ], [ 0.9131178259849548, @@ -487,9 +487,9 @@ export const testData = { { "input": [ [ - -0.9058369994163513, - -0.26072561740875244, - -0.5465103983879089 + 0.0, + 1.0, + -1.0 ], [ 2.117400646209717, @@ -504,9 +504,9 @@ export const testData = { ], "expected_output": [ [ - 0.8205406665802002, - 0.06797784566879272, - 0.2986736297607422 + 0.0, + 1.0, + 1.0 ], [ 4.4833855628967285, @@ -521,9 +521,9 @@ export const testData = { ], "expected_grad": [ [ - -1.8116739988327026, - -0.5214512348175049, - -1.0930207967758179 + 0.0, + 2.0, + -2.0 ], [ 4.234801292419434, @@ -540,9 +540,9 @@ export const testData = { { "input": [ [ - 1.450257658958435, - -0.6935664415359497, - 0.9966652989387512 + 0.0, + 1.0, + -1.0 ], [ 0.6130759119987488, @@ -557,9 +557,9 @@ export const testData = { ], "expected_output": [ [ - 2.1032471656799316, - 0.48103439807891846, - 0.9933417439460754 + 0.0, + 1.0, + 1.0 ], [ 0.3758620619773865, @@ -574,9 +574,9 @@ export const testData = { ], "expected_grad": [ [ - 2.90051531791687, - -1.3871328830718994, - 1.9933305978775024 + 0.0, + 2.0, + -2.0 ], [ 1.2261518239974976, @@ -593,9 +593,9 @@ export const testData = { { "input": [ [ - 0.9157298803329468, - -0.6429603099822998, - 0.7113185524940491 + 0.0, + 1.0, + -1.0 ], [ 0.39997783303260803, @@ -610,9 +610,9 @@ export const testData = { ], "expected_output": [ [ - 0.8385612368583679, - 0.41339796781539917, - 0.5059740543365479 + 0.0, + 1.0, + 1.0 ], [ 0.15998226404190063, @@ -627,9 +627,9 @@ export const testData = { ], "expected_grad": [ [ - 1.8314597606658936, - -1.2859206199645996, - 1.4226371049880981 + 0.0, + 2.0, + -2.0 ], [ 0.7999556660652161, @@ -648,9 +648,9 @@ export const testData = { { "input": [ [ - -1.2842116355895996, - -0.6916776895523071, - -0.5359472632408142 + 0.0, + 1.0, + -1.0 ], [ 0.33552202582359314, @@ -665,9 +665,9 @@ export const testData = { ], "expected_output": [ [ - 1.2842116355895996, - 0.6916776895523071, - 0.5359472632408142 + 0.0, + 1.0, + 1.0 ], [ 0.33552202582359314, @@ -682,8 +682,8 @@ export const testData = { ], "expected_grad": [ [ - -1.0, - -1.0, + 0.0, + 1.0, -1.0 ], [ @@ -701,9 +701,9 @@ export const testData = { { "input": [ [ - -0.2147795557975769, - 1.265119194984436, - -0.31780683994293213 + 0.0, + 1.0, + -1.0 ], [ -0.42791351675987244, @@ -718,9 +718,9 @@ export const testData = { ], "expected_output": [ [ - 0.2147795557975769, - 1.265119194984436, - 0.31780683994293213 + 0.0, + 1.0, + 1.0 ], [ 0.42791351675987244, @@ -735,7 +735,7 @@ export const testData = { ], "expected_grad": [ [ - -1.0, + 0.0, 1.0, -1.0 ], @@ -754,9 +754,9 @@ export const testData = { { "input": [ [ - -0.47487422823905945, - 1.6639716625213623, - 0.01096251793205738 + 0.0, + 1.0, + -1.0 ], [ 0.14468061923980713, @@ -771,9 +771,9 @@ export const testData = { ], "expected_output": [ [ - 0.47487422823905945, - 1.6639716625213623, - 0.01096251793205738 + 0.0, + 1.0, + 1.0 ], [ 0.14468061923980713, @@ -788,9 +788,9 @@ export const testData = { ], "expected_grad": [ [ - -1.0, + 0.0, 1.0, - 1.0 + -1.0 ], [ 1.0, @@ -809,9 +809,9 @@ export const testData = { { "input": [ [ - 1.0703048706054688, - -1.7378737926483154, - 0.18413154780864716 + 0.0, + 1.0, + -1.0 ], [ -0.1562519073486328, @@ -826,9 +826,9 @@ export const testData = { ], "expected_output": [ [ + 0.0, 1.0, - -1.0, - 1.0 + -1.0 ], [ -1.0, @@ -862,9 +862,9 @@ export const testData = { { "input": [ [ - -0.7581364512443542, - 0.9989117383956909, - -0.8792798519134521 + 0.0, + 1.0, + -1.0 ], [ 0.7485982179641724, @@ -879,7 +879,7 @@ export const testData = { ], "expected_output": [ [ - -1.0, + 0.0, 1.0, -1.0 ], @@ -915,9 +915,9 @@ export const testData = { { "input": [ [ - -1.0089720487594604, - -1.2315175533294678, - -1.046962022781372 + 0.0, + 1.0, + -1.0 ], [ -1.7460761070251465, @@ -932,8 +932,8 @@ export const testData = { ], "expected_output": [ [ - -1.0, - -1.0, + 0.0, + 1.0, -1.0 ], [ @@ -970,9 +970,9 @@ export const testData = { { "input": [ [ - -0.7723492980003357, - 0.15315502882003784, - 1.3269745111465454 + 0.0, + 1.0, + -1.0 ], [ -0.8023788928985596, @@ -987,9 +987,9 @@ export const testData = { ], "expected_output": [ [ - 0.7723492980003357, - -0.15315502882003784, - -1.3269745111465454 + -0.0, + -1.0, + 1.0 ], [ 0.8023788928985596, @@ -1023,9 +1023,9 @@ export const testData = { { "input": [ [ - -2.1798956394195557, - 0.20737595856189728, - -1.9843575954437256 + 0.0, + 1.0, + -1.0 ], [ -0.1816582977771759, @@ -1040,9 +1040,9 @@ export const testData = { ], "expected_output": [ [ - 2.1798956394195557, - -0.20737595856189728, - 1.9843575954437256 + -0.0, + -1.0, + 1.0 ], [ 0.1816582977771759, @@ -1076,9 +1076,9 @@ export const testData = { { "input": [ [ - -1.0002132654190063, - -0.024445118382573128, - 0.24967312812805176 + 0.0, + 1.0, + -1.0 ], [ -1.7517130374908447, @@ -1093,9 +1093,9 @@ export const testData = { ], "expected_output": [ [ - 1.0002132654190063, - 0.024445118382573128, - -0.24967312812805176 + -0.0, + -1.0, + 1.0 ], [ 1.7517130374908447, @@ -1131,9 +1131,9 @@ export const testData = { { "input": [ [ - -0.8561121225357056, - -0.53642737865448, - -1.0440475940704346 + 0.0, + 1.0, + -1.0 ], [ 1.2561368942260742, @@ -1148,9 +1148,9 @@ export const testData = { ], "expected_output": [ [ - -1.1680712699890137, - -1.8641852140426636, - -0.9578107595443726 + Infinity, + 1.0, + -1.0 ], [ 0.7960915565490723, @@ -1165,9 +1165,9 @@ export const testData = { ], "expected_grad": [ [ - -1.36439049243927, - -3.475186586380005, - -0.9174014329910278 + -Infinity, + -1.0, + -1.0 ], [ -0.6337617635726929, @@ -1184,9 +1184,9 @@ export const testData = { { "input": [ [ - 0.012067895382642746, - -0.6397443413734436, - 0.6415984630584717 + 0.0, + 1.0, + -1.0 ], [ -0.5963875651359558, @@ -1201,9 +1201,9 @@ export const testData = { ], "expected_output": [ [ - 82.86448669433594, - -1.563124418258667, - 1.5586072206497192 + Infinity, + 1.0, + -1.0 ], [ -1.6767619848251343, @@ -1218,9 +1218,9 @@ export const testData = { ], "expected_grad": [ [ - -6866.52294921875, - -2.4433579444885254, - -2.4292564392089844 + -Infinity, + -1.0, + -1.0 ], [ -2.811530828475952, @@ -1237,9 +1237,9 @@ export const testData = { { "input": [ [ - -1.7989355325698853, - -0.6020540595054626, - 0.673175573348999 + 0.0, + 1.0, + -1.0 ], [ 0.018282217904925346, @@ -1254,9 +1254,9 @@ export const testData = { ], "expected_output": [ [ - -0.5558843016624451, - -1.660980463027954, - 1.4854965209960938 + Infinity, + 1.0, + -1.0 ], [ 54.697959899902344, @@ -1271,9 +1271,9 @@ export const testData = { ], "expected_grad": [ [ - -0.30900734663009644, - -2.7588560581207275, - -2.206699848175049 + -Infinity, + -1.0, + -1.0 ], [ -2991.86669921875, @@ -1292,9 +1292,9 @@ export const testData = { { "input": [ [ - -1.600385069847107, - 0.8983902335166931, - -0.6497360467910767 + 0.0, + 1.0, + -1.0 ], [ 0.21935275197029114, @@ -1309,9 +1309,9 @@ export const testData = { ], "expected_output": [ [ - -0.9995622634887695, - 0.782325267791748, - -0.604976236820221 + 0.0, + 0.8414709568023682, + -0.8414709568023682 ], [ 0.21759793162345886, @@ -1326,9 +1326,9 @@ export const testData = { ], "expected_grad": [ [ - -0.029584426432847977, - 0.622870147228241, - 0.7962434887886047 + 1.0, + 0.5403023362159729, + 0.5403023362159729 ], [ 0.9760385155677795, @@ -1345,9 +1345,9 @@ export const testData = { { "input": [ [ - 1.1458033323287964, - -0.05559399351477623, - -0.3598405122756958 + 0.0, + 1.0, + -1.0 ], [ 1.1056941747665405, @@ -1362,9 +1362,9 @@ export const testData = { ], "expected_output": [ [ - 0.9110416173934937, - -0.05556536093354225, - -0.352124959230423 + 0.0, + 0.8414709568023682, + -0.8414709568023682 ], [ 0.8937757611274719, @@ -1379,9 +1379,9 @@ export const testData = { ], "expected_grad": [ [ - 0.41231441497802734, - 0.9984550476074219, - 0.9359530210494995 + 1.0, + 0.5403023362159729, + 0.5403023362159729 ], [ 0.44851410388946533, @@ -1398,9 +1398,9 @@ export const testData = { { "input": [ [ - 0.8266488909721375, - -1.0300014019012451, - 1.7748093605041504 + 0.0, + 1.0, + -1.0 ], [ 0.24461546540260315, @@ -1415,9 +1415,9 @@ export const testData = { ], "expected_output": [ [ - 0.7356656193733215, - -0.8572996854782104, - 0.9792613983154297 + 0.0, + 0.8414709568023682, + -0.8414709568023682 ], [ 0.24218325316905975, @@ -1432,9 +1432,9 @@ export const testData = { ], "expected_grad": [ [ - 0.6773448586463928, - 0.5148176550865173, - -0.20260076224803925 + 1.0, + 0.5403023362159729, + 0.5403023362159729 ], [ 0.9702305197715759, @@ -1453,9 +1453,9 @@ export const testData = { { "input": [ [ - -0.3285827040672302, - -0.3712422847747803, - -0.5473041534423828 + 0.0, + 1.0, + -1.0 ], [ 1.3824070692062378, @@ -1470,9 +1470,9 @@ export const testData = { ], "expected_output": [ [ - 0.9465006589889526, - 0.9318773746490479, - 0.8539305329322815 + 1.0, + 0.5403023362159729, + 0.5403023362159729 ], [ 0.1872768998146057, @@ -1487,9 +1487,9 @@ export const testData = { ], "expected_grad": [ [ - 0.3227018713951111, - 0.3627733588218689, - 0.5203870534896851 + -0.0, + -0.8414709568023682, + 0.8414709568023682 ], [ -0.9823071956634521, @@ -1506,9 +1506,9 @@ export const testData = { { "input": [ [ - 0.23622490465641022, - 0.2450244277715683, - 0.6467189788818359 + 0.0, + 1.0, + -1.0 ], [ 0.6161983609199524, @@ -1523,9 +1523,9 @@ export const testData = { ], "expected_output": [ [ - 0.9722284078598022, - 0.9701313972473145, - 0.7980651259422302 + 1.0, + 0.5403023362159729, + 0.5403023362159729 ], [ 0.8160814642906189, @@ -1540,9 +1540,9 @@ export const testData = { ], "expected_grad": [ [ - -0.23403404653072357, - -0.24258002638816833, - -0.6025711894035339 + -0.0, + -0.8414709568023682, + 0.8414709568023682 ], [ -0.5779368877410889, @@ -1559,9 +1559,9 @@ export const testData = { { "input": [ [ - -0.3060486316680908, - 0.9692544937133789, - -0.7809293270111084 + 0.0, + 1.0, + -1.0 ], [ 0.2835264801979065, @@ -1576,9 +1576,9 @@ export const testData = { ], "expected_output": [ [ - 0.9535315632820129, - 0.5659143328666687, - 0.7102596759796143 + 1.0, + 0.5403023362159729, + 0.5403023362159729 ], [ 0.9600749015808105, @@ -1593,9 +1593,9 @@ export const testData = { ], "expected_grad": [ [ - 0.3012932538986206, - -0.8244640231132507, - 0.7039397954940796 + -0.0, + -0.8414709568023682, + 0.8414709568023682 ], [ -0.2797430753707886, @@ -1614,9 +1614,9 @@ export const testData = { { "input": [ [ - -0.43932145833969116, - -0.212321937084198, - 0.07726861536502838 + 0.0, + 1.0, + -1.0 ], [ -0.8692201972007751, @@ -1631,9 +1631,9 @@ export const testData = { ], "expected_output": [ [ - -0.469951868057251, - -0.2155710756778717, - 0.07742276042699814 + 0.0, + 1.5574077367782593, + -1.5574077367782593 ], [ -1.1834511756896973, @@ -1648,9 +1648,9 @@ export const testData = { ], "expected_grad": [ [ - 1.2208547592163086, - 1.0464708805084229, - 1.0059943199157715 + 1.0, + 3.425518751144409, + 3.425518751144409 ], [ 2.4005565643310547, @@ -1667,9 +1667,9 @@ export const testData = { { "input": [ [ - -1.2612135410308838, - -0.08296369016170502, - -0.6891635060310364 + 0.0, + 1.0, + -1.0 ], [ 0.391975462436676, @@ -1684,9 +1684,9 @@ export const testData = { ], "expected_output": [ [ - -3.1262941360473633, - -0.08315455913543701, - -0.8239307999610901 + 0.0, + 1.5574077367782593, + -1.5574077367782593 ], [ 0.41336604952812195, @@ -1701,9 +1701,9 @@ export const testData = { ], "expected_grad": [ [ - 10.773715019226074, - 1.006914734840393, - 1.6788619756698608 + 1.0, + 3.425518751144409, + 3.425518751144409 ], [ 1.1708714962005615, @@ -1720,9 +1720,9 @@ export const testData = { { "input": [ [ - 0.1198730394244194, - -0.19844388961791992, - -1.130265712738037 + 0.0, + 1.0, + -1.0 ], [ 0.2562393546104431, @@ -1737,9 +1737,9 @@ export const testData = { ], "expected_output": [ [ - 0.12045053392648697, - -0.2010904848575592, - -2.1212105751037598 + 0.0, + 1.5574077367782593, + -1.5574077367782593 ], [ 0.2619987726211548, @@ -1754,9 +1754,9 @@ export const testData = { ], "expected_grad": [ [ - 1.0145083665847778, - 1.0404373407363892, - 5.4995341300964355 + 1.0, + 3.425518751144409, + 3.425518751144409 ], [ 1.06864333152771, @@ -1777,67 +1777,103 @@ export const testData = { { "input_x": [ [ - -0.017705317586660385, - -0.7571937441825867, - -1.6010069847106934 + 0.0, + 1.0, + -1.0, + -1.1133604049682617 + ], + [ + 0.0, + 1.0, + -1.0, + 0.2570752799510956 ], [ - 0.3873583972454071, - -0.57644122838974, - 0.20196054875850677 + 0.6377718448638916, + 0.15978877246379852, + 1.7697970867156982, + 0.6268176436424255 ], [ - 1.0855722427368164, - 1.2247178554534912, - 0.27423009276390076 + -0.4976125955581665, + -0.18228091299533844, + -0.21200162172317505, + 0.8162168264389038 ] ], "input_y": [ [ - -0.7684280276298523, - 0.6938012838363647, - -1.428295612335205 + 0.0, + 0.0, + 1.294582724571228, + 0.22267311811447144 + ], + [ + 1.0, + 1.0, + -0.8326117396354675, + -0.8129478096961975 ], [ - -0.37946099042892456, - 1.5014593601226807, - 0.12739363312721252 + -1.0, + -1.0, + 0.7637977004051208, + 1.1792222261428833 ], [ - 1.0316026210784912, - -0.5813775658607483, - 0.7993662357330322 + 0.08301948755979538, + 0.4220196604728699, + 0.3418477773666382, + -2.701582431793213 ] ], "expected_output": [ [ - -0.786133348941803, - -0.06339246034622192, - -3.0293025970458984 + 0.0, + 1.0, + 0.294582724571228, + -0.8906872868537903 + ], + [ + 1.0, + 2.0, + -1.8326117992401123, + -0.5558725595474243 ], [ - 0.007897406816482544, - 0.9250181317329407, - 0.3293541669845581 + -0.3622281551361084, + -0.8402112126350403, + 2.533594846725464, + 1.806039810180664 ], [ - 2.1171748638153076, - 0.6433402895927429, - 1.0735963582992554 + -0.4145931005477905, + 0.23973874747753143, + 0.12984615564346313, + -1.885365605354309 ] ], "expected_grad_x": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -1845,16 +1881,25 @@ export const testData = { ], "expected_grad_y": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -1864,67 +1909,103 @@ export const testData = { { "input_x": [ [ - 0.4884093105792999, - -2.1239805221557617, - -0.4837254583835602 + 0.0, + 1.0, + -1.0, + -0.5786357522010803 ], [ - -0.8704075217247009, - 0.7864606976509094, - 0.47071704268455505 - ], + 0.0, + 1.0, + -1.0, + 0.3255786597728729 + ], [ - -1.0652520656585693, - 0.7358277440071106, - 0.43029549717903137 + 0.043896086513996124, + 1.4443233013153076, + 0.23202891647815704, + 0.5064983367919922 + ], + [ + -0.9177634716033936, + 0.42056551575660706, + -0.368858277797699, + -0.7696145176887512 ] ], "input_y": [ [ - -0.6365610361099243, - -0.2711743116378784, - -0.7389668226242065 + 0.0, + 0.0, + -1.190559983253479, + 0.7756073474884033 + ], + [ + 1.0, + 1.0, + -1.881459355354309, + 0.5850948691368103 ], [ - 1.6474533081054688, - -0.5047107338905334, - 0.7850356101989746 + -1.0, + -1.0, + -0.8708454966545105, + -0.6410972476005554 ], [ - 0.3700398802757263, - 0.07554273307323456, - -1.5730698108673096 + 0.5373784899711609, + 0.7817491888999939, + 1.0477299690246582, + -0.39480558037757874 ] ], "expected_output": [ [ - -0.1481517255306244, - -2.3951549530029297, - -1.2226922512054443 + 0.0, + 1.0, + -2.1905598640441895, + 0.196971595287323 + ], + [ + 1.0, + 2.0, + -2.8814592361450195, + 0.9106734991073608 ], [ - 0.7770457863807678, - 0.281749963760376, - 1.255752682685852 + -0.9561039209365845, + 0.4443233013153076, + -0.6388165950775146, + -0.13459891080856323 ], [ - -0.695212185382843, - 0.8113704919815063, - -1.1427743434906006 + -0.38038498163223267, + 1.2023147344589233, + 0.6788716912269592, + -1.1644201278686523 ] ], "expected_grad_x": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -1932,16 +2013,25 @@ export const testData = { ], "expected_grad_y": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -1951,67 +2041,103 @@ export const testData = { { "input_x": [ [ - 0.2201399803161621, - 0.23505949974060059, - 1.0043964385986328 + 0.0, + 1.0, + -1.0, + -0.29864323139190674 + ], + [ + 0.0, + 1.0, + -1.0, + 0.881690502166748 ], [ - 0.4351750910282135, - -0.0459199883043766, - 0.7410483360290527 + -0.518220841884613, + 0.83954256772995, + 0.05852266773581505, + -1.6682480573654175 ], [ - 0.5975771546363831, - 0.7118588089942932, - -1.308319330215454 + -0.019966987892985344, + -1.2131143808364868, + 1.197104811668396, + -0.7817718386650085 ] ], "input_y": [ [ - -0.24913781881332397, - -1.2001056671142578, - 0.5043410658836365 + 0.0, + 0.0, + 0.2794382870197296, + -0.5718191266059875 + ], + [ + 1.0, + 1.0, + -0.37528103590011597, + 1.446703553199768 ], [ - 0.5920562744140625, - -0.8244076371192932, - -1.5402805805206299 + -1.0, + -1.0, + 0.12306158244609833, + 0.8757511377334595 ], [ - 0.4552428424358368, - 1.629791498184204, - -0.3871910572052002 + 0.21162617206573486, + 1.2271368503570557, + -0.5722804665565491, + -0.17070035636425018 ] ], "expected_output": [ [ - -0.028997838497161865, - -0.9650461673736572, - 1.508737564086914 + 0.0, + 1.0, + -0.7205617427825928, + -0.8704623579978943 + ], + [ + 1.0, + 2.0, + -1.3752810955047607, + 2.3283939361572266 ], [ - 1.0272313356399536, - -0.8703276515007019, - -0.7992322444915771 + -1.5182209014892578, + -0.16045743227005005, + 0.18158425390720367, + -0.792496919631958 ], [ - 1.0528199672698975, - 2.3416502475738525, - -1.6955103874206543 + 0.19165918231010437, + 0.014022469520568848, + 0.6248243451118469, + -0.9524722099304199 ] ], "expected_grad_x": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -2019,16 +2145,25 @@ export const testData = { ], "expected_grad_y": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -2040,67 +2175,103 @@ export const testData = { { "input_x": [ [ - 0.20325958728790283, - 1.5292197465896606, - 0.04372377693653107 + 0.0, + 1.0, + -1.0, + 1.541925072669983 + ], + [ + 0.0, + 1.0, + -1.0, + -1.3860632181167603 ], [ - -1.480481505393982, - -0.23249931633472443, - -0.415950745344162 + -1.2519514560699463, + 3.0250484943389893, + 1.3462589979171753, + 0.8556069731712341 ], [ - 1.4263980388641357, - -1.0918711423873901, - -0.7077858448028564 + -1.525596261024475, + 1.2538059949874878, + -0.684340238571167, + -2.121647357940674 ] ], "input_y": [ [ - 1.0836158990859985, - -0.19257144629955292, - -1.0489495992660522 + 0.0, + 0.0, + -0.4809381365776062, + -0.9903622269630432 + ], + [ + 1.0, + 1.0, + -1.0486466884613037, + 1.7823078632354736 ], [ - -0.012573999352753162, - 1.1939914226531982, - 1.120118260383606 + -1.0, + -1.0, + 0.9993040561676025, + 1.2751853466033936 ], [ - -0.5828483700752258, - -0.06718457490205765, - 0.3241202235221863 + 1.2704023122787476, + -0.07503493875265121, + -2.2949612140655518, + -1.3630598783493042 ] ], "expected_output": [ [ - -0.8803563117980957, - 1.72179114818573, - 1.092673420906067 + 0.0, + 1.0, + -0.5190618634223938, + 2.532287359237671 + ], + [ + -1.0, + 0.0, + 0.04864668846130371, + -3.1683712005615234 ], [ - -1.4679075479507446, - -1.4264907836914062, - -1.5360690355300903 + -0.2519514560699463, + 4.02504825592041, + 0.34695494174957275, + -0.4195783734321594 ], [ - 2.009246349334717, - -1.024686574935913, - -1.0319061279296875 + -2.7959985733032227, + 1.328840970993042, + 1.6106209754943848, + -0.7585874795913696 ] ], "expected_grad_x": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -2108,16 +2279,25 @@ export const testData = { ], "expected_grad_y": [ [ + -1.0, + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, -1.0, -1.0, -1.0 ], [ + -1.0, -1.0, -1.0, -1.0 ], [ + -1.0, -1.0, -1.0, -1.0 @@ -2127,67 +2307,103 @@ export const testData = { { "input_x": [ [ - -0.04043859243392944, - -0.6861222982406616, - 0.5436578989028931 + 0.0, + 1.0, + -1.0, + 0.3547132909297943 + ], + [ + 0.0, + 1.0, + -1.0, + 0.22359032928943634 ], [ - -1.5625712871551514, - 0.8695050477981567, - 0.21445733308792114 + 0.34287506341934204, + -1.4590637683868408, + -1.4936561584472656, + -0.22138521075248718 ], [ - -0.7495803833007812, - -0.49505615234375, - 1.38492751121521 + 0.12097510695457458, + 0.5535293817520142, + -1.9203240871429443, + -0.09706467390060425 ] ], "input_y": [ [ - 0.723960280418396, - 0.14494575560092926, - 2.234894275665283 + 0.0, + 0.0, + -0.8097057938575745, + -1.4298604726791382 + ], + [ + 1.0, + 1.0, + 1.8783389329910278, + 0.18154054880142212 ], [ - 0.02188074216246605, - 0.32069334387779236, - 0.16325443983078003 + -1.0, + -1.0, + -1.2370758056640625, + -2.301875114440918 ], [ - -1.0949900150299072, - 0.5536599159240723, - -0.7866464257240295 + 0.6071491837501526, + 0.034609485417604446, + -0.5123788118362427, + 0.5574127435684204 ] ], "expected_output": [ [ - -0.7643988728523254, - -0.8310680389404297, - -1.6912363767623901 + 0.0, + 1.0, + -0.19029420614242554, + 1.7845737934112549 + ], + [ + -1.0, + 0.0, + -2.8783388137817383, + 0.04204978048801422 ], [ - -1.5844520330429077, - 0.548811674118042, - 0.05120289325714111 + 1.3428750038146973, + -0.4590637683868408, + -0.2565803527832031, + 2.0804898738861084 ], [ - 0.345409631729126, - -1.0487160682678223, - 2.1715738773345947 + -0.486174076795578, + 0.5189198851585388, + -1.4079452753067017, + -0.6544774174690247 ] ], "expected_grad_x": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -2195,16 +2411,25 @@ export const testData = { ], "expected_grad_y": [ [ + -1.0, + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, -1.0, -1.0, -1.0 ], [ + -1.0, -1.0, -1.0, -1.0 ], [ + -1.0, -1.0, -1.0, -1.0 @@ -2214,67 +2439,103 @@ export const testData = { { "input_x": [ [ - -0.6246262192726135, - -0.056941766291856766, - 1.0051201581954956 + 0.0, + 1.0, + -1.0, + 2.8543806076049805 + ], + [ + 0.0, + 1.0, + -1.0, + -0.18887265026569366 ], [ - -0.27256739139556885, - -0.09721744060516357, - 0.34720900654792786 + 0.0696544423699379, + -1.6034338474273682, + -0.42982181906700134, + 0.5761587619781494 ], [ - -0.2762232720851898, - 0.635994553565979, - -0.1394427865743637 + 0.682919979095459, + -0.035719022154808044, + -0.8881044387817383, + -0.5891188979148865 ] ], "input_y": [ [ - 1.2944984436035156, - 0.24116213619709015, - 0.18012243509292603 + 0.0, + 0.0, + -0.7190185785293579, + -0.38583096861839294 + ], + [ + 1.0, + 1.0, + 0.09291388839483261, + -0.7843634486198425 ], [ - -0.8317649364471436, - 0.34142518043518066, - 1.0009468793869019 + -1.0, + -1.0, + -0.7668924331665039, + -0.9494866728782654 ], [ - 0.05718276649713516, - -1.3248257637023926, - -0.24600434303283691 + 0.58314448595047, + 0.033020101487636566, + -1.2597709894180298, + -0.7298099398612976 ] ], "expected_output": [ [ - -1.9191246032714844, - -0.2981038987636566, - 0.8249977231025696 + 0.0, + 1.0, + -0.2809814214706421, + 3.2402114868164062 + ], + [ + -1.0, + 0.0, + -1.0929138660430908, + 0.5954908132553101 ], [ - 0.5591975450515747, - -0.43864262104034424, - -0.6537379026412964 + 1.0696544647216797, + -0.6034338474273682, + 0.33707061409950256, + 1.5256454944610596 ], [ - -0.3334060311317444, - 1.9608203172683716, - 0.1065615564584732 + 0.09977549314498901, + -0.06873912364244461, + 0.3716665506362915, + 0.14069104194641113 ] ], "expected_grad_x": [ [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 ], [ + 1.0, 1.0, 1.0, 1.0 @@ -2282,16 +2543,25 @@ export const testData = { ], "expected_grad_y": [ [ + -1.0, + -1.0, + -1.0, + -1.0 + ], + [ + -1.0, -1.0, -1.0, -1.0 ], [ + -1.0, -1.0, -1.0, -1.0 ], [ + -1.0, -1.0, -1.0, -1.0 @@ -2303,261 +2573,396 @@ export const testData = { { "input_x": [ [ - 0.06055254861712456, - 0.567650556564331, - 0.3359237015247345 + 0.0, + 1.0, + -1.0, + 1.9025356769561768 + ], + [ + 0.0, + 1.0, + -1.0, + 0.06751081347465515 ], [ - 0.4317582845687866, - 2.4537413120269775, - 1.545257568359375 + 0.7401772737503052, + 1.4161995649337769, + 0.6833979487419128, + -0.13825182616710663 ], [ - -0.456123024225235, - 0.5606658458709717, - -0.8425916433334351 + 0.9863895177841187, + -0.3892551064491272, + 0.6138074398040771, + -0.2786312699317932 ] ], "input_y": [ [ - 1.0377453565597534, - 0.01705855503678322, - -0.47082921862602234 + 0.0, + 0.0, + 0.19955870509147644, + -1.2461947202682495 + ], + [ + 1.0, + 1.0, + -0.5218439698219299, + 0.8302035331726074 ], [ - 0.012864481657743454, - -0.8240524530410767, - 1.8157182931900024 + -1.0, + -1.0, + -1.2894343137741089, + 1.0762810707092285 ], [ - 0.3094446361064911, - 0.4485149085521698, - 0.3250584602355957 + -2.2878637313842773, + -0.48340824246406555, + 0.5599985718727112, + -1.0602329969406128 ] ], "expected_output": [ [ - 0.0628381296992302, - 0.009683297947049141, - -0.1581626981496811 + 0.0, + 0.0, + -0.19955870509147644, + -2.3709299564361572 + ], + [ + 0.0, + 1.0, + 0.5218439698219299, + 0.0560477152466774 ], [ - 0.005554346367716789, - -2.0220115184783936, - 2.8057525157928467 + -0.7401772737503052, + -1.4161995649337769, + -0.8811967372894287, + -0.14879782497882843 ], [ - -0.14114482700824738, - 0.2514669895172119, - -0.27389153838157654 + -2.2567248344421387, + 0.18816912174224854, + 0.3437312841415405, + 0.2954140603542328 ] ], "expected_grad_x": [ [ - 1.0377453565597534, - 0.01705855503678322, - -0.47082921862602234 + 0.0, + 0.0, + 0.19955870509147644, + -1.2461947202682495 + ], + [ + 1.0, + 1.0, + -0.5218439698219299, + 0.8302035331726074 ], [ - 0.012864481657743454, - -0.8240524530410767, - 1.8157182931900024 + -1.0, + -1.0, + -1.2894343137741089, + 1.0762810707092285 ], [ - 0.3094446361064911, - 0.4485149085521698, - 0.3250584602355957 + -2.2878637313842773, + -0.48340824246406555, + 0.5599985718727112, + -1.0602329969406128 ] ], "expected_grad_y": [ [ - 0.06055254861712456, - 0.567650556564331, - 0.3359237015247345 + 0.0, + 1.0, + -1.0, + 1.9025356769561768 + ], + [ + 0.0, + 1.0, + -1.0, + 0.06751081347465515 ], [ - 0.4317582845687866, - 2.4537413120269775, - 1.545257568359375 + 0.7401772737503052, + 1.4161995649337769, + 0.6833979487419128, + -0.13825182616710663 ], [ - -0.456123024225235, - 0.5606658458709717, - -0.8425916433334351 + 0.9863895177841187, + -0.3892551064491272, + 0.6138074398040771, + -0.2786312699317932 ] ] }, { "input_x": [ [ - -1.2630205154418945, - 0.7806677222251892, - -0.730068027973175 + 0.0, + 1.0, + -1.0, + -0.7554785013198853 + ], + [ + 0.0, + 1.0, + -1.0, + -0.008815222419798374 ], [ - -0.005363038275390863, - 0.19142311811447144, - -0.7694061398506165 + -1.6514869928359985, + 2.1477253437042236, + -0.6604134440422058, + 0.11352583765983582 ], [ - -1.4855033159255981, - 0.7473039031028748, - -1.07101309299469 + 0.35569247603416443, + 1.2056455612182617, + 1.3690308332443237, + -0.6949581503868103 ] ], "input_y": [ [ - 0.3512069880962372, - 0.29272884130477905, - -0.006127047352492809 + 0.0, + 0.0, + -1.2322070598602295, + -0.598077118396759 + ], + [ + 1.0, + 1.0, + -0.23776796460151672, + -0.1013922467827797 ], [ - 1.3258482217788696, - 0.6050942540168762, - 0.07117609679698944 + -1.0, + -1.0, + -0.595004141330719, + 0.3926331400871277 ], [ - -1.0134872198104858, - 0.9038492441177368, - -0.02116147242486477 + -1.4313503503799438, + -0.039798520505428314, + -0.5003415942192078, + 0.2930373251438141 ] ], "expected_output": [ [ - -0.44358164072036743, - 0.22852395474910736, - 0.004473161417990923 + 0.0, + 0.0, + 1.2322070598602295, + 0.45183441042900085 + ], + [ + 0.0, + 1.0, + 0.23776796460151672, + 0.0008937952225096524 ], [ - -0.007110574748367071, - 0.11582902818918228, - -0.054763324558734894 + 1.6514869928359985, + -2.1477253437042236, + 0.3929487466812134, + 0.044574007391929626 ], [ - 1.5055385828018188, - 0.6754500865936279, - 0.022664213553071022 + -0.509120523929596, + -0.04798290878534317, + -0.6849830746650696, + -0.2036486715078354 ] ], "expected_grad_x": [ [ - 0.3512069880962372, - 0.29272884130477905, - -0.006127047352492809 + 0.0, + 0.0, + -1.2322070598602295, + -0.598077118396759 + ], + [ + 1.0, + 1.0, + -0.23776796460151672, + -0.1013922467827797 ], [ - 1.3258482217788696, - 0.6050942540168762, - 0.07117609679698944 + -1.0, + -1.0, + -0.595004141330719, + 0.3926331400871277 ], [ - -1.0134872198104858, - 0.9038492441177368, - -0.02116147242486477 + -1.4313503503799438, + -0.039798520505428314, + -0.5003415942192078, + 0.2930373251438141 ] ], "expected_grad_y": [ [ - -1.2630205154418945, - 0.7806677222251892, - -0.730068027973175 + 0.0, + 1.0, + -1.0, + -0.7554785013198853 ], [ - -0.005363038275390863, - 0.19142311811447144, - -0.7694061398506165 + 0.0, + 1.0, + -1.0, + -0.008815222419798374 ], [ - -1.4855033159255981, - 0.7473039031028748, - -1.07101309299469 + -1.6514869928359985, + 2.1477253437042236, + -0.6604134440422058, + 0.11352583765983582 + ], + [ + 0.35569247603416443, + 1.2056455612182617, + 1.3690308332443237, + -0.6949581503868103 ] ] }, { "input_x": [ [ - -1.4251255989074707, - -0.3948180079460144, - -0.016342604532837868 + 0.0, + 1.0, + -1.0, + -0.13413065671920776 + ], + [ + 0.0, + 1.0, + -1.0, + -1.5807840824127197 ], [ - -1.9588884115219116, - -1.6948655843734741, - -1.0810617208480835 + -0.15693345665931702, + 1.138344645500183, + -0.2505214214324951, + 1.6704555749893188 ], [ - 1.9611457586288452, - -0.12107571214437485, - -0.06618902087211609 + 1.8887592554092407, + -0.7538138628005981, + -1.7142589092254639, + -2.2069785594940186 ] ], "input_y": [ [ - -1.128678321838379, - -0.7868197560310364, - 0.2418329268693924 + 0.0, + 0.0, + 0.49674081802368164, + -2.369169235229492 + ], + [ + 1.0, + 1.0, + -0.8810284733772278, + 0.34835284948349 ], [ - -0.6500567197799683, - -0.23437145352363586, - -2.115622043609619 + -1.0, + -1.0, + -0.9705761075019836, + 1.4723693132400513 ], [ - -0.026218075305223465, - 1.8427811861038208, - -0.3302917778491974 + -1.3775256872177124, + -1.204437255859375, + -0.48241984844207764, + -0.8164191246032715 ] ], "expected_output": [ [ - 1.6085083484649658, - 0.31065061688423157, - -0.0039521800354123116 + 0.0, + 0.0, + -0.49674081802368164, + 0.31777822971343994 ], [ - 1.2733886241912842, - 0.3972281217575073, - 2.2871179580688477 + 0.0, + 1.0, + 0.8810284733772278, + -0.5506706237792969 ], [ - -0.05141746625304222, - -0.22311604022979736, - 0.021861689165234566 + 0.15693345665931702, + -1.138344645500183, + 0.24315010011196136, + 2.4595274925231934 + ], + [ + -2.6018145084381104, + 0.9079214930534363, + 0.8269925117492676, + 1.8018195629119873 ] ], "expected_grad_x": [ [ - -1.128678321838379, - -0.7868197560310364, - 0.2418329268693924 + 0.0, + 0.0, + 0.49674081802368164, + -2.369169235229492 ], [ - -0.6500567197799683, - -0.23437145352363586, - -2.115622043609619 + 1.0, + 1.0, + -0.8810284733772278, + 0.34835284948349 ], [ - -0.026218075305223465, - 1.8427811861038208, - -0.3302917778491974 + -1.0, + -1.0, + -0.9705761075019836, + 1.4723693132400513 + ], + [ + -1.3775256872177124, + -1.204437255859375, + -0.48241984844207764, + -0.8164191246032715 ] ], "expected_grad_y": [ [ - -1.4251255989074707, - -0.3948180079460144, - -0.016342604532837868 + 0.0, + 1.0, + -1.0, + -0.13413065671920776 + ], + [ + 0.0, + 1.0, + -1.0, + -1.5807840824127197 ], [ - -1.9588884115219116, - -1.6948655843734741, - -1.0810617208480835 + -0.15693345665931702, + 1.138344645500183, + -0.2505214214324951, + 1.6704555749893188 ], [ - 1.9611457586288452, - -0.12107571214437485, - -0.06618902087211609 + 1.8887592554092407, + -0.7538138628005981, + -1.7142589092254639, + -2.2069785594940186 ] ] } @@ -2566,261 +2971,396 @@ export const testData = { { "input_x": [ [ - 0.848053514957428, - -0.4575539231300354, - -1.2403643131256104 + 0.0, + 1.0, + -1.0, + -0.5379461050033569 + ], + [ + 0.0, + 1.0, + -1.0, + -0.3353029191493988 ], [ - 1.325866937637329, - -0.9645381569862366, - -1.6019319295883179 + 0.9199973940849304, + -0.3787555396556854, + -1.5597758293151855, + -0.8009540438652039 ], [ - -0.2991969585418701, - 1.3587521314620972, - 1.6083942651748657 + 0.35879161953926086, + 1.286241054534912, + 0.8211396932601929, + 0.9001851081848145 ] ], "input_y": [ [ - 1.341455340385437, - -0.6912397742271423, - 0.6742424964904785 + 0.0, + 0.0, + 1.875388741493225, + 1.1042989492416382 ], [ - -0.5411797165870667, - -0.27575162053108215, - 0.22375407814979553 + 1.0, + 1.0, + 0.23035314679145813, + -0.36578282713890076 ], [ - -0.1522003561258316, - -1.3301465511322021, - 0.5499060750007629 + -1.0, + -1.0, + 1.5921050310134888, + -0.41619211435317993 + ], + [ + -0.7509436011314392, + -1.4861301183700562, + -0.03333820775151253, + 1.199822187423706 ] ], "expected_output": [ [ - 0.632189154624939, - 0.6619322896003723, - -1.8396412134170532 + NaN, + Infinity, + -0.5332227945327759, + -0.48713812232017517 ], [ - -2.4499568939208984, - 3.4978513717651367, - -7.159341812133789 + 0.0, + 1.0, + -4.341160774230957, + 0.9166721105575562 ], [ - 1.9658098220825195, - -1.02150559425354, - 2.9248526096343994 + -0.9199973940849304, + 0.3787555396556854, + -0.9796940684318542, + 1.9244815111160278 + ], + [ + -0.47778770327568054, + -0.8654969334602356, + -24.63058853149414, + 0.7502654194831848 ] ], "expected_grad_x": [ [ - 0.7454590201377869, - -1.4466760158538818, - 1.4831459522247314 + Infinity, + Infinity, + 0.5332227945327759, + 0.9055519104003906 ], [ - -1.8478150367736816, - -3.6264519691467285, - 4.4691925048828125 + 1.0, + 1.0, + 4.341160774230957, + -2.7338626384735107 + ], + [ + -1.0, + -1.0, + 0.628099262714386, + -2.4027364253997803 ], [ - -6.570286750793457, - -0.7517968416213989, - 1.8184924125671387 + -1.331657886505127, + -0.6728885769844055, + -29.99561309814453, + 0.833456814289093 ] ], "expected_grad_y": [ [ - -0.4712711274623871, - 0.9576015472412109, - 2.7284562587738037 + NaN, + -Infinity, + 0.28432655334472656, + 0.44112884998321533 ], [ - -4.527067184448242, - 12.684789657592773, - 31.996475219726562 + -0.0, + -1.0, + 18.84567642211914, + 2.5060555934906006 ], [ - 12.915934562683105, - -0.7679647207260132, - -5.318821907043457 + -0.9199973940849304, + 0.3787555396556854, + 0.6153451204299927, + 4.624022006988525 + ], + [ + -0.6362497806549072, + -0.5823830366134644, + -738.8096313476562, + -0.6253138184547424 ] ] }, { "input_x": [ [ - 0.6266193389892578, - 0.5769692659378052, - 0.6269291639328003 + 0.0, + 1.0, + -1.0, + 0.32332202792167664 + ], + [ + 0.0, + 1.0, + -1.0, + -0.3372461199760437 ], [ - 2.1126511096954346, - 0.1117599681019783, - 0.5981283187866211 + -0.08114803582429886, + 1.2586976289749146, + 0.8691263794898987, + -0.9609367251396179 ], [ - -0.4339904189109802, - -0.5859114527702332, - -1.1628034114837646 + 0.3896495997905731, + 0.378065288066864, + -0.13722474873065948, + 1.1604512929916382 ] ], "input_y": [ [ - 0.9215105772018433, - 0.46360349655151367, - -0.7266963124275208 + 0.0, + 0.0, + -0.22963792085647583, + -0.40709349513053894 ], [ - 0.2733789086341858, - 0.10054377466440201, - 0.23247668147087097 + 1.0, + 1.0, + 0.8916962146759033, + 0.7001703381538391 ], [ - 0.7063558101654053, - 0.3692564070224762, - -0.8367782831192017 + -1.0, + -1.0, + 0.9187757968902588, + 0.6662830114364624 + ], + [ + 0.22452101111412048, + -0.9745140671730042, + 0.9816727638244629, + 0.5836943984031677 ] ], "expected_output": [ [ - 0.6799914836883545, - 1.2445317506790161, - -0.8627113699913025 + NaN, + Infinity, + 4.354681491851807, + -0.7942205667495728 ], [ - 7.7279229164123535, - 1.1115553379058838, - 2.572852849960327 + 0.0, + 1.0, + -1.1214581727981567, + -0.48166295886039734 + ], + [ + 0.08114803582429886, + -1.2586976289749146, + 0.9459613561630249, + -1.4422351121902466 ], [ - -0.6144076585769653, - -1.586733341217041, - 1.3896194696426392 + 1.7354705333709717, + -0.38795262575149536, + -0.13978664577007294, + 1.9881144762039185 ] ], "expected_grad_x": [ [ - 1.0851746797561646, - 2.157015562057495, - -1.3760906457901 + Infinity, + Infinity, + -4.354681491851807, + -2.4564380645751953 + ], + [ + 1.0, + 1.0, + 1.1214581727981567, + 1.4282238483428955 ], [ - 3.657926559448242, - 9.945916175842285, - 4.301506519317627 + -1.0, + -1.0, + 1.0884047746658325, + 1.5008636713027954 ], [ - 1.4157171249389648, - 2.7081453800201416, - -1.1950596570968628 + 4.453926086425781, + -1.026152491569519, + 1.0186693668365479, + 1.713225245475769 ] ], "expected_grad_y": [ [ - -0.7379095554351807, - -2.684474468231201, - -1.187169075012207 + NaN, + -Infinity, + 18.9632511138916, + -1.950953722000122 + ], + [ + -0.0, + -1.0, + 1.257668375968933, + 0.6879225373268127 ], [ - -28.26817512512207, - -11.055437088012695, - -11.067143440246582 + 0.08114803582429886, + -1.2586976289749146, + -1.0295889377593994, + 2.1645984649658203 ], [ - 0.8698274493217468, - 4.297104358673096, - 1.6606782674789429 + -7.7296576499938965, + -0.39809852838516235, + 0.14239637553691864, + -3.406087875366211 ] ] }, { "input_x": [ [ - -1.220356822013855, - -0.313897043466568, - 0.5908606648445129 + 0.0, + 1.0, + -1.0, + -0.7911050319671631 + ], + [ + 0.0, + 1.0, + -1.0, + -0.17465536296367645 ], [ - -1.5677003860473633, - -0.6271555423736572, - 1.1621606349945068 + 0.34005025029182434, + 1.4557304382324219, + -0.3461014926433563, + -0.2633814215660095 ], [ - -1.959486484527588, - 1.2394423484802246, - -0.7589735388755798 + 1.5014268159866333, + -0.033501043915748596, + 1.1346064805984497, + 0.14365693926811218 ] ], "input_y": [ [ - -0.13591812551021576, - 0.24926981329917908, - -1.121405839920044 + 0.0, + 0.0, + 1.3061575889587402, + -0.9275763630867004 ], [ - -0.606251060962677, - 0.2932665944099426, - 0.7437686324119568 + 1.0, + 1.0, + 1.2907683849334717, + 1.5468223094940186 ], [ - -0.19546888768672943, - 1.2695143222808838, - 0.21413196623325348 + -1.0, + -1.0, + -0.6493158936500549, + 0.45214036107063293 + ], + [ + 1.2459663152694702, + -0.8647340536117554, + -0.8475469946861267, + -0.02352304570376873 ] ], "expected_output": [ [ - 8.978617668151855, - -1.2592661380767822, - -0.5268927812576294 + NaN, + Infinity, + -0.7656043767929077, + 0.8528732061386108 ], [ - 2.585892915725708, - -2.138516902923584, - 1.5625298023223877 + 0.0, + 1.0, + -0.7747323513031006, + -0.1129123643040657 ], [ - 10.024543762207031, - 0.9763122200965881, - -3.544419527053833 + -0.34005025029182434, + -1.4557304382324219, + 0.5330248475074768, + -0.582521378993988 + ], + [ + 1.2050299644470215, + 0.03874144330620766, + -1.338694453239441, + -6.107072353363037 ] ], "expected_grad_x": [ [ - -7.357370376586914, - 4.011717319488525, - -0.8917378187179565 + Infinity, + Infinity, + 0.7656043767929077, + -1.0780783891677856 + ], + [ + 1.0, + 1.0, + 0.7747323513031006, + 0.6464866399765015 ], [ - -1.6494816541671753, - 3.4098668098449707, - 1.3445041179656982 + -1.0, + -1.0, + -1.5400824546813965, + 2.211702585220337 ], [ - -5.115903854370117, - 0.7877027988433838, - 4.670017242431641 + 0.8025898933410645, + -1.156424880027771, + -1.1798756122589111, + -42.51150131225586 ] ], "expected_grad_y": [ [ - 66.05901336669922, - 5.051819801330566, - -0.46985021233558655 + NaN, + -Infinity, + 0.5861501097679138, + 0.9194641709327698 + ], + [ + -0.0, + -1.0, + 0.6002101898193359, + 0.0729963406920433 ], [ - 4.265382766723633, - 7.292057514190674, - -2.100827693939209 + -0.34005025029182434, + -1.4557304382324219, + 0.8209022283554077, + 1.288364052772522 ], [ - 51.28459930419922, - -0.7690438628196716, - 16.552501678466797 + -0.9671449065208435, + 0.04480157047510147, + -1.5794929265975952, + -259.6208190917969 ] ] } @@ -2829,261 +3369,396 @@ export const testData = { { "input_x": [ [ - 1.5344094038009644, - -3.066803455352783, - -2.4677371978759766 + 0.0, + 1.0, + -1.0, + -0.35899198055267334 ], [ - 0.16308026015758514, - -0.0031113873701542616, - 0.3103507161140442 + 0.0, + 1.0, + -1.0, + 0.013965161517262459 ], [ - -0.11947628855705261, - 0.06774814426898956, - -0.3587782680988312 + -1.3923954963684082, + 0.540465772151947, + 0.4350730776786804, + -2.2717032432556152 + ], + [ + 0.06991618871688843, + 0.5178828239440918, + -0.3457261919975281, + 1.3411089181900024 ] ], "input_y": [ [ - -1.0992363691329956, - 0.9729869961738586, - 1.6560982465744019 + 0.0, + 0.0, + -0.5522539615631104, + -0.09342008084058762 ], [ - -1.2484521865844727, - -2.239192247390747, - -0.732846200466156 + 1.0, + 1.0, + -0.5081791877746582, + 1.1477830410003662 ], [ - -2.3703532218933105, - 0.656094491481781, - 0.45320239663124084 + -1.0, + -1.0, + 0.9821351766586304, + 0.22690092027187347 + ], + [ + 1.563033103942871, + 0.5983186960220337, + -0.5407329201698303, + 0.7841619849205017 ] ], "expected_output": [ [ - 0.6246066689491272, + 1.0, + 1.0, NaN, NaN ], [ - 9.622306823730469, + 0.0, + 1.0, NaN, - 2.3571856021881104 + 0.007428741082549095 ], [ - NaN, - 0.17098508775234222, + -0.7181867361068726, + 1.8502559661865234, + 0.44159001111984253, NaN + ], + [ + 0.01563280075788498, + 0.6745581030845642, + NaN, + 1.2587876319885254 ] ], "expected_grad_x": [ [ - -0.447462260723114, + 0.0, + 0.0, NaN, NaN ], [ - -73.66305541992188, + 1.0, + 1.0, NaN, - -5.566137313842773 + 0.6105610132217407 ], [ - NaN, - 1.6558737754821777, + -0.515792191028595, + -3.4234468936920166, + 0.9968464374542236, NaN + ], + [ + 0.3494839370250702, + 0.7793282866477966, + NaN, + 0.7360277771949768 ] ], "expected_grad_y": [ [ - 0.26742255687713623, + 0.0, + 0.0, NaN, NaN ], [ - -17.450176239013672, + 0.0, + 0.0, NaN, - -2.758030414581299 + -0.0317295640707016 ], [ NaN, - -0.4602847099304199, + -1.1385067701339722, + -0.3675094544887543, NaN + ], + [ + -0.041590411216020584, + -0.4438634514808655, + NaN, + 0.3694501519203186 ] ] }, { "input_x": [ [ - -0.9435422420501709, - 0.9280446171760559, - 0.7899183034896851 + 0.0, + 1.0, + -1.0, + 0.7011352777481079 ], [ - 1.5556696653366089, - -1.350498914718628, - 1.1451255083084106 + 0.0, + 1.0, + -1.0, + 0.46809425950050354 ], [ - 0.6095852255821228, - -0.2682342529296875, - -1.1788489818572998 + 0.1417587399482727, + 1.1084681749343872, + 0.5544233322143555, + 1.5817502737045288 + ], + [ + -0.5585249066352844, + 0.6636945605278015, + -1.7024588584899902, + 1.669644832611084 ] ], "input_y": [ [ - 0.8645744919776917, - -0.6576043367385864, - -0.0943203940987587 + 0.0, + 0.0, + -1.6634936332702637, + -0.7650561332702637 + ], + [ + 1.0, + 1.0, + -1.1787039041519165, + -2.1400885581970215 ], [ - 1.4321774244308472, - 1.0809533596038818, - -0.5367263555526733 + -1.0, + -1.0, + -0.07032525539398193, + 0.27448296546936035 ], [ - -0.8979145288467407, - -0.3949545621871948, - -1.3240617513656616 + 0.5569454431533813, + -0.23220781981945038, + -0.05974622070789337, + -1.666461706161499 ] ], "expected_output": [ [ + 1.0, + 1.0, NaN, - 1.0503326654434204, - 1.0224924087524414 + 1.3121100664138794 ], [ - 1.8830409049987793, + 0.0, + 1.0, NaN, - 0.9298480749130249 + 5.075933456420898 + ], + [ + 7.054238796234131, + 0.9021458625793457, + 1.0423519611358643, + 1.1341224908828735 ], [ - 1.559626817703247, NaN, - NaN + 1.0998674631118774, + NaN, + 0.4256037771701813 ] ], "expected_grad_x": [ [ + 0.0, + 0.0, NaN, - -0.7442565560340881, - -0.12209095805883408 + -1.4317320585250854 ], [ - 1.7335611581802368, + 1.0, + 1.0, NaN, - -0.4358246922492981 + -23.206750869750977 + ], + [ + -49.76228332519531, + -0.8138672113418579, + -0.13221606612205505, + 0.19680559635162354 ], [ - -2.297318935394287, NaN, - NaN + -0.38481229543685913, + NaN, + -0.4247923791408539 ] ], "expected_grad_y": [ [ + 0.0, + 0.0, NaN, - -0.07843408733606339, - -0.2411300390958786 + -0.4658704996109009 ], [ - 0.8321272730827332, + 0.0, + 0.0, NaN, - 0.12600766122341156 + -3.8530678749084473 + ], + [ + -13.781363487243652, + 0.09290211647748947, + -0.6148070693016052, + 0.5200314521789551 ], [ - -0.7719786763191223, NaN, - NaN + -0.4508722424507141, + NaN, + 0.21816913783550262 ] ] }, { "input_x": [ [ - -0.8422006368637085, - -0.21955861151218414, - 0.758247971534729 + 0.0, + 1.0, + -1.0, + -1.5196866989135742 ], [ - -0.6107911467552185, - 1.689821481704712, - -0.6808373332023621 + 0.0, + 1.0, + -1.0, + 0.9274609088897705 ], [ - 0.5883275866508484, - -2.3586840629577637, - 0.5554983615875244 + 0.7894347310066223, + 0.7824702858924866, + -0.06465863436460495, + -0.0002302070497535169 + ], + [ + 0.569308340549469, + 0.7476243376731873, + 2.1336774826049805, + 0.5014525055885315 ] ], "input_y": [ [ - -0.9920331239700317, - -0.13226133584976196, - 0.549020528793335 + 0.0, + 0.0, + 1.4614392518997192, + 1.0566132068634033 ], [ - -0.15818315744400024, - -0.42454805970191956, - 1.707962989807129 + 1.0, + 1.0, + -0.2809409499168396, + -0.3604622483253479 ], [ - 0.5729089975357056, - 0.011930502019822598, - -0.9791588187217712 + -1.0, + -1.0, + -1.7659958600997925, + -2.5379507541656494 + ], + [ + -0.03343662992119789, + -1.7016695737838745, + 0.5863364338874817, + -1.7526601552963257 ] ], "expected_output": [ [ + 1.0, + 1.0, NaN, + NaN + ], + [ + 0.0, + 1.0, NaN, - 0.8590410351753235 + 1.02751624584198 ], [ + 1.2667291164398193, + 1.2780038118362427, NaN, - 0.80033278465271, NaN ], [ - 0.7379259467124939, - NaN, - 1.7782634496688843 + 1.0190144777297974, + 1.640397310256958, + 1.5594813823699951, + 3.3527045249938965 ] ], "expected_grad_x": [ [ + 0.0, + 0.0, NaN, + NaN + ], + [ + 1.0, + 1.0, NaN, - 0.6220011711120605 + -0.39934927225112915 ], [ + -1.6046028137207031, + -1.6332937479019165, NaN, - -0.20107434689998627, NaN ], [ - 0.718586802482605, - NaN, - -3.1344869136810303 + -0.05984878167510033, + -3.733712673187256, + 0.42854681611061096, + -11.71826171875 ] ], "expected_grad_y": [ [ + 0.0, + 0.0, NaN, + NaN + ], + [ + 0.0, + 0.0, NaN, - -0.23773515224456787 + -0.07737673819065094 ], [ + -0.29950305819511414, + -0.3134934902191162, NaN, - 0.419872909784317, NaN ], [ - -0.39144858717918396, - NaN, - -1.0454225540161133 + -0.5740445852279663, + -0.4771172106266022, + 1.1818482875823975, + -2.314192295074463 ] ] } @@ -3092,85 +3767,130 @@ export const testData = { { "input_x": [ [ - 2.2314751148223877, - -0.14775699377059937, - -0.7025889158248901 + 0.0, + 1.0, + -1.0, + 0.2491273283958435 ], [ - -1.3201872110366821, - -1.8284006118774414, - 0.19090472161769867 + 0.0, + 1.0, + -1.0, + 0.0604986697435379 ], [ - 0.17843060195446014, - 1.00639808177948, - 0.9555224180221558 + -0.18495284020900726, + -1.0380902290344238, + -0.10130416601896286, + -0.9271824359893799 + ], + [ + 0.734416127204895, + 0.030971217900514603, + -0.5865293741226196, + -0.3154546320438385 ] ], "input_y": [ [ - 0.39204949140548706, - 1.397952914237976, - 1.2648344039916992 + 0.0, + 0.0, + 1.2309634685516357, + 1.2286686897277832 ], [ - -1.6484825611114502, - -0.17498807609081268, - 0.44165265560150146 + 1.0, + 1.0, + -1.2784851789474487, + -1.269239068031311 ], [ - 0.6014829277992249, - -0.5517386794090271, - 0.5157949924468994 + -1.0, + -1.0, + 1.8989076614379883, + -0.04056643322110176 + ], + [ + 0.6467097401618958, + -2.081273078918457, + -0.9303572773933411, + -1.3949681520462036 ] ], "expected_output": [ [ - 2.2314751148223877, - 1.397952914237976, - 1.2648344039916992 + 0.0, + 1.0, + 1.2309634685516357, + 1.2286686897277832 + ], + [ + 1.0, + 1.0, + -1.0, + 0.0604986697435379 ], [ - -1.3201872110366821, - -0.17498807609081268, - 0.44165265560150146 + -0.18495284020900726, + -1.0, + 1.8989076614379883, + -0.04056643322110176 ], [ - 0.6014829277992249, - 1.00639808177948, - 0.9555224180221558 + 0.734416127204895, + 0.030971217900514603, + -0.5865293741226196, + -0.3154546320438385 ] ], "expected_grad_x": [ [ + 0.5, 1.0, 0.0, 0.0 ], + [ + 0.0, + 0.5, + 1.0, + 1.0 + ], [ 1.0, 0.0, + 0.0, 0.0 ], [ - 0.0, + 1.0, + 1.0, 1.0, 1.0 ] ], "expected_grad_y": [ [ + 0.5, 0.0, 1.0, 1.0 ], [ + 1.0, + 0.5, 0.0, + 0.0 + ], + [ + 0.0, + 1.0, 1.0, 1.0 ], [ - 1.0, + 0.0, + 0.0, 0.0, 0.0 ] @@ -3179,173 +3899,263 @@ export const testData = { { "input_x": [ [ - 1.7731256484985352, - -1.6310747861862183, - 1.7790842056274414 + 0.0, + 1.0, + -1.0, + -0.10754015296697617 + ], + [ + 0.0, + 1.0, + -1.0, + 0.3934462368488312 ], [ - 0.03431599214673042, - 0.4497534930706024, - -0.4963332414627075 + 0.9626035690307617, + -1.1049346923828125, + -0.7909473180770874, + -0.21609316766262054 ], [ - 1.0892176628112793, - -2.281388759613037, - 0.13769249618053436 + 0.8574033975601196, + 1.145952820777893, + -0.11311652511358261, + 1.409318447113037 ] ], "input_y": [ [ - -1.073378562927246, - -1.0421594381332397, - 1.1992487907409668 + 0.0, + 0.0, + 1.6020095348358154, + -1.0371782779693604 + ], + [ + 1.0, + 1.0, + 0.11150163412094116, + 1.7073947191238403 ], [ - 1.8445014953613281, - 0.5515044331550598, - -1.4479703903198242 + -1.0, + -1.0, + -0.06464217603206635, + 3.445625066757202 ], [ - 1.2580268383026123, - -0.16691471636295319, - -1.46559476852417 + 0.36726734042167664, + -0.39192530512809753, + 0.1605725735425949, + 2.2373695373535156 ] ], "expected_output": [ [ - 1.7731256484985352, - -1.0421594381332397, - 1.7790842056274414 + 0.0, + 1.0, + 1.6020095348358154, + -0.10754015296697617 ], [ - 1.8445014953613281, - 0.5515044331550598, - -0.4963332414627075 + 1.0, + 1.0, + 0.11150163412094116, + 1.7073947191238403 + ], + [ + 0.9626035690307617, + -1.0, + -0.06464217603206635, + 3.445625066757202 ], [ - 1.2580268383026123, - -0.16691471636295319, - 0.13769249618053436 + 0.8574033975601196, + 1.145952820777893, + 0.1605725735425949, + 2.2373695373535156 ] ], "expected_grad_x": [ [ + 0.5, 1.0, 0.0, 1.0 ], [ 0.0, + 0.5, 0.0, - 1.0 + 0.0 ], [ + 1.0, 0.0, 0.0, - 1.0 + 0.0 + ], + [ + 1.0, + 1.0, + 0.0, + 0.0 ] ], "expected_grad_y": [ [ + 0.5, 0.0, 1.0, 0.0 ], [ 1.0, + 0.5, 1.0, - 0.0 + 1.0 ], [ + 0.0, 1.0, 1.0, - 0.0 + 1.0 + ], + [ + 0.0, + 0.0, + 1.0, + 1.0 ] ] }, { "input_x": [ [ - -0.16166037321090698, - 1.3858773708343506, - 0.5715627670288086 + 0.0, + 1.0, + -1.0, + 0.32681646943092346 ], [ - -0.20138078927993774, - -0.09701951593160629, - 2.2975573539733887 + 0.0, + 1.0, + -1.0, + -0.2612513303756714 ], [ - -0.02061469666659832, - -0.6522951722145081, - -0.04624612256884575 + -1.3136197328567505, + -0.6061143279075623, + 0.6449755430221558, + -0.24771355092525482 + ], + [ + -0.9767715930938721, + -0.443967342376709, + 0.7373694777488708, + -0.13394701480865479 ] ], "input_y": [ [ - 1.0050909519195557, - -0.39795130491256714, - 2.0522775650024414 + 0.0, + 0.0, + 0.25832492113113403, + -2.4340736865997314 ], [ - 1.2850029468536377, - 0.25980693101882935, - 0.1596033275127411 + 1.0, + 1.0, + -2.0726318359375, + -2.1240861415863037 ], [ - 0.8647605776786804, - 0.630111575126648, - 1.3362239599227905 + -1.0, + -1.0, + 0.4093967378139496, + -0.5840954780578613 + ], + [ + 1.0092873573303223, + 1.0439283847808838, + 0.29792049527168274, + 0.8381712436676025 ] ], "expected_output": [ [ - 1.0050909519195557, - 1.3858773708343506, - 2.0522775650024414 + 0.0, + 1.0, + 0.25832492113113403, + 0.32681646943092346 + ], + [ + 1.0, + 1.0, + -1.0, + -0.2612513303756714 ], [ - 1.2850029468536377, - 0.25980693101882935, - 2.2975573539733887 + -1.0, + -0.6061143279075623, + 0.6449755430221558, + -0.24771355092525482 ], [ - 0.8647605776786804, - 0.630111575126648, - 1.3362239599227905 + 1.0092873573303223, + 1.0439283847808838, + 0.7373694777488708, + 0.8381712436676025 ] ], "expected_grad_x": [ [ - 0.0, + 0.5, 1.0, - 0.0 + 0.0, + 1.0 ], [ 0.0, + 0.5, + 1.0, + 1.0 + ], + [ 0.0, + 1.0, + 1.0, 1.0 ], [ 0.0, 0.0, + 1.0, 0.0 ] ], "expected_grad_y": [ [ - 1.0, + 0.5, 0.0, - 1.0 + 1.0, + 0.0 ], [ 1.0, + 0.5, + 0.0, + 0.0 + ], + [ 1.0, + 0.0, + 0.0, 0.0 ], [ 1.0, 1.0, + 0.0, 1.0 ] ] @@ -3355,86 +4165,131 @@ export const testData = { { "input_x": [ [ - -0.9831093549728394, - -0.12308304011821747, - -0.8408450484275818 + 0.0, + 1.0, + -1.0, + 1.4483332633972168 ], [ - 0.48604804277420044, - 1.138323426246643, - -0.2449806183576584 + 0.0, + 1.0, + -1.0, + -0.8552408218383789 ], [ - 1.8371145725250244, - 2.1368844509124756, - 2.196890354156494 + -0.25843867659568787, + -0.7501540780067444, + 1.2354754209518433, + 1.0141247510910034 + ], + [ + -0.6535475254058838, + 1.4623208045959473, + 0.1203368678689003, + 0.7514159083366394 ] ], "input_y": [ [ - 0.9145165085792542, - -0.3624510169029236, - 1.4744350910186768 + 0.0, + 0.0, + -0.8768263459205627, + -1.5509816408157349 ], [ - -0.8670269846916199, - -0.843208909034729, - 0.06224742531776428 + 1.0, + 1.0, + -0.20693671703338623, + 0.44715985655784607 ], [ - 0.4080433249473572, - -1.2516316175460815, - -1.2717373371124268 + -1.0, + -1.0, + 0.21129246056079865, + 1.4860185384750366 + ], + [ + 2.121837854385376, + 0.4178215563297272, + 0.44609254598617554, + -0.02666892670094967 ] ], "expected_output": [ [ - -0.9831093549728394, - -0.3624510169029236, - -0.8408450484275818 + 0.0, + 0.0, + -1.0, + -1.5509816408157349 ], [ - -0.8670269846916199, - -0.843208909034729, - -0.2449806183576584 + 0.0, + 1.0, + -1.0, + -0.8552408218383789 ], [ - 0.4080433249473572, - -1.2516316175460815, - -1.2717373371124268 + -1.0, + -1.0, + 0.21129246056079865, + 1.0141247510910034 + ], + [ + -0.6535475254058838, + 0.4178215563297272, + 0.1203368678689003, + -0.02666892670094967 ] ], "expected_grad_x": [ [ - 1.0, + 0.5, 0.0, + 1.0, + 0.0 + ], + [ + 1.0, + 0.5, + 1.0, 1.0 ], [ + 0.0, 0.0, 0.0, 1.0 ], [ + 1.0, 0.0, - 0.0, + 1.0, 0.0 ] ], "expected_grad_y": [ [ - 0.0, + 0.5, 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 0.5, + 0.0, 0.0 ], [ + 1.0, 1.0, 1.0, 0.0 ], [ + 0.0, 1.0, - 1.0, + 0.0, 1.0 ] ] @@ -3442,67 +4297,103 @@ export const testData = { { "input_x": [ [ - 0.8055283427238464, - 1.0920584201812744, - 0.8560135960578918 + 0.0, + 1.0, + -1.0, + 1.0925219058990479 + ], + [ + 0.0, + 1.0, + -1.0, + -0.24391917884349823 ], [ - 1.5192112922668457, - 0.44675812125205994, - -0.2566242218017578 + -0.783242404460907, + -0.26778313517570496, + 1.5684525966644287, + -0.283514142036438 ], [ - 1.7753183841705322, - -0.7927579879760742, - -1.6142888069152832 + -1.465786099433899, + -0.06292983889579773, + -2.527074098587036, + 0.47731438279151917 ] ], "input_y": [ [ - 0.31103116273880005, - 1.7946441173553467, - 3.19868803024292 + 0.0, + 0.0, + -0.06058019772171974, + -0.5304896831512451 + ], + [ + 1.0, + 1.0, + 1.6892662048339844, + -0.6297198534011841 ], [ - 0.2567588686943054, - 0.8679211735725403, - -1.1851390600204468 + -1.0, + -1.0, + -1.4458993673324585, + -0.31466683745384216 ], [ - 0.7940642833709717, - 0.19724640250205994, - 0.622898280620575 + -1.242173194885254, + -0.3340345025062561, + -1.5728429555892944, + 2.810397148132324 ] ], "expected_output": [ [ - 0.31103116273880005, - 1.0920584201812744, - 0.8560135960578918 + 0.0, + 0.0, + -1.0, + -0.5304896831512451 + ], + [ + 0.0, + 1.0, + -1.0, + -0.6297198534011841 ], [ - 0.2567588686943054, - 0.44675812125205994, - -1.1851390600204468 + -1.0, + -1.0, + -1.4458993673324585, + -0.31466683745384216 ], [ - 0.7940642833709717, - -0.7927579879760742, - -1.6142888069152832 + -1.465786099433899, + -0.3340345025062561, + -2.527074098587036, + 0.47731438279151917 ] ], "expected_grad_x": [ [ + 0.5, 0.0, 1.0, - 1.0 + 0.0 ], [ - 0.0, 1.0, + 0.5, + 1.0, + 0.0 + ], + [ + 0.0, + 0.0, + 0.0, 0.0 ], [ + 1.0, 0.0, 1.0, 1.0 @@ -3510,16 +4401,25 @@ export const testData = { ], "expected_grad_y": [ [ + 0.5, 1.0, 0.0, - 0.0 + 1.0 ], [ - 1.0, 0.0, + 0.5, + 0.0, + 1.0 + ], + [ + 1.0, + 1.0, + 1.0, 1.0 ], [ + 0.0, 1.0, 0.0, 0.0 @@ -3529,85 +4429,130 @@ export const testData = { { "input_x": [ [ - 1.186416506767273, - 1.3099017143249512, - -2.1073341369628906 + 0.0, + 1.0, + -1.0, + -2.0370566844940186 ], [ - -0.22107578814029694, - 0.9579378366470337, - -1.3392482995986938 + 0.0, + 1.0, + -1.0, + 0.9563636779785156 ], [ - -1.3702017068862915, - -0.32176926732063293, - 0.1034090593457222 + -0.8331825137138367, + -0.47921040654182434, + 0.2998451292514801, + 0.721377432346344 + ], + [ + 0.7283791899681091, + -0.34462252259254456, + 0.4790245592594147, + 0.024238986894488335 ] ], "input_y": [ [ - -0.07071641087532043, - -0.3897135257720947, - 1.7265616655349731 + 0.0, + 0.0, + 0.43399056792259216, + 1.1234275102615356 + ], + [ + 1.0, + 1.0, + 0.2529439628124237, + 0.12658123672008514 ], [ - 1.084613561630249, - 1.1876388788223267, - 0.5510113835334778 + -1.0, + -1.0, + 0.825295627117157, + 2.268347978591919 ], [ - -0.27905166149139404, - 0.6056016683578491, - -2.1992974281311035 + -0.06611745059490204, + -1.0740467309951782, + 1.3753548860549927, + -0.3824302554130554 ] ], "expected_output": [ [ - -0.07071641087532043, - -0.3897135257720947, - -2.1073341369628906 + 0.0, + 0.0, + -1.0, + -2.0370566844940186 + ], + [ + 0.0, + 1.0, + -1.0, + 0.12658123672008514 ], [ - -0.22107578814029694, - 0.9579378366470337, - -1.3392482995986938 + -1.0, + -1.0, + 0.2998451292514801, + 0.721377432346344 ], [ - -1.3702017068862915, - -0.32176926732063293, - -2.1992974281311035 + -0.06611745059490204, + -1.0740467309951782, + 0.4790245592594147, + -0.3824302554130554 ] ], "expected_grad_x": [ [ + 0.5, 0.0, - 0.0, + 1.0, 1.0 ], [ 1.0, + 0.5, 1.0, - 1.0 + 0.0 ], [ + 0.0, + 0.0, 1.0, + 1.0 + ], + [ + 0.0, + 0.0, 1.0, 0.0 ] ], "expected_grad_y": [ [ + 0.5, 1.0, - 1.0, + 0.0, 0.0 ], [ 0.0, + 0.5, 0.0, - 0.0 + 1.0 ], [ + 1.0, + 1.0, 0.0, + 0.0 + ], + [ + 1.0, + 1.0, 0.0, 1.0 ] @@ -3621,38 +4566,38 @@ export const testData = { "op_name": "add", "input_x": [ [ - 0.10101978480815887, - -1.7474379539489746, - 0.49967822432518005 + -0.017705317586660385, + -0.843208909034729, + 0.06224742531776428 ], [ - -1.2637113332748413, - 0.19651830196380615, - -0.4187171757221222 + 0.4080433249473572, + -1.2516316175460815, + -1.2717373371124268 ] ], "input_y": [ [ - 0.48351433873176575, - 0.9704157710075378, - -0.1363738477230072 + 0.8055283427238464, + 1.0920584201812744, + 0.8560135960578918 ], [ - -0.4913654327392578, - 0.5787925720214844, - -0.5241618156433105 + 1.5192112922668457, + 0.44675812125205994, + -0.2566242218017578 ] ], "expected_output": [ [ - 0.5845341086387634, - -0.7770221829414368, - 0.36330437660217285 + 0.7878230214118958, + 0.2488495111465454, + 0.9182610511779785 ], [ - -1.7550767660140991, - 0.7753108739852905, - -0.9428789615631104 + 1.9272546768188477, + -0.8048734664916992, + -1.5283615589141846 ] ], "expected_grad_x": [ @@ -3685,62 +4630,62 @@ export const testData = { "op_name": "mul", "input_x": [ [ - -0.8587943315505981, - 0.32446324825286865, - -0.17433615028858185 + 1.7753183841705322, + -0.7927579879760742, + -1.6142888069152832 ], [ - 0.6593497395515442, - -0.5109422206878662, - -0.944842517375946 + 0.31103116273880005, + 1.7946441173553467, + 3.19868803024292 ] ], "input_y": [ [ - -0.5671818852424622, - 0.4958496391773224, - 1.1620975732803345 + 0.2567588686943054, + 0.8679211735725403, + -1.1851390600204468 ], [ - 0.726780116558075, - 0.6438865661621094, - 0.6418544054031372 + 0.7940642833709717, + 0.19724640250205994, + 0.622898280620575 ] ], "expected_output": [ [ - 0.4870925843715668, - 0.16088499128818512, - -0.20259562134742737 + 0.4558287262916565, + -0.6880514621734619, + 1.9131567478179932 ], [ - 0.4792022705078125, - -0.32898882031440735, - -0.6064513325691223 + 0.2469787299633026, + 0.35398709774017334, + 1.9924572706222534 ] ], "expected_grad_x": [ [ - -0.5671818852424622, - 0.4958496391773224, - 1.1620975732803345 + 0.2567588686943054, + 0.8679211735725403, + -1.1851390600204468 ], [ - 0.726780116558075, - 0.6438865661621094, - 0.6418544054031372 + 0.7940642833709717, + 0.19724640250205994, + 0.622898280620575 ] ], "expected_grad_y": [ [ - -0.8587943315505981, - 0.32446324825286865, - -0.17433615028858185 + 1.7753183841705322, + -0.7927579879760742, + -1.6142888069152832 ], [ - 0.6593497395515442, - -0.5109422206878662, - -0.944842517375946 + 0.31103116273880005, + 1.7946441173553467, + 3.19868803024292 ] ] }, @@ -3750,22 +4695,22 @@ export const testData = { "input_x": 1.5, "input_y": [ [ - 0.7264923453330994, - -0.023122388869524002 + 1.186416506767273, + 1.3099017143249512 ], [ - -0.5372034311294556, - -0.5396077632904053 + -2.1073341369628906, + -0.22107578814029694 ] ], "expected_output": [ [ - 2.226492404937744, - 1.4768775701522827 + 2.6864166259765625, + 2.809901714324951 ], [ - 0.9627965688705444, - 0.9603922367095947 + -0.6073341369628906, + 1.2789242267608643 ] ], "expected_grad_x": 4.0, @@ -3786,25 +4731,25 @@ export const testData = { "input_x": 1.5, "input_y": [ [ - 0.6077166199684143, - 0.27988874912261963 + 0.9579378366470337, + -1.3392482995986938 ], [ - -1.0373796224594116, - 0.589288592338562 + -1.3702017068862915, + -0.32176926732063293 ] ], "expected_output": [ [ - 0.9115749597549438, - 0.41983312368392944 + 1.4369068145751953, + -2.0088725090026855 ], [ - -1.5560693740844727, - 0.883932888507843 + -2.055302619934082, + -0.4826539158821106 ] ], - "expected_grad_x": 0.4395143389701843, + "expected_grad_x": -2.0732815265655518, "expected_grad_y": [ [ 1.5, @@ -3823,88 +4768,88 @@ export const testData = { [ [ [ - -0.10694646835327148 + -1.9291036128997803 ], [ - 0.6531567573547363 + 0.03497670218348503 ], [ - -1.015342116355896 + -0.4833625555038452 ], [ - -0.8090125918388367 + -1.2260730266571045 ] ], [ [ - -0.5131909251213074 + -1.6395642757415771 ], [ - -0.8087556958198547 + 0.2299439013004303 ], [ - 1.1124427318572998 + -0.44963574409484863 ], [ - 0.11936674267053604 + -0.40768420696258545 ] ], [ [ - 0.6386357545852661 + -0.011143443174660206 ], [ - -0.4361383616924286 + 1.8151899576187134 ], [ - -1.0022987127304077 + 0.6066091060638428 ], [ - 0.3780289888381958 + 0.5963938236236572 ] ] ], [ [ [ - 0.04276036471128464 + 0.5361921191215515 ], [ - 0.5858650803565979 + 1.2350000143051147 ], [ - -1.3687634468078613 + -0.21214154362678528 ], [ - 1.1168509721755981 + 1.387345790863037 ] ], [ [ - 0.27692535519599915 + -0.6384463906288147 ], [ - 1.0580254793167114 + 0.737216591835022 ], [ - -0.05147926136851311 + 1.1485421657562256 ], [ - 0.17128385603427887 + 0.725890040397644 ] ], [ [ - -0.21165163815021515 + -0.29366371035575867 ], [ - -0.1787608563899994 + -0.6286743879318237 ], [ - -0.8498311638832092 + -0.04226749762892723 ], [ - 1.166976809501648 + -0.27004849910736084 ] ] ] @@ -3912,17 +4857,17 @@ export const testData = { "input_y": [ [ [ - 1.2661118507385254 + 0.1034090593457222 ] ], [ [ - 0.5520188808441162 + -0.5241618156433105 ] ], [ [ - -0.2482202798128128 + -0.8587943315505981 ] ] ], @@ -3930,88 +4875,88 @@ export const testData = { [ [ [ - 1.159165382385254 + -1.8256945610046387 ], [ - 1.9192686080932617 + 0.13838575780391693 ], [ - 0.2507697343826294 + -0.3799535036087036 ], [ - 0.4570992588996887 + -1.122663974761963 ] ], [ [ - 0.03882795572280884 + -2.1637260913848877 ], [ - -0.2567368149757385 + -0.29421791434288025 ], [ - 1.664461612701416 + -0.9737975597381592 ], [ - 0.671385645866394 + -0.931846022605896 ] ], [ [ - 0.3904154896736145 + -0.8699377775192261 ], [ - -0.6843586564064026 + 0.9563956260681152 ], [ - -1.250519037246704 + -0.25218522548675537 ], [ - 0.129808709025383 + -0.2624005079269409 ] ] ], [ [ [ - 1.3088722229003906 + 0.6396011710166931 ], [ - 1.8519768714904785 + 1.3384090662002563 ], [ - -0.10265159606933594 + -0.10873248428106308 ], [ - 2.382962703704834 + 1.4907548427581787 ] ], [ [ - 0.828944206237793 + -1.1626081466674805 ], [ - 1.6100443601608276 + 0.21305477619171143 ], [ - 0.5005396008491516 + 0.624380350112915 ], [ - 0.7233027219772339 + 0.2017282247543335 ] ], [ [ - -0.45987191796302795 + -1.1524580717086792 ], [ - -0.4269811511039734 + -1.4874687194824219 ], [ - -1.0980514287948608 + -0.9010618329048157 ], [ - 0.9187565445899963 + -1.128842830657959 ] ] ] @@ -4131,88 +5076,88 @@ export const testData = { [ [ [ - 0.20935998857021332 + 2.8818862438201904 ], [ - 1.505028486251831 + -1.1672022342681885 ], [ - -1.1346086263656616 + 1.9413354396820068 ], [ - -0.7111839056015015 + -1.163609266281128 ] ], [ [ - -0.8095768690109253 + -1.5966553688049316 ], [ - 0.41242745518684387 + 0.08320564776659012 ], [ - 2.0646610260009766 + -0.9222075343132019 ], [ - -0.32648909091949463 + -0.3711417317390442 ] ], [ [ - -0.16211076080799103 + 0.1490848809480667 ], [ - 0.49002620577812195 + -0.2603190541267395 ], [ - 0.9112547636032104 + -0.7125067710876465 ], [ - 1.792615532875061 + -0.7577925324440002 ] ] ], [ [ [ - 1.0188977718353271 + -0.6056803464889526 ], [ - -1.8317182064056396 + -0.001647569122724235 ], [ - 0.2806217670440674 + -0.48284876346588135 ], [ - 0.6909231543540955 + -1.0801341533660889 ] ], [ [ - 0.9776358604431152 + 0.9042091369628906 ], [ - 0.7260830402374268 + -0.03959815204143524 ], [ - 1.2465280294418335 + 0.3362662196159363 ], [ - 0.6389282941818237 + -0.9519665837287903 ] ], [ [ - 0.38033702969551086 + -0.08652620017528534 ], [ - -1.962886095046997 + 0.832058310508728 ], [ - -0.7805798053741455 + 0.9070028066635132 ], [ - -0.1343953162431717 + 0.03912770003080368 ] ] ] @@ -4220,17 +5165,17 @@ export const testData = { "input_y": [ [ [ - -1.4443291425704956 + -1.5896711349487305 ] ], [ [ - 0.9527847170829773 + -0.040549930185079575 ] ], [ [ - -2.000053644180298 + 1.9009761810302734 ] ] ], @@ -4238,88 +5183,88 @@ export const testData = { [ [ [ - -0.30238473415374756 + -4.58125114440918 ], [ - -2.1737565994262695 + 1.855467677116394 ], [ - 1.638748288154602 + -3.0860848426818848 ], [ - 1.0271836519241333 + 1.849756121635437 ] ], [ [ - -0.7713524699211121 + 0.0647442638874054 ], [ - 0.39295458793640137 + -0.0033739833161234856 ], [ - 1.9671775102615356 + 0.037395451217889786 ], [ - -0.31107380986213684 + 0.015049771405756474 ] ], [ [ - 0.32423022389411926 + 0.2834067940711975 ], [ - -0.9800786972045898 + -0.49486032128334045 ], [ - -1.8225584030151367 + -1.3544584512710571 ], [ - -3.5853271484375 + -1.4405455589294434 ] ] ], [ [ [ - -1.4716237783432007 + 0.9628325700759888 ], [ - 2.645603895187378 + 0.0026190930511802435 ], [ - -0.40531018376350403 + 0.7675707340240479 ], [ - -0.9979204535484314 + 1.7170580625534058 ] ], [ [ - 0.9314765334129333 + -0.03666561841964722 ], [ - 0.6918008327484131 + 0.001605702331289649 ], [ - 1.1876728534698486 + -0.013635572046041489 ], [ - 0.6087611317634583 + 0.03860217705368996 ] ], [ [ - -0.7606944441795349 + -0.16448424756526947 ], [ - 3.925877571105957 + 1.5817229747772217 ], [ - 1.5612014532089233 + 1.7241907119750977 ], [ - 0.2687978446483612 + 0.07438082247972488 ] ] ] @@ -4328,88 +5273,88 @@ export const testData = { [ [ [ - -1.4443291425704956 + -1.5896711349487305 ], [ - -1.4443291425704956 + -1.5896711349487305 ], [ - -1.4443291425704956 + -1.5896711349487305 ], [ - -1.4443291425704956 + -1.5896711349487305 ] ], [ [ - 0.9527847170829773 + -0.040549930185079575 ], [ - 0.9527847170829773 + -0.040549930185079575 ], [ - 0.9527847170829773 + -0.040549930185079575 ], [ - 0.9527847170829773 + -0.040549930185079575 ] ], [ [ - -2.000053644180298 + 1.9009761810302734 ], [ - -2.000053644180298 + 1.9009761810302734 ], [ - -2.000053644180298 + 1.9009761810302734 ], [ - -2.000053644180298 + 1.9009761810302734 ] ] ], [ [ [ - -1.4443291425704956 + -1.5896711349487305 ], [ - -1.4443291425704956 + -1.5896711349487305 ], [ - -1.4443291425704956 + -1.5896711349487305 ], [ - -1.4443291425704956 + -1.5896711349487305 ] ], [ [ - 0.9527847170829773 + -0.040549930185079575 ], [ - 0.9527847170829773 + -0.040549930185079575 ], [ - 0.9527847170829773 + -0.040549930185079575 ], [ - 0.9527847170829773 + -0.040549930185079575 ] ], [ [ - -2.000053644180298 + 1.9009761810302734 ], [ - -2.000053644180298 + 1.9009761810302734 ], [ - -2.000053644180298 + 1.9009761810302734 ], [ - -2.000053644180298 + 1.9009761810302734 ] ] ] @@ -4417,17 +5362,17 @@ export const testData = { "expected_grad_y": [ [ [ - 0.027320444583892822 + 0.3220992088317871 ] ], [ [ - 4.930197715759277 + -2.5578882694244385 ] ], [ [ - 0.5342614650726318 + 0.11012923717498779 ] ] ] @@ -4436,45 +5381,45 @@ export const testData = { "test_name": "broadcast_add_(1,)_and_(3, 1, 2)", "op_name": "add", "input_x": [ - -0.5958812236785889 + -0.6620396375656128 ], "input_y": [ [ [ - 0.07782832533121109, - 0.5926167964935303 + 0.2589207887649536, + -1.0626986026763916 ] ], [ [ - 1.030975103378296, - -0.663306713104248 + -1.4913355112075806, + 0.16728094220161438 ] ], [ [ - -0.11067406833171844, - -0.2901550829410553 + 0.7527865171432495, + 0.611292839050293 ] ] ], "expected_output": [ [ [ - -0.518052875995636, - -0.0032644271850585938 + -0.4031188488006592, + -1.7247382402420044 ] ], [ [ - 0.43509387969970703, - -1.259187936782837 + -2.1533751487731934, + -0.4947586953639984 ] ], [ [ - -0.7065553069114685, - -0.8860362768173218 + 0.09074687957763672, + -0.050746798515319824 ] ] ], @@ -4506,68 +5451,68 @@ export const testData = { "test_name": "broadcast_mul_(1,)_and_(3, 1, 2)", "op_name": "mul", "input_x": [ - -0.698898434638977 + -1.7093836069107056 ], "input_y": [ [ [ - -0.7456109523773193, - 1.1263020038604736 + -0.6855810284614563, + -0.10798398405313492 ] ], [ [ - -0.7577127814292908, - -0.24528881907463074 + -0.5913975834846497, + 0.7366381287574768 ] ], [ [ - -0.477226585149765, - -1.3771432638168335 + 1.6831679344177246, + -0.3644360899925232 ] ] ], "expected_output": [ [ [ - 0.5211063027381897, - -0.7871707081794739 + 1.1719210147857666, + 0.1845860481262207 ] ], [ [ - 0.5295642614364624, - 0.17143197357654572 + 1.01092529296875, + -1.2591971158981323 ] ], [ [ - 0.3335328996181488, - 0.962483286857605 + -2.8771796226501465, + 0.6229611039161682 ] ] ], "expected_grad_x": [ - -2.4766805171966553 + 0.6704073548316956 ], "expected_grad_y": [ [ [ - -0.698898434638977, - -0.698898434638977 + -1.7093836069107056, + -1.7093836069107056 ] ], [ [ - -0.698898434638977, - -0.698898434638977 + -1.7093836069107056, + -1.7093836069107056 ] ], [ [ - -0.698898434638977, - -0.698898434638977 + -1.7093836069107056, + -1.7093836069107056 ] ] ] @@ -4579,80 +5524,80 @@ export const testData = { [ [ [ - -0.8496796488761902 + 1.6522549390792847 ], [ - -0.6987038254737854 + -0.4681110680103302 ], [ - -0.20516234636306763 + -1.3070950508117676 ], [ - -0.7811664342880249 + -0.2728694975376129 ] ] ], [ [ [ - -0.8665743470191956 + -1.0562596321105957 ], [ - -0.30639445781707764 + 0.24130821228027344 ], [ - -0.5359372496604919 + 0.18275369703769684 ], [ - -0.35750812292099 + 0.6246524453163147 ] ] ], [ [ [ - -1.4471426010131836 + -0.7939775586128235 ], [ - -1.6966946125030518 + -0.674835205078125 ], [ - -2.1704893112182617 + -0.3876877427101135 ], [ - -0.3568725883960724 + 0.44965043663978577 ] ] ], [ [ [ - 0.21925963461399078 + 0.3726101517677307 ], [ - 0.4133651852607727 + -1.9104946851730347 ], [ - 0.0061524491757154465 + 0.26085028052330017 ], [ - -0.5672794580459595 + 1.4177610874176025 ] ] ], [ [ [ - 0.10004822909832001 + 0.6738032102584839 ], [ - -0.2485211342573166 + 1.4665507078170776 ], [ - -0.9125545620918274 + -1.1077474355697632 ], [ - -0.8421810865402222 + -0.7443782091140747 ] ] ] @@ -4660,17 +5605,17 @@ export const testData = { "input_y": [ [ [ - -0.13354362547397614 + -0.048239294439554214 ] ], [ [ - 0.5437685251235962 + -0.8039766550064087 ] ], [ [ - -2.3363192081451416 + -0.3882785737514496 ] ] ], @@ -4678,220 +5623,220 @@ export const testData = { [ [ [ - -0.9832232594490051 + 1.604015588760376 ], [ - -0.8322474360466003 + -0.5163503885269165 ], [ - -0.33870595693588257 + -1.3553344011306763 ], [ - -0.9147100448608398 + -0.32110878825187683 ] ], [ [ - -0.305911123752594 + 0.848278284072876 ], [ - -0.1549353003501892 + -1.2720876932144165 ], [ - 0.33860617876052856 + -2.1110715866088867 ], [ - -0.2373979091644287 + -1.0768461227416992 ] ], [ [ - -3.1859989166259766 + 1.2639763355255127 ], [ - -3.0350229740142822 + -0.8563896417617798 ], [ - -2.5414814949035645 + -1.6953736543655396 ], [ - -3.117485523223877 + -0.6611480712890625 ] ] ], [ [ [ - -1.0001180171966553 + -1.1044989824295044 ], [ - -0.4399380683898926 + 0.19306892156600952 ], [ - -0.6694808602333069 + 0.13451440632343292 ], [ - -0.49105173349380493 + 0.5764131546020508 ] ], [ [ - -0.32280582189559937 + -1.8602362871170044 ], [ - 0.23737406730651855 + -0.5626684427261353 ], [ - 0.007831275463104248 + -0.621222972869873 ], [ - 0.1862604022026062 + -0.179324209690094 ] ], [ [ - -3.2028934955596924 + -1.4445382356643677 ], [ - -2.6427135467529297 + -0.14697036147117615 ], [ - -2.8722565174102783 + -0.20552487671375275 ], [ - -2.6938273906707764 + 0.2363738715648651 ] ] ], [ [ [ - -1.5806862115859985 + -0.8422168493270874 ], [ - -1.8302382230758667 + -0.7230744957923889 ], [ - -2.304033041000366 + -0.43592703342437744 ], [ - -0.4904162287712097 + 0.40141114592552185 ] ], [ [ - -0.9033740758895874 + -1.597954273223877 ], [ - -1.1529260873794556 + -1.4788118600845337 ], [ - -1.6267207860946655 + -1.191664457321167 ], [ - 0.1868959367275238 + -0.3543262183666229 ] ], [ [ - -3.783461809158325 + -1.1822561025619507 ], [ - -4.033013820648193 + -1.063113808631897 ], [ - -4.506808280944824 + -0.7759662866592407 ], [ - -2.6931917667388916 + 0.06137186288833618 ] ] ], [ [ [ - 0.08571600914001465 + 0.3243708610534668 ], [ - 0.27982157468795776 + -1.9587340354919434 ], [ - -0.12739117443561554 + 0.21261098980903625 ], [ - -0.7008230686187744 + 1.3695217370986938 ] ], [ [ - 0.7630281448364258 + -0.431366503238678 ], [ - 0.9571337103843689 + -2.7144713401794434 ], [ - 0.5499209761619568 + -0.5431263446807861 ], [ - -0.02351093292236328 + 0.6137844324111938 ] ], [ [ - -2.1170594692230225 + -0.015668421983718872 ], [ - -1.9229540824890137 + -2.2987732887268066 ], [ - -2.330166816711426 + -0.12742829322814941 ], [ - -2.9035987854003906 + 1.0294824838638306 ] ] ], [ [ [ - -0.03349539637565613 + 0.62556391954422 ], [ - -0.3820647597312927 + 1.418311357498169 ], [ - -1.046098232269287 + -1.1559867858886719 ], [ - -0.9757246971130371 + -0.7926174998283386 ] ], [ [ - 0.6438167691230774 + -0.1301734447479248 ], [ - 0.2952473759651184 + 0.662574052810669 ], [ - -0.3687860369682312 + -1.9117240905761719 ], [ - -0.298412561416626 + -1.5483548641204834 ] ], [ [ - -2.2362709045410156 + 0.2855246365070343 ], [ - -2.5848402976989746 + 1.0782721042633057 ], [ - -3.248873710632324 + -1.4960260391235352 ], [ - -3.178500175476074 + -1.1326568126678467 ] ] ] @@ -5003,80 +5948,80 @@ export const testData = { [ [ [ - -0.7984835505485535 + 0.7183824777603149 ], [ - 0.5182347893714905 + -0.5719326138496399 ], [ - -1.1608222723007202 + -0.46663370728492737 ], [ - -1.0226510763168335 + 0.1017654687166214 ] ] ], [ [ [ - -0.89991295337677 + 0.7780604362487793 ], [ - 0.4791645407676697 + -1.4069199562072754 ], [ - -0.24811258912086487 + 0.4058326482772827 ], [ - -1.3093348741531372 + 1.8279902935028076 ] ] ], [ [ [ - -0.2919580638408661 + -1.4415538311004639 ], [ - 0.45643651485443115 + -0.6341907978057861 ], [ - -0.3147018849849701 + -1.9628868103027344 ], [ - -0.41328999400138855 + -0.6502721905708313 ] ] ], [ [ [ - -0.17061950266361237 + -1.4416067600250244 ], [ - -0.6140995025634766 + -1.2435057163238525 ], [ - 0.53551185131073 + -1.226744532585144 ], [ - -1.6644023656845093 + -0.14965394139289856 ] ] ], [ [ [ - -0.15447334945201874 + -1.2425028085708618 ], [ - -1.6013476848602295 + 1.4803948402404785 ], [ - -0.059470854699611664 + 0.6343469023704529 ], [ - -0.9928666353225708 + -0.7937742471694946 ] ] ] @@ -5084,17 +6029,17 @@ export const testData = { "input_y": [ [ [ - -1.1151187419891357 + -0.24528881907463074 ] ], [ [ - -0.6466555595397949 + -0.477226585149765 ] ], [ [ - -0.9256587624549866 + -1.3771432638168335 ] ] ], @@ -5102,220 +6047,220 @@ export const testData = { [ [ [ - 0.8904039859771729 + -0.1762111932039261 ], [ - -0.5778933167457581 + 0.14028868079185486 ], [ - 1.2944546937942505 + 0.11446002870798111 ], [ - 1.140377402305603 + -0.024961931630969048 ] ], [ [ - 0.5163438320159912 + -0.34283122420310974 ], [ - -0.3351193964481354 + 0.2729414403438568 ], [ - 0.7506521940231323 + 0.22269001603126526 ], [ - 0.6613029837608337 + -0.04856518656015396 ] ], [ [ - 0.7391232848167419 + -0.9893155694007874 ], [ - -0.47970858216285706 + 0.7876331210136414 ], [ - 1.0745253562927246 + 0.6426214575767517 ], [ - 0.9466259479522705 + -0.14014562964439392 ] ] ], [ [ [ - 1.003509759902954 + -0.19084952771663666 ], [ - -0.534325361251831 + 0.3451017439365387 ], [ - 0.2766749858856201 + -0.09954620897769928 ], [ - 1.4600638151168823 + -0.4483855664730072 ] ], [ [ - 0.5819337368011475 + -0.37131112813949585 ], [ - -0.3098544180393219 + 0.671419620513916 ], [ - 0.16044338047504425 + -0.19367413222789764 ], [ - 0.8466886878013611 + -0.8723655939102173 ] ], [ [ - 0.8330122828483582 + -1.0715006589889526 ], [ - -0.44354286789894104 + 1.9375303983688354 ], [ - 0.22966758906841278 + -0.5588896870613098 ], [ - 1.2119972705841064 + -2.517404556274414 ] ] ], [ [ [ - 0.32556790113449097 + 0.3535970449447632 ], [ - -0.508980929851532 + 0.15555991232395172 ], [ - 0.35092997550964355 + 0.4814741909503937 ], [ - 0.46086740493774414 + 0.1595045030117035 ] ], [ [ - 0.18879631161689758 + 0.6879478096961975 ], [ - -0.29515722393989563 + 0.3026527166366577 ], [ - 0.20350372791290283 + 0.9367417693138123 ], [ - 0.2672562599182129 + 0.3103271722793579 ] ], [ [ - 0.2702535390853882 + 1.9852261543273926 ], [ - -0.4225044548511505 + 0.8733716011047363 ], [ - 0.2913065552711487 + 2.703176259994507 ], [ - 0.3825654983520508 + 0.8955179452896118 ] ] ], [ [ [ - 0.19026100635528564 + 0.35361000895500183 ], [ - 0.6847938895225525 + 0.30501803755760193 ], [ - -0.5971593260765076 + 0.3009067177772522 ], [ - 1.8560062646865845 + 0.03670843690633774 ] ], [ [ - 0.11033204942941666 + 0.6879730820655823 ], [ - 0.39711084961891174 + 0.5934339761734009 ], [ - -0.346291720867157 + 0.5854350924491882 ], [ - 1.076295018196106 + 0.07141883671283722 ] ], [ [ - 0.15793544054031372 + 1.985298991203308 ], [ - 0.5684465765953064 + 1.7124855518341064 ], [ - -0.49570122361183167 + 1.6894029378890991 ], [ - 1.5406686067581177 + 0.2060949206352234 ] ] ], [ [ [ - 0.17225612699985504 + 0.3047720491886139 ], [ - 1.785692811012268 + -0.3631243109703064 ], [ - 0.06631706655025482 + -0.1555982083082199 ], [ - 1.1071641445159912 + 0.19470395147800446 ] ], [ [ - 0.0998910516500473 + 0.5929553508758545 ], [ - 1.0355204343795776 + -0.706483781337738 ], [ - 0.03845715895295143 + -0.30272719264030457 ], [ - 0.6420427560806274 + 0.37881016731262207 ] ], [ [ - 0.1429896056652069 + 1.711104393005371 ], [ - 1.4823014736175537 + -2.0387158393859863 ], [ - 0.05504971742630005 + -0.8735865354537964 ], [ - 0.919055700302124 + 1.0931408405303955 ] ] ] @@ -5324,80 +6269,80 @@ export const testData = { [ [ [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ] ] ], [ [ [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ] ] ], [ [ [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ] ] ], [ [ [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ] ] ], [ [ [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ], [ - -2.6874330043792725 + -2.099658727645874 ] ] ] @@ -5405,17 +6350,17 @@ export const testData = { "expected_grad_y": [ [ [ - -9.72719955444336 + -7.285405158996582 ] ], [ [ - -9.72719955444336 + -7.285405158996582 ] ], [ [ - -9.72719955444336 + -7.285405158996582 ] ] ] @@ -5425,164 +6370,164 @@ export const testData = { { "test_name": "matmul_1D_dot_product", "input_x": [ - 1.9982808828353882, - 0.34709975123405457, - -0.10135623067617416 + -0.13354362547397614, + -2.023963212966919, + -1.170003056526184 ], "input_y": [ - -0.7542831897735596, - 1.9345619678497314, - -1.2589340209960938 + -1.1057088375091553, + -0.5529776215553284, + 1.1801894903182983 ], - "expected_output": -0.7081828713417053, + "expected_output": -0.11395859718322754, "expected_grad_x": [ - -0.7542831897735596, - 1.9345619678497314, - -1.2589340209960938 + -1.1057088375091553, + -0.5529776215553284, + 1.1801894903182983 ], "expected_grad_y": [ - 1.9982808828353882, - 0.34709975123405457, - -0.10135623067617416 + -0.13354362547397614, + -2.023963212966919, + -1.170003056526184 ] }, { "test_name": "matmul_2D_matrix_multiply", "input_x": [ [ - -0.38954418897628784, - 0.5330391526222229, - -0.24234455823898315 + 0.8215275406837463, + 0.1607755422592163, + -0.19208626449108124 ], [ - 0.6653695106506348, - 0.9382926821708679, - 0.044521868228912354 + -0.6162866353988647, + -0.02657255157828331, + -0.25292056798934937 ] ], "input_y": [ [ - 1.1535056829452515, - 1.0917677879333496, - 0.04327869415283203, - -1.7126272916793823 + -0.28625473380088806, + 0.3182649314403534, + 1.1329631805419922, + -1.1634578704833984 ], [ - -1.030257225036621, - -0.5207390189170837, - 1.1711158752441406, - -0.45347651839256287 + -2.6641499996185303, + 1.012193202972412, + -0.6236492991447449, + 0.5437685251235962 ], [ - 0.3185255229473114, - 1.3442730903625488, - -0.07879567891359329, - -0.7328374981880188 + -2.3363192081451416, + 0.10341913998126984, + 0.25140896439552307, + 1.244645357131958 ] ], "expected_output": [ [ - -1.0757018327713013, - -1.0286433696746826, - 0.6264873743057251, - 0.6030224561691284 + -0.21472150087356567, + 0.4043339192867279, + 0.7822006940841675, + -1.1074672937393188 ], [ - -0.1849939525127411, - 0.29767292737960815, - 1.1241376399993896, - -1.5976510047912598 + 0.838111400604248, + -0.24919579923152924, + -0.7452446222305298, + 0.38777783513069153 ] ], "expected_grad_x": [ [ - 0.5759249925613403, - -0.8333569765090942, - 0.8511654734611511 + 0.001515507698059082, + -1.7318376302719116, + -0.736845850944519 ], [ - 0.5759249925613403, - -0.8333569765090942, - 0.8511654734611511 + 0.001515507698059082, + -1.7318376302719116, + -0.736845850944519 ] ], "expected_grad_y": [ [ - 0.2758253216743469, - 0.2758253216743469, - 0.2758253216743469, - 0.2758253216743469 + 0.2052409052848816, + 0.2052409052848816, + 0.2052409052848816, + 0.2052409052848816 ], [ - 1.4713318347930908, - 1.4713318347930908, - 1.4713318347930908, - 1.4713318347930908 + 0.1342029869556427, + 0.1342029869556427, + 0.1342029869556427, + 0.1342029869556427 ], [ - -0.1978226900100708, - -0.1978226900100708, - -0.1978226900100708, - -0.1978226900100708 + -0.4450068473815918, + -0.4450068473815918, + -0.4450068473815918, + -0.4450068473815918 ] ] }, { "test_name": "matmul_1D_2D_prepend_remove", "input_x": [ - 0.11520808190107346, - -1.3933792114257812, - -2.112499237060547 + 0.5262587070465088, + 0.7186952829360962, + 0.2846910357475281 ], "input_y": [ [ - -0.5033561587333679, - -0.3874717056751251, - 1.9671382904052734, - 0.5708574652671814 + 0.40772733092308044, + 0.25750425457954407, + 0.9894949793815613, + -0.13609549403190613 ], [ - 0.9349703192710876, - -2.07222843170166, - -0.5888614654541016, - -0.5368285179138184 + -0.046313412487506866, + -0.8070783019065857, + -0.8997132778167725, + 0.4604453444480896 ], [ - -0.55372554063797, - 0.13748766481876373, - 0.3860569894313812, - -1.294584035873413 + 0.09099376946687698, + 1.264731764793396, + -0.5384116172790527, + -0.5032119154930115 ] ], "expected_output": [ - -0.1910141259431839, - 2.5523173809051514, - 0.23159240186214447, - 3.5485808849334717 + 0.20718994736671448, + -0.08447171002626419, + -0.27917027473449707, + 0.11603852361440659 ], "expected_grad_x": [ - 1.6471679210662842, - -2.2629480361938477, - -1.3247649669647217 + 1.518631100654602, + -1.2926596403121948, + 0.3141019344329834 ], "expected_grad_y": [ [ - 0.11520808190107346, - 0.11520808190107346, - 0.11520808190107346, - 0.11520808190107346 + 0.5262587070465088, + 0.5262587070465088, + 0.5262587070465088, + 0.5262587070465088 ], [ - -1.3933792114257812, - -1.3933792114257812, - -1.3933792114257812, - -1.3933792114257812 + 0.7186952829360962, + 0.7186952829360962, + 0.7186952829360962, + 0.7186952829360962 ], [ - -2.112499237060547, - -2.112499237060547, - -2.112499237060547, - -2.112499237060547 + 0.2846910357475281, + 0.2846910357475281, + 0.2846910357475281, + 0.2846910357475281 ] ] }, @@ -5590,41 +6535,41 @@ export const testData = { "test_name": "matmul_2D_1D_matrix_vector", "input_x": [ [ - -0.9253478646278381, - 0.026843471452593803, - -1.56169593334198 + -1.1151187419891357, + -0.6466555595397949, + -0.9256587624549866 ], [ - 1.6090036630630493, - 0.5269482731819153, - -0.4549155831336975 + 1.9982808828353882, + 0.34709975123405457, + -0.10135623067617416 ] ], "input_y": [ - 0.8616125583648682, - 0.8724160194396973, - 1.0766733884811401 + -0.7542831897735596, + 1.9345619678497314, + -1.2589340209960938 ], "expected_output": [ - -2.4553091526031494, - 1.3562602996826172 + 0.7554633021354675, + -0.7081828713417053 ], "expected_grad_x": [ [ - 0.8616125583648682, - 0.8724160194396973, - 1.0766733884811401 + -0.7542831897735596, + 1.9345619678497314, + -1.2589340209960938 ], [ - 0.8616125583648682, - 0.8724160194396973, - 1.0766733884811401 + -0.7542831897735596, + 1.9345619678497314, + -1.2589340209960938 ] ], "expected_grad_y": [ - 0.6836557984352112, - 0.5537917613983154, - -2.0166115760803223 + 0.8831621408462524, + -0.29955580830574036, + -1.027014970779419 ] }, { @@ -5633,28 +6578,28 @@ export const testData = { [ [ [ - -1.411333680152893, - 0.36025282740592957, - -1.2506803274154663 + -0.38954418897628784, + 0.5330391526222229, + -0.24234455823898315 ], [ - -0.1725202202796936, - 0.8875670433044434, - 1.4435428380966187 + 0.6653695106506348, + 0.9382926821708679, + 0.044521868228912354 ] ] ], [ [ [ - -0.4563913941383362, - 0.04452125355601311, - -0.5545827150344849 + 1.1535056829452515, + 1.0917677879333496, + 0.04327869415283203 ], [ - 1.213465929031372, - -0.5521613359451294, - 1.3268003463745117 + -1.7126272916793823, + -1.030257225036621, + -0.5207390189170837 ] ] ] @@ -5662,44 +6607,44 @@ export const testData = { "input_y": [ [ [ - -1.2941471338272095, - -1.2331957817077637 + 1.6714451313018799, + -0.4941222369670868 ], [ - -1.0800817012786865, - 1.9881891012191772 + 1.1431647539138794, + 1.3563427925109863 ], [ - 0.1034913882613182, - 0.11661393195390701 + -1.2485027313232422, + -0.02572690322995186 ] ], [ [ - -0.02522038109600544, - 0.3788713812828064 + 1.936702013015747, + -0.9197023510932922 ], [ - 0.24455690383911133, - -0.8915789723396301 + 0.8713390231132507, + -0.522757887840271 ], [ - -1.5224734544754028, - -2.6157381534576416 + -1.287382960319519, + -1.2039293050765991 ] ], [ [ - -0.5713837146759033, - -0.6671661734580994 + -0.6580986976623535, + -0.35780131816864014 ], [ - -0.09203547239303589, - 0.9548746347427368 + 0.4201647937297821, + -0.0068255518563091755 ], [ - 0.18482893705368042, - -0.11677189916372299 + 0.33024173974990845, + -0.9533721804618835 ] ] ], @@ -5707,64 +6652,64 @@ export const testData = { [ [ [ - 1.307936429977417, - 2.31085467338562 + 0.2608177065849304, + 0.9217010736465454 ], [ - -0.5859841108322144, - 2.1457395553588867 + 2.1291661262512207, + 0.942727267742157 ] ], [ [ - 2.0278244018554688, - 2.4155445098876953 + 0.022017061710357666, + 0.3713800013065338 ], [ - -1.9763438701629639, - -4.63262939453125 + 2.0488767623901367, + -1.1560429334640503 ] ], [ [ - 0.5420950651168823, - 1.4316346645355225 + 0.4002905488014221, + 0.3667857050895691 ], [ - 0.2836960554122925, - 0.7940497398376465 + -0.02893828973174095, + -0.28692036867141724 ] ] ], [ [ [ - 0.48515650629997253, - 0.5866645574569702 + 3.122058391571045, + 0.9097251296043396 ], [ - -0.8367117047309875, - -2.439518690109253 + -3.3901724815368652, + -0.5377377867698669 ] ], [ [ - 0.8667358160018921, - 1.2380353212356567 + 3.129580497741699, + -1.6837165355682373 ], [ - -2.185657262802124, - -2.518519401550293 + -3.544161319732666, + 2.7406153678894043 ] ], [ [ - 0.15417414903640747, - 0.41176077723503113 + -0.28610578179359436, + -0.46143847703933716 ], [ - -0.39730513095855713, - -1.4917612075805664 + 0.5222302675247192, + 1.1162704229354858 ] ] ] @@ -5773,28 +6718,28 @@ export const testData = { [ [ [ - -3.4122416973114014, - 1.1239244937896729, - -3.8500492572784424 + 1.1784225702285767, + 3.261427640914917, + -4.388672351837158 ], [ - -3.4122416973114014, - 1.1239244937896729, - -3.8500492572784424 + 1.1784225702285767, + 3.261427640914917, + -4.388672351837158 ] ] ], [ [ [ - -3.4122416973114014, - 1.1239244937896729, - -3.8500492572784424 + 1.1784225702285767, + 3.261427640914917, + -4.388672351837158 ], [ - -3.4122416973114014, - 1.1239244937896729, - -3.8500492572784424 + 1.1784225702285767, + 3.261427640914917, + -4.388672351837158 ] ] ] @@ -5802,44 +6747,44 @@ export const testData = { "expected_grad_y": [ [ [ - -0.8267794251441956, - -0.8267794251441956 + -0.28329628705978394, + -0.28329628705978394 ], [ - 0.7401798367500305, - 0.7401798367500305 + 1.5328423976898193, + 1.5328423976898193 ], [ - 0.9650801420211792, - 0.9650801420211792 + -0.6752830147743225, + -0.6752830147743225 ] ], [ [ - -0.8267794251441956, - -0.8267794251441956 + -0.28329628705978394, + -0.28329628705978394 ], [ - 0.7401798367500305, - 0.7401798367500305 + 1.5328423976898193, + 1.5328423976898193 ], [ - 0.9650801420211792, - 0.9650801420211792 + -0.6752830147743225, + -0.6752830147743225 ] ], [ [ - -0.8267794251441956, - -0.8267794251441956 + -0.28329628705978394, + -0.28329628705978394 ], [ - 0.7401798367500305, - 0.7401798367500305 + 1.5328423976898193, + 1.5328423976898193 ], [ - 0.9650801420211792, - 0.9650801420211792 + -0.6752830147743225, + -0.6752830147743225 ] ] ] @@ -5854,96 +6799,96 @@ export const testData = { "input": [ [ [ - 2.5331664085388184, - -1.1566962003707886, - -1.0765177011489868, - -0.5477657318115234, - -0.3289257884025574 + -0.4858148694038391, + -0.49008455872535706, + 0.9206437468528748, + -0.6285682320594788, + 0.6663421988487244 ], [ - 0.05841278284788132, - 2.1100034713745117, - 0.7726138234138489, - 0.9717037081718445, - -0.40528324246406555 + -0.03547006472945213, + -0.11422315984964371, + -0.05629456788301468, + 0.2728163003921509, + 0.7324181199073792 ], [ - -0.2497664988040924, - 0.22397132217884064, - -0.6875526905059814, - -0.489844411611557, - 0.399687796831131 + 1.7147032022476196, + -2.687852621078491, + -0.042423129081726074, + 0.7085697650909424, + -1.2797164916992188 ], [ - 0.6981958150863647, - 0.8767979145050049, - -0.21163156628608704, - 0.05950453504920006, - 1.7285562753677368 + -1.5433486700057983, + 1.2571464776992798, + 0.5763423442840576, + -0.9772611856460571, + -1.533514380455017 ] ], [ [ - 0.2920781075954437, - -0.6925867199897766, - -0.8442767858505249, - -0.32920387387275696, - -0.7236549258232117 + 0.7982524633407593, + -0.5078546404838562, + -0.91661536693573, + 0.4702746272087097, + -1.750167965888977 ], [ - 0.1715654879808426, - 0.3004419207572937, - 1.6395184993743896, - -1.0744175910949707, - 0.32121846079826355 + 0.9156812429428101, + -0.7037500739097595, + 1.2993873357772827, + -1.6580263376235962, + 3.150531768798828 ], [ - 0.2892301678657532, - 0.35196706652641296, - -0.7732301354408264, - 1.324594259262085, - -1.7715193033218384 + -0.2053070068359375, + -1.4739270210266113, + -0.03289732709527016, + 0.3655078113079071, + -0.03989681601524353 ], [ - 0.0968942642211914, - 0.36735019087791443, - 0.47318676114082336, - 0.5876799821853638, - 0.183979332447052 + -1.2108122110366821, + -1.6996815204620361, + -0.4819910228252411, + -0.9970720410346985, + -0.34807199239730835 ] ], [ [ - -0.025479229167103767, - -0.15332099795341492, - 1.0871516466140747, - 0.6801379919052124, - 0.3648642897605896 + 0.29087918996810913, + -0.1686161607503891, + -0.7467212677001953, + 1.4040724039077759, + 1.2316521406173706 ], [ - -0.029142292216420174, - 1.1481481790542603, - -1.1586997509002686, - 0.16382797062397003, - -0.5482404828071594 + 2.9194436073303223, + 0.4634987413883209, + 0.6845051050186157, + 1.5183887481689453, + -0.91494220495224 ], [ - 0.5447612404823303, - 1.522364616394043, - -1.7682260274887085, - 1.1501456499099731, - 0.03875375911593437 + 2.251573324203491, + -0.3680903911590576, + -2.4219810962677, + -0.08308011293411255, + 0.683392345905304 ], [ - -0.7637909650802612, - -2.0094480514526367, - -0.5111404657363892, - -0.7054344415664673, - 1.1544770002365112 + 2.353518486022949, + 0.04335293173789978, + 0.580488383769989, + 0.6679447293281555, + 0.6449635624885559 ] ] ], - "expected_output": 5.651155948638916, + "expected_output": 2.9822170734405518, "expected_grad": [ [ [ @@ -6045,123 +6990,123 @@ export const testData = { "input": [ [ [ - 1.6580723524093628, - 0.2531333863735199, - -0.7901830077171326, - 1.3513535261154175, - -0.07234654575586319 + 1.4343817234039307, + -1.9291707277297974, + -1.6733232736587524, + 0.9231958985328674, + -0.020498022437095642 ], [ - 2.0859556198120117, - 0.6107109189033508, - 0.2142704576253891, - 0.20150239765644073, - -0.5960649251937866 + 0.48795756697654724, + 0.37779226899147034, + -1.057392954826355, + -0.22911065816879272, + -0.3448553681373596 ], [ - -1.5545626878738403, - 1.5109810829162598, - -1.4638135433197021, - -0.5889208316802979, - 0.0267170500010252 + 0.4634801745414734, + 1.4675588607788086, + 1.5677039623260498, + 0.4278451204299927, + -0.2732718884944916 ], [ - -0.25020739436149597, - 1.2176311016082764, - -1.04723060131073, - 1.5084929466247559, - -1.4026533365249634 + 0.5940448641777039, + -0.34265488386154175, + 1.2370060682296753, + 1.1887205839157104, + 1.002081274986267 ] ], [ [ - -1.339130163192749, - -2.1181247234344482, - 0.8562206029891968, - 0.4322175085544586, - 0.48647579550743103 + -1.4646551609039307, + -0.030163101851940155, + -0.11644338816404343, + 0.3850177526473999, + 0.05211031809449196 ], [ - -0.6963290572166443, - 1.926598310470581, - -2.0344724655151367, - -0.8289412260055542, - -0.14974211156368256 + 0.2882064878940582, + 0.35200777649879456, + -0.3861907422542572, + 0.3567925691604614, + 1.7113765478134155 ], [ - 1.3149042129516602, - 1.2470786571502686, - 0.8008047342300415, - 0.9250672459602356, - 1.6375963687896729 + 0.21664851903915405, + 0.3170451521873474, + -0.1140289157629013, + -0.8452204465866089, + 0.5263259410858154 ], [ - -0.9297109842300415, - -0.8541247248649597, - 0.15929833054542542, - -0.41023650765419006, - -0.7588294148445129 + 0.12554097175598145, + -1.7527469396591187, + 0.7751637697219849, + -0.10626579821109772, + 0.8907954692840576 ] ], [ [ - -1.8527090549468994, - -1.3658616542816162, - 0.45045167207717896, - -0.01783839240670204, - 0.3848164975643158 + 2.0987792015075684, + -0.5285679697990417, + -0.4658718407154083, + 0.49164071679115295, + 0.6064606308937073 ], [ - 0.29434895515441895, - 0.6351331472396851, - 0.20356419682502747, - -0.18102435767650604, - -0.9300417900085449 + -0.46068817377090454, + -0.8800807595252991, + -1.4766337871551514, + 0.982934296131134, + 0.034095875918865204 ], [ - 0.4725607931613922, - -1.008976936340332, - -0.16193436086177826, - 0.886084258556366, - 1.8162529468536377 + -0.461677223443985, + 0.3484693765640259, + -1.7167327404022217, + 0.04617787152528763, + 0.09389957040548325 ], [ - 0.20681823790073395, - 0.11982676386833191, - 0.9609657526016235, - -1.2074177265167236, - 0.1798500418663025 + -1.35635244846344, + -1.0603324174880981, + 1.0654057264328003, + 0.8679789900779724, + -0.5582399368286133 ] ] ], "expected_output": [ [ - -1.5337668657302856, - -3.2308530807495117, - 0.5164892673492432, - 1.7657326459884644, - 0.7989457845687866 + 2.0685057640075684, + -2.4879016876220703, + -2.255638599395752, + 1.7998543977737427, + 0.6380729079246521 ], [ - 1.6839754581451416, - 3.1724424362182617, - -1.6166378259658813, - -0.8084632158279419, - -1.6758488416671753 + 0.3154758810997009, + -0.15028071403503418, + -2.920217514038086, + 1.1106162071228027, + 1.400617003440857 ], [ - 0.23290231823921204, - 1.7490828037261963, - -0.8249431848526001, - 1.2222306728363037, - 3.4805665016174316 + 0.21845147013664246, + 2.133073329925537, + -0.2630577087402344, + -0.3711974620819092, + 0.3469536304473877 ], [ - -0.9731001853942871, - 0.48333314061164856, - 0.07303345203399658, - -0.10916125774383545, - -1.9816327095031738 + -0.6367666125297546, + -3.155734062194824, + 3.07757568359375, + 1.9504337310791016, + 1.3346368074417114 ] ], "expected_grad": [ @@ -6265,124 +7210,124 @@ export const testData = { "input": [ [ [ - 1.354137897491455, - -0.07092823088169098, - 2.172628879547119, - 2.2334160804748535, - 0.22253729403018951 + 0.02351505309343338, + 0.28558799624443054, + 0.020343216136097908, + 0.9289091229438782, + -0.9238923788070679 ], [ - -0.9300196170806885, - 0.3208498954772949, - 0.03714213892817497, - 0.5674765110015869, - 0.8283826112747192 + 1.1473842859268188, + 0.941576361656189, + 0.4414193034172058, + -1.7462857961654663, + 0.7103408575057983 ], [ - -0.005647851154208183, - 0.3184404969215393, - -0.24027781188488007, - -0.25278961658477783, - -0.23367400467395782 + -0.10175959765911102, + -0.9663392901420593, + -1.4231536388397217, + -0.7846477627754211, + 1.7235876321792603 ], [ - 1.5783164501190186, - 1.2004878520965576, - -1.2668757438659668, - -0.6659766435623169, - -1.7441022396087646 + 0.1520993411540985, + -0.17470814287662506, + -1.7561272382736206, + 1.4259073734283447, + 0.5127183794975281 ] ], [ [ - 0.11392442137002945, - -0.19157223403453827, - 2.5826096534729004, - -0.6460883021354675, - 1.443666696548462 + -0.4026731848716736, + 1.9770677089691162, + -0.030815819278359413, + -1.737373948097229, + -0.09136287868022919 ], [ - 0.196146160364151, - 1.050157904624939, - 0.7994747757911682, - 0.19265566766262054, - -0.4098454415798187 + -0.5283262729644775, + -0.46433013677597046, + -0.15669254958629608, + -1.5964131355285645, + -1.5322294235229492 ], [ - 1.2105144262313843, - -0.1680372804403305, - 0.16369947791099548, - 1.3456140756607056, - -1.1182259321212769 + -0.11408505588769913, + -0.9761450290679932, + 0.24113479256629944, + -0.05469474941492081, + 0.04771281033754349 ], [ - -0.5912953019142151, - 0.528777003288269, - -0.9880816340446472, - 0.09833063185214996, - 0.31492868065834045 + -0.8637551665306091, + -1.141897201538086, + -0.8292406797409058, + 0.32627707719802856, + -0.14103326201438904 ] ], [ [ - 1.763922929763794, - -0.048379626125097275, - 0.6488431692123413, - -1.1631555557250977, - 0.45085909962654114 + -0.25818052887916565, + -1.340453863143921, + -0.5561836957931519, + 1.173104166984558, + 0.6556643843650818 ], [ - 0.04091703146696091, - -0.06933283060789108, - 0.2585761547088623, - 0.4775455594062805, - -1.4889180660247803 + -0.7471360564231873, + 1.1705763339996338, + 1.6411151885986328, + 0.428303986787796, + -1.0703928470611572 ], [ - -1.4860504865646362, - 0.2769140899181366, - 0.07306429743766785, - 0.9967362284660339, - 1.0237910747528076 + -0.6159464716911316, + -1.0194525718688965, + 0.37926265597343445, + 0.9845729470252991, + -1.7715047597885132 ], [ - -1.2132517099380493, - 0.9744538068771362, - 0.45322731137275696, - 1.1672674417495728, - 0.7930575013160706 + 0.4349344074726105, + 0.06312361359596252, + -0.6894504427909851, + -0.2829807698726654, + 0.6600029468536377 ] ] ], "expected_output": [ [ [ - 3.231985092163086, - -0.3108800947666168, - 5.40408182144165, - 0.42417216300964355, - 2.117063045501709 + -0.6373386383056641, + 0.9222018718719482, + -0.5666562914848328, + 0.3646393418312073, + -0.3595908284187317 ], [ - -0.6929564476013184, - 1.3016749620437622, - 1.0951931476593018, - 1.237677812576294, - -1.0703809261322021 + -0.12807804346084595, + 1.647822618484497, + 1.9258419275283813, + -2.9143950939178467, + -1.892281413078308 ], [ - -0.28118395805358887, - 0.4273173213005066, - -0.003514036536216736, - 2.0895607471466064, - -0.32810890674591064 + -0.8317911624908447, + -2.9619369506835938, + -0.8027561902999878, + 0.14523041248321533, + -0.00020432472229003906 ], [ - -0.22623056173324585, - 2.703718662261963, - -1.8017301559448242, - 0.5996214151382446, - -0.636116087436676 + -0.27672144770622253, + -1.2534817457199097, + -3.2748184204101562, + 1.4692035913467407, + 1.0316880941390991 ] ] ], @@ -6487,116 +7432,116 @@ export const testData = { "input": [ [ [ - -0.9585699439048767, - -0.5702749490737915, - 0.19281719624996185, - 0.3847457766532898, - -0.8595814108848572 + -1.2625644207000732, + -0.1746397167444229, + 0.5484238862991333, + 0.45765289664268494, + 0.9676891565322876 ], [ - 1.2814747095108032, - 0.9838918447494507, - -0.060601282864809036, - -1.2942535877227783, - 0.6038413643836975 + -0.6673583388328552, + 1.6183183193206787, + -0.26440465450286865, + -1.9805819988250732, + 0.6427897214889526 ], [ - 1.117246150970459, - 0.4163925051689148, - 0.6747081875801086, - 0.2249874323606491, - -0.5817884206771851 + -0.3697128891944885, + -0.24597389996051788, + 0.3293827772140503, + 0.6973733305931091, + 0.8342204093933105 ], [ - 0.8646862506866455, - 0.6935068964958191, - -0.4358613193035126, - -0.9824548959732056, - -0.9062879085540771 + -1.098692774772644, + 0.17085814476013184, + -0.7267439365386963, + -3.832531690597534, + 0.11584769189357758 ] ], [ [ - 1.25956130027771, - 0.34626761078834534, - 0.21445013582706451, - -0.26712074875831604, - 0.46033239364624023 + 1.9915446043014526, + 1.0238094329833984, + 2.1327197551727295, + 0.23347528278827667, + -0.3182602822780609 ], [ - 1.179113507270813, - -1.0105520486831665, - -0.620258629322052, - -1.4548780918121338, - -0.5897568464279175 + -0.28946641087532043, + -0.9444983005523682, + -0.1793764978647232, + 0.31204938888549805, + 0.717379093170166 ], [ - 1.492590308189392, - 1.144742488861084, - 0.723761260509491, - -0.18846826255321503, - -0.5821011662483215 + -0.2302778661251068, + 0.7147674560546875, + 0.14227113127708435, + -0.9353750944137573, + -0.8332573175430298 ], [ - -0.4351550042629242, - -1.2878144979476929, - 1.9290111064910889, - -0.13884380459785461, - -0.4319995641708374 + -0.952683687210083, + -0.36366915702819824, + -1.2479252815246582, + -0.09261447191238403, + 0.6533640027046204 ] ], [ [ - 0.6912683248519897, - 0.5198960900306702, - -0.7546091079711914, - -0.033411234617233276, - 0.0006704955594614148 + -0.5295901894569397, + -0.6448984146118164, + -0.369537353515625, + -0.47141557931900024, + 1.2438589334487915 ], [ - -0.012675444595515728, - 2.065865993499756, - 1.0178154706954956, - -1.9378867149353027, - -0.5477144718170166 + -1.7002424001693726, + -1.2208786010742188, + -1.3158544301986694, + -1.8084080219268799, + -0.4799889922142029 ], [ - -0.18265697360038757, - -1.2373387813568115, - 1.439368486404419, - -0.9488052129745483, - 0.10380307585000992 + 0.7350953221321106, + -0.269319087266922, + 0.8924283385276794, + 1.3709611892700195, + 0.7821508049964905 ], [ - -0.6988955140113831, - -0.5013832449913025, - -0.1714278757572174, - -1.5410068035125732, - -0.3302071988582611 + -0.30908405780792236, + 0.6509400010108948, + -1.5479099750518799, + -1.2930028438568115, + 0.8795658946037292 ] ] ], "expected_output": [ [ - 2.304837226867676, - 1.523516297340393, - 0.3710627853870392, - -1.6669752597808838, - -1.7438163757324219 + -3.3983283042907715, + 1.3685628175735474, + -0.11334192752838135, + -4.658087253570557, + 2.560546875 ], [ - 3.496110439300537, - -0.8073564767837524, - 2.2469639778137207, - -2.0493109226226807, - -1.1435251235961914 + 0.5191166400909424, + 0.43040943145751953, + 0.847689151763916, + -0.48246490955352783, + 0.21922549605369568 ], [ - -0.20295962691307068, - 0.8470399975776672, - 1.5311470031738281, - -4.4611101150512695, - -0.77344810962677 + -1.8038214445114136, + -1.4841561317443848, + -2.3408734798431396, + -2.2018651962280273, + 2.425586700439453 ] ], "expected_grad": [ @@ -6700,121 +7645,121 @@ export const testData = { "input": [ [ [ - 0.21622301638126373, - 0.9593762159347534, - 0.17837846279144287, - -0.1793491244316101, - -0.5583686828613281 + -0.03328368067741394, + -0.1935928761959076, + -0.7671046257019043, + 1.041800618171692, + -0.5939895510673523 ], [ - -0.880412757396698, - -0.8791263699531555, - 1.5490630865097046, - 1.5681371688842773, - 1.577425479888916 + -0.9907869696617126, + -0.9927570819854736, + -0.2557562291622162, + -0.22515931725502014, + 0.7214905023574829 ], [ - -0.4480331838130951, - 1.8764188289642334, - -0.8918796181678772, - 0.43931636214256287, - -1.030982494354248 + 0.12578019499778748, + 1.4050774574279785, + 0.19477412104606628, + -0.4741835296154022, + 0.1276102066040039 ], [ - -1.4263975620269775, - -0.6300327181816101, - -0.21408268809318542, - -1.3461240530014038, - -0.05369861051440239 + 0.6101059317588806, + -0.3841469883918762, + -0.921748697757721, + -0.4872817397117615, + -0.5074361562728882 ] ], [ [ - -1.0822854042053223, - 0.3181943893432617, - -2.230900526046753, - -1.0310343503952026, - 0.411555677652359 + 0.5522661805152893, + 0.061027202755212784, + -0.9556332230567932, + -0.7779799103736877, + 1.3941880464553833 ], [ - 0.7411331534385681, - 0.960921049118042, - -1.2231221199035645, - 0.0782814472913742, - -0.15562321245670319 + -0.2754690647125244, + -0.5164039731025696, + 0.1548738032579422, + -0.8348855972290039, + 0.22885975241661072 ], [ - 0.40913498401641846, - 0.4989188015460968, - -1.1010884046554565, - -0.5320523977279663, - -0.5345580577850342 + -2.0042972564697266, + 0.005512263625860214, + -0.3478994369506836, + 0.5377600193023682, + -0.9290909767150879 ], [ - -1.4051520824432373, - 1.8911962509155273, - 1.3595441579818726, - -0.8487699627876282, - -1.841177225112915 + 1.1321873664855957, + -0.7327660322189331, + 1.1509846448898315, + -0.6960206627845764, + 0.5155009627342224 ] ], [ [ - -1.3550636768341064, - -1.025729775428772, - -0.8582409024238586, - -0.47482022643089294, - -1.0972518920898438 + 0.27344995737075806, + 0.6651293039321899, + 1.0537790060043335, + 0.7269541621208191, + -0.4144572615623474 ], [ - 0.8443618416786194, - 1.2229877710342407, - -0.607181966304779, - -1.8006703853607178, - 1.8074243068695068 + -0.7832543253898621, + 1.1300108432769775, + -1.612937569618225, + 0.445094496011734, + 0.051411572843790054 ], [ - -1.3159326314926147, - -0.1285407692193985, - -0.565393328666687, - 0.2557545602321625, - -1.537744164466858 + -0.35013654828071594, + -1.006677508354187, + -0.534939169883728, + 0.9171100854873657, + -1.031330943107605 ], [ - -0.1796068251132965, - -0.11240867525339127, - 0.2712157368659973, - 1.1221709251403809, - 2.794304609298706 + -0.3431452810764313, + -0.5040718913078308, + 0.07251296937465668, + -1.078025221824646, + -0.39548805356025696 ] ] ], "expected_output": [ [ [ - -2.5386204719543457, - 1.3266358375549316, - 0.6214792728424072, - 0.4819803237915039, - -0.06562431156635284 + -0.2881844639778137, + -0.16541951894760132, + -1.74983549118042, + -0.14482393860816956, + -0.25232499837875366 ] ], [ [ - -1.3371694087982178, - 3.6692304611206055, - -3.1955666542053223, - -2.3335752487182617, - -2.119802951812744 + -0.5953128337860107, + -1.1826305389404297, + 0.002325773239135742, + -1.7711260318756104, + 1.2094578742980957 ] ], [ [ - -2.0062413215637207, - -0.043691448867321014, - -1.7596004009246826, - -0.8975651264190674, - 1.9667328596115112 + -1.2030861377716064, + 0.28439074754714966, + -1.0215847492218018, + 1.0111335515975952, + -1.7898646593093872 ] ] ], @@ -6919,113 +7864,113 @@ export const testData = { "input": [ [ [ - 2.321488618850708, - -0.9497286677360535, - 1.6485934257507324, - -1.9016783237457275, - 0.6118991374969482 + -0.16857317090034485, + 0.688886284828186, + 0.09771557152271271, + 1.052785038948059, + -1.1113090515136719 ], [ - -0.5020667910575867, - 0.5067698955535889, - 0.2828640341758728, - -1.9398406744003296, - -1.724557876586914 + -0.9389597773551941, + -1.3075956106185913, + 0.9676118493080139, + -0.7394251227378845, + -1.5103271007537842 ], [ - -1.187090516090393, - 0.2815004289150238, - 0.21720317006111145, - 0.6477780938148499, - -0.6847841143608093 + 0.08060058951377869, + -1.8929684162139893, + 0.5650917887687683, + 0.8412631750106812, + -0.9580911993980408 ], [ - -0.7950332760810852, - -0.5194478034973145, - 0.31374549865722656, - -0.13856260478496552, - -0.7214519381523132 + -0.7895215749740601, + 0.015372429974377155, + -0.027610722929239273, + -0.053718894720077515, + -0.7734133005142212 ] ], [ [ - -0.6180415749549866, - 0.8307966589927673, - -1.4335700273513794, - -0.8756160736083984, - 1.3628478050231934 + -1.3837915658950806, + 0.97823166847229, + 1.2639201879501343, + -2.0509865283966064, + 0.7195857763290405 ], [ - -0.8794435858726501, - 0.2203734815120697, - 0.07557395845651627, - 1.5741719007492065, - 0.13540978729724884 + 0.5959717631340027, + -1.8225737810134888, + -0.1343626081943512, + 0.49848124384880066, + 0.3930509090423584 ], [ - -0.7953895330429077, - -1.1213213205337524, - -0.10318246483802795, - 1.6807347536087036, - -0.2909294664859772 + -0.6577728390693665, + 0.24517367780208588, + 0.20588766038417816, + -0.8329556584358215, + -0.820264458656311 ], [ - -0.19037924706935883, - -0.4397279620170593, - 0.890130877494812, - 0.3846955895423889, - 0.17066167294979095 + -0.8202312588691711, + 0.9118992686271667, + -1.6226643323898315, + 0.6528452634811401, + 0.474252313375473 ] ], [ [ - -0.7483856081962585, - 0.6799973845481873, - -0.1450810432434082, - -0.010367825627326965, - -0.4629494845867157 + -1.0028913021087646, + 0.06786083430051804, + 0.5943557024002075, + -1.4299345016479492, + -1.8149548768997192 ], [ - -1.6245776414871216, - -0.18524813652038574, - -0.34354501962661743, - -0.9827845096588135, - 1.4724041223526 + -0.48883718252182007, + 0.3190588653087616, + 0.8207234740257263, + 0.26855215430259705, + 0.5349103808403015 ], [ - 0.5184305310249329, - 1.1344083547592163, - 0.1288852095603943, - 0.2891088128089905, - 0.6047351360321045 + 0.2828715443611145, + 0.2559785544872284, + -0.3839770257472992, + 0.9996393918991089, + -0.411981463432312 ], [ - 0.0995018258690834, - 0.21674297749996185, - -0.7446264624595642, - -1.889365315437317, - 0.8229770660400391 + 1.7920981645584106, + -0.7672699093818665, + -1.307977557182312, + -1.7257500886917114, + -0.03232753649353981 ] ] ], "expected_output": [ [ - 1.730574131011963, - -3.376831531524658, - -0.7253928780555725, - -1.8607500791549683 + 0.5595046877861023, + -3.528696060180664, + -1.364104151725769, + -1.628892183303833 ], [ - -0.7335832118988037, - 1.1260855197906494, - -0.6300879716873169, - 0.8153809309005737 + -0.47304046154022217, + -0.4694325029850006, + -1.8599317073822021, + -0.4038987159729004 ], [ - -0.6867865324020386, - -1.6637511253356934, - 2.675568103790283, - -1.494769811630249 + -3.585564136505127, + 1.4544076919555664, + 0.7425310015678406, + -2.041226863861084 ] ], "expected_grad": [ @@ -7129,136 +8074,136 @@ export const testData = { "input": [ [ [ - 0.6587340831756592, - 0.6428387761116028, - -1.036969780921936, - -0.2975744307041168, - -0.8517249226570129 + 1.3067461252212524, + 0.1913401335477829, + 1.3767470121383667, + 0.6892044544219971, + 0.43921586871147156 ], [ - 0.2891763746738434, - -0.8932358622550964, - 1.8647022247314453, - 0.9801297783851624, - 0.11956664174795151 + -0.04813985526561737, + -0.3315163552761078, + -0.23632389307022095, + -0.08464081585407257, + -0.2434539496898651 ], [ - -0.12774989008903503, - 0.357759952545166, - -1.123816728591919, - 0.46558526158332825, - -3.0509555339813232 + -1.4118940830230713, + -1.0503880977630615, + 1.110618233680725, + 0.21369199454784393, + 0.9332243204116821 ], [ - 0.8507809042930603, - -0.6753576993942261, - -0.32092228531837463, - -1.3800082206726074, - -0.3640788197517395 + 0.7342482805252075, + -1.1814165115356445, + -0.9001671671867371, + 2.1022186279296875, + 0.13313262164592743 ] ], [ [ - -0.1983477771282196, - 0.5546607375144958, - 0.26535895466804504, - -0.27042195200920105, - -0.28734639286994934 + 0.022425031289458275, + -0.2799490988254547, + -0.13277991116046906, + -1.1816505193710327, + -1.7333787679672241 ], [ - -0.6621134877204895, - 0.8970773220062256, - 1.0963815450668335, - 0.00377941457554698, - 0.41841161251068115 + 1.1858826875686646, + 0.4465799629688263, + 1.1301037073135376, + -0.3333589434623718, + 0.8935588598251343 ], [ - 0.7451213002204895, - 0.019408423453569412, - -2.3971786499023438, - 0.38038408756256104, - 1.3957277536392212 + -1.948160171508789, + -1.366417646408081, + 0.009384111501276493, + 0.6304294466972351, + 0.8632985949516296 ], [ - -0.00876561738550663, - 0.04509954899549484, - 0.21804611384868622, - 2.176718235015869, - 2.1929168701171875 + 1.1419644355773926, + 0.3109254240989685, + -0.10642467439174652, + -1.2388849258422852, + -1.1811842918395996 ] ], [ [ - 0.15840405225753784, - -0.8398545384407043, - -0.8984683752059937, - -0.8500047326087952, - 2.26790452003479 + 0.8579769134521484, + -1.6933249235153198, + 0.28935855627059937, + 0.12979160249233246, + 0.9177106618881226 ], [ - 0.9991294741630554, - -0.29818224906921387, - -0.7564722895622253, - -0.20476730167865753, - 1.405016303062439 + -0.08528606593608856, + 0.646186888217926, + 0.9474418759346008, + -0.9643430113792419, + -0.05544678866863251 ], [ - -1.5722324848175049, - 0.6451810002326965, - 0.3931215703487396, - 0.4133126139640808, - 0.4638987183570862 + 0.6487414836883545, + -1.5244767665863037, + 0.7500134110450745, + -2.1544389724731445, + 1.4023377895355225 ], [ - -0.02982708252966404, - 1.2715272903442383, - 1.0848652124404907, - -0.5404359698295593, - 0.4884187579154968 + 0.38867735862731934, + 0.7254555821418762, + -1.389511227607727, + -0.8552696704864502, + -1.5335310697555542 ] ] ], "expected_output": [ [ [ - -0.8846962451934814 + 4.003253936767578 ], [ - 2.3603391647338867 + -0.9440748691558838 ], [ - -3.4791769981384277 + -0.20474763214588165 ], [ - -1.889586091041565 + 0.888015866279602 ] ], [ [ - 0.0639035701751709 + -3.305333137512207 ], [ - 1.7535364627838135 + 3.322766065597534 ], [ - 0.14346301555633545 + -1.8114655017852783 ], [ - 4.624014854431152 + -1.0736039876937866 ] ], [ [ - -0.16201895475387573 + 0.5015128254890442 ], [ - 1.1447237730026245 + 0.48855286836624146 ], [ - 0.3432813584804535 + -0.8778231143951416 ], [ - 2.274548292160034 + -2.6641790866851807 ] ] ], @@ -7363,96 +8308,96 @@ export const testData = { "input": [ [ [ - -0.49658793210983276, - 0.36382463574409485, - 0.3396982252597809, - 1.273138165473938, - -1.5371414422988892 + -1.1046700477600098, + 0.3997063636779785, + -0.7377328872680664, + 0.8807763457298279, + -0.7662639021873474 ], [ - 1.0402002334594727, - -1.1433440446853638, - -0.6347954273223877, - -0.009090420790016651, - 0.253021240234375 + 1.4585676193237305, + 1.7723872661590576, + 0.32965973019599915, + -0.014356887899339199, + 1.0570905208587646 ], [ - 0.8895691633224487, - 2.015190601348877, - 0.12288182973861694, - 0.283156156539917, - 0.7347971796989441 + 0.40178006887435913, + 0.6623095273971558, + -0.8157885074615479, + 1.7509973049163818, + -0.07119281589984894 ], [ - 1.4138668775558472, - -2.4690840244293213, - -1.6101100444793701, - 1.7436981201171875, - -0.38771313428878784 + -0.3190559148788452, + 0.050714727491140366, + 0.019659370183944702, + -0.06124546006321907, + -0.9422666430473328 ] ], [ [ - 0.7723278403282166, - 0.22671592235565186, - -0.3837747573852539, - -0.7681311964988708, - 1.8044092655181885 + 1.4318883419036865, + 0.13153165578842163, + -0.18222470581531525, + 0.3660371005535126, + 0.5798347592353821 ], [ - 1.4646685123443604, - 0.2913444936275482, - -1.1624996662139893, - -0.4783642590045929, - 1.3870203495025635 + 0.2429470419883728, + -1.2091906070709229, + 0.07767737656831741, + 0.17619068920612335, + 0.578863799571991 ], [ - -0.4341133236885071, - 0.2929425835609436, - -1.144444465637207, - -1.1233654022216797, - -0.7945832014083862 + 1.5511679649353027, + 0.08444352447986603, + 1.2101210355758667, + -0.8561125993728638, + -0.01396828331053257 ], [ - -0.5694751739501953, - 0.0549420528113842, - -0.7646363377571106, - -1.0492900609970093, - 1.0828652381896973 + -0.2777872681617737, + -0.7856798768043518, + 0.46062397956848145, + 0.566218376159668, + 1.1541569232940674 ] ], [ [ - -0.0699654296040535, - 0.4944293797016144, - 2.1871159076690674, - 1.1617707014083862, - -0.9024235010147095 + -0.4426518380641937, + 1.2387607097625732, + -1.0242971181869507, + 0.7994512319564819, + 0.2551962435245514 ], [ - -2.41979718208313, - 0.7134581804275513, - -1.9506268501281738, - -0.6031076312065125, - -0.7942026853561401 + -1.102837324142456, + 0.8238721489906311, + 0.0035749999806284904, + -1.7263970375061035, + 0.23050972819328308 ], [ - 0.023615580052137375, - -0.7165514230728149, - 1.0070719718933105, - -0.12568299472332, - 0.2154434323310852 + -0.006388451438397169, + -0.3764995038509369, + -0.12150754034519196, + 0.41562098264694214, + 1.0095174312591553 ], [ - -1.2841796875, - 2.2291040420532227, - 0.8249357342720032, - 0.4553866684436798, - 0.5599141120910645 + 0.6818063259124756, + -0.7300068736076355, + -0.8303658366203308, + -0.9434769749641418, + 2.028413772583008 ] ] ], - "expected_output": 0.03159071132540703, + "expected_output": 0.15700183808803558, "expected_grad": [ [ [ @@ -7554,123 +8499,123 @@ export const testData = { "input": [ [ [ - 0.20383627712726593, - -0.7248139977455139, - 0.2881997525691986, - 1.6998308897018433, - 2.432499408721924 + 0.1755259782075882, + 0.29882222414016724, + -0.6017733812332153, + 1.1090705394744873, + -0.26971787214279175 ], [ - 0.2585121691226959, - 1.3330131769180298, - 0.12649448215961456, - 0.17614391446113586, - 0.10091600567102432 + -0.4379420578479767, + -1.0124340057373047, + -0.14667245745658875, + 0.15679313242435455, + 0.19906163215637207 ], [ - 1.2233283519744873, - 0.791765034198761, - 0.5074418187141418, - 0.4391697347164154, - -0.8357943892478943 + 0.6868006587028503, + -0.4260328412055969, + -0.7560138702392578, + 0.17112013697624207, + -0.7641999125480652 ], [ - -0.6900646686553955, - 0.47324633598327637, - 0.22348645329475403, - 0.41359904408454895, - -0.5239112377166748 + -0.44291654229164124, + 1.180337905883789, + 0.37527406215667725, + 0.16405928134918213, + -0.5820143818855286 ] ], [ [ - 0.13422854244709015, - -1.1245696544647217, - 1.3094075918197632, - -0.07285541296005249, - -0.70379638671875 + -0.6077602505683899, + -0.20455589890480042, + 0.5790372490882874, + -0.19989891350269318, + -0.06916097551584244 ], [ - 0.558134913444519, - 0.2722645699977875, - -0.428587943315506, - 0.8239985108375549, - -1.3989880084991455 + -0.2501976788043976, + -0.631926953792572, + -0.10361812263727188, + 0.9832454323768616, + -0.21117885410785675 ], [ - -0.6815629601478577, - 0.8538435697555542, - -0.5384427905082703, - -0.6699069142341614, - 0.23984402418136597 + 0.8466978073120117, + 0.8503185510635376, + -1.003414511680603, + -0.9655314683914185, + 0.21109014749526978 ], [ - 2.1043002605438232, - -0.7700114250183105, - -1.5130436420440674, - -0.403571754693985, - -0.442477822303772 + -1.413875699043274, + 0.8920503854751587, + -0.30397742986679077, + -0.05114508792757988, + -0.6013848185539246 ] ], [ [ - -0.19414693117141724, - -1.3718643188476562, - -0.2043316662311554, - -1.1885942220687866, - -1.4498616456985474 + 0.11547855287790298, + -0.17881472408771515, + -0.09405016899108887, + -0.6329993009567261, + -1.0465848445892334 ], [ - 0.1425102800130844, - 0.3205632269382477, - -0.585231602191925, - 0.4060876965522766, - 0.2572997212409973 + 1.3759163618087769, + 0.05762922391295433, + 0.35209375619888306, + 1.0967378616333008, + -0.9882838726043701 ], [ - 0.8778835535049438, - 0.7318398952484131, - 0.3467099368572235, - -0.08159374445676804, - -1.4703203439712524 + 1.9996482133865356, + -1.2997536659240723, + -0.7523331046104431, + -0.47686854004859924, + 1.2204824686050415 ], [ - -0.3415772616863251, - 1.2259759902954102, - 1.8914309740066528, - -0.6524525284767151, - -0.8879274725914001 + -0.15345095098018646, + -0.5119454264640808, + 0.11924147605895996, + 1.428880214691162, + 2.0869503021240234 ] ] ], "expected_output": [ [ - 0.047972630709409714, - -1.073749303817749, - 0.4644252359867096, - 0.1461271047592163, - 0.09294712543487549 + -0.1055852472782135, + -0.028182798996567726, + -0.038928765803575516, + 0.09205744415521622, + -0.46182122826576233 ], [ - 0.3197191059589386, - 0.6419469714164734, - -0.29577502608299255, - 0.4687434136867523, - -0.3469240665435791 + 0.22925888001918793, + -0.5289105772972107, + 0.033934395760297775, + 0.7455921173095703, + -0.333467036485672 ], [ - 0.47321629524230957, - 0.792482852935791, - 0.10523632168769836, - -0.10411030799150467, - -0.6887569427490234 + 1.1777156591415405, + -0.2918226420879364, + -0.8372538089752197, + -0.42375993728637695, + 0.22245757281780243 ], [ - 0.35755276679992676, - 0.309736967086792, - 0.20062458515167236, - -0.21414174139499664, - -0.6181054711341858 + -0.6700810790061951, + 0.5201475620269775, + 0.06351270526647568, + 0.5139314532279968, + 0.30118370056152344 ] ], "expected_grad": [ @@ -7774,124 +8719,124 @@ export const testData = { "input": [ [ [ - 1.7347886562347412, - 0.032030463218688965, - 0.9726912379264832, - 1.0879974365234375, - -1.1082324981689453 + 0.9313072562217712, + 0.11275313794612885, + -0.29632923007011414, + 0.6281623244285583, + 0.797209620475769 ], [ - 2.1468100547790527, - -0.20463405549526215, - -0.1949448138475418, - -0.3272537291049957, - 0.48203662037849426 + 0.6957338452339172, + -0.18519674241542816, + 0.19908924400806427, + 0.21209175884723663, + 1.1861251592636108 ], [ - -1.8594290018081665, - 0.14130207896232605, - 1.6815085411071777, - 0.9141939282417297, - 1.2556324005126953 + -0.08824097365140915, + -1.1839087009429932, + -0.23501551151275635, + 0.6680712103843689, + -0.7205530405044556 ], [ - -0.8077448010444641, - 0.19963520765304565, - -0.19339345395565033, - -1.219641089439392, - 1.0411797761917114 + 0.9816026091575623, + -0.15770527720451355, + 0.5783246755599976, + 0.5183308720588684, + 0.10639314353466034 ] ], [ [ - -0.10632240027189255, - 0.07336213439702988, - 0.4191838204860687, - -0.8154667019844055, - -0.5155897736549377 + -0.0708099901676178, + 0.1868356168270111, + -1.135615348815918, + -0.6121562123298645, + 0.4646506905555725 ], [ - 0.32028329372406006, - 1.5522725582122803, - 1.3522603511810303, - 1.1632877588272095, - -0.5602036714553833 + 0.9826740026473999, + 0.4591689705848694, + 0.3639809787273407, + 0.24808230996131897, + -0.5714194178581238 ], [ - -0.8605437278747559, - -0.400406152009964, - 0.5620190501213074, - -2.7735390663146973, - 1.15679931640625 + -1.8829892873764038, + 1.6257703304290771, + 1.1227099895477295, + -0.24534782767295837, + 0.42072793841362 ], [ - -0.2487672120332718, - -0.10994483530521393, - -0.4232594072818756, - 1.6037938594818115, - 0.7152358293533325 + 1.2927830219268799, + -0.062042392790317535, + -0.07447009533643723, + 1.8144526481628418, + 0.4126001298427582 ] ], [ [ - -0.6582046151161194, - 0.395238995552063, - -0.6984677910804749, - 0.8194941282272339, - -2.815762519836426 + 1.5678290128707886, + -0.5997704267501831, + 0.13211850821971893, + -0.4554636776447296, + -0.32575365900993347 ], [ - -0.28375279903411865, - 1.9665663242340088, - 0.4404697120189667, - -0.5943435430526733, - 0.7206440567970276 + 2.110002040863037, + -0.5582384467124939, + 0.3878994286060333, + -2.2768142223358154, + 0.37306782603263855 ], [ - -1.0877529382705688, - -0.19153426587581635, - -0.6546841263771057, - 1.0335131883621216, - -0.31327491998672485 + -0.9947562217712402, + -1.3262041807174683, + -0.599851667881012, + 0.17797666788101196, + -1.143309235572815 ], [ - -0.18328620493412018, - -0.17836901545524597, - 2.0791051387786865, - 0.1488768607378006, - 3.190993547439575 + 1.3394620418548584, + -0.996752142906189, + -0.6021904945373535, + 0.32188680768013, + 0.1322384774684906 ] ] ], "expected_output": [ [ [ - 0.32342055439949036, - 0.16687719523906708, - 0.23113574087619781, - 0.3640082776546478, - -1.4798616170883179 + 0.8094420433044434, + -0.10006055980920792, + -0.43327537178993225, + -0.1464858502149582, + 0.31203556060791016 ], [ - 0.7277801632881165, - 1.1047348976135254, - 0.5325950980186462, - 0.0805635079741478, - 0.2141590118408203 + 1.262803316116333, + -0.09475541114807129, + 0.3169898986816406, + -0.6055467128753662, + 0.3292578458786011 ], [ - -1.2692418098449707, - -0.15021277964115143, - 0.5296145081520081, - -0.27527734637260437, - 0.6997189521789551 + -0.9886621832847595, + -0.2947808504104614, + 0.09594760090112686, + 0.2002333402633667, + -0.4810447692871094 ], [ - -0.41326606273651123, - -0.0295595470815897, - 0.4874840974807739, - 0.17767654359340668, - 1.6491364240646362 + 1.2046159505844116, + -0.4054999351501465, + -0.03277863934636116, + 0.884890079498291, + 0.21707725524902344 ] ] ], @@ -7996,116 +8941,116 @@ export const testData = { "input": [ [ [ - 0.7202309370040894, - 0.8769089579582214, - -0.8568285703659058, - -1.469225525856018, - 0.9260697960853577 + 0.27381452918052673, + 1.7188366651535034, + 1.3450311422348022, + -1.2653104066848755, + 0.45117413997650146 ], [ - -0.5594438910484314, - 2.2181360721588135, - 0.4000236988067627, - 1.8645329475402832, - -0.8439115881919861 + 0.6597211360931396, + -2.012479305267334, + -0.516261100769043, + -1.0803741216659546, + 1.424518346786499 ], [ - -1.0606149435043335, - 1.045390248298645, - 1.1547093391418457, - 0.3212544322013855, - 0.1364518105983734 + -1.1213253736495972, + 0.3918372392654419, + -0.49036842584609985, + -0.2890629470348358, + -0.7217605710029602 ], [ - -1.7697168588638306, - -0.4297706186771393, - -0.9330264925956726, - 0.03445770964026451, - 0.5089080333709717 + 1.9135220050811768, + 1.668276309967041, + 0.674127995967865, + 1.1708104610443115, + 0.02161409705877304 ] ], [ [ - 0.6470111608505249, - -0.5019861459732056, - -0.14353430271148682, - -1.2236298322677612, - -1.9437434673309326 + -0.9156265258789062, + 0.21846671402454376, + -0.5406830906867981, + -0.8299271464347839, + 2.0619850158691406 ], [ - 0.09865526109933853, - 2.5731418132781982, - -0.7051668167114258, - -1.1590256690979004, - -0.2769569158554077 + 0.3048802316188812, + -1.4610782861709595, + -0.20266015827655792, + 0.03146770969033241, + 0.2910449504852295 ], [ - 1.1326403617858887, - -0.961678147315979, - 0.07773400843143463, - 1.8036106824874878, - -1.3065544366836548 + 0.5939645171165466, + 1.3427438735961914, + -0.6950612664222717, + 0.8987486362457275, + -0.763476550579071 ], [ - 1.1060339212417603, - 0.921552836894989, - -1.3966097831726074, - -0.888012707233429, - -2.21113920211792 + -0.19663105905056, + -0.3633078634738922, + -1.5530608892440796, + -0.15105754137039185, + -0.5337246656417847 ] ], [ [ - -1.1771180629730225, - 1.7409440279006958, - 4.6923309128033e-05, - 0.5687845945358276, - -0.8220173120498657 + 1.6809849739074707, + -0.11213088780641556, + -0.5451535582542419, + 0.5253366231918335, + 0.5843788981437683 ], [ - 0.7975156307220459, - -0.7685240507125854, - 1.5375657081604004, - -1.7771120071411133, - -1.0646121501922607 + -2.286334276199341, + 0.5851041674613953, + 1.2774115800857544, + 0.8801257610321045, + 0.5200220942497253 ], [ - -0.42104366421699524, - -0.6636930704116821, - -1.5027097463607788, - -1.0865437984466553, - 2.1495704650878906 + -1.0255969762802124, + 1.7627143859863281, + -0.0564274862408638, + 0.9568160176277161, + -0.6867133378982544 ], [ - -0.9262224435806274, - -0.8617974519729614, - -0.013285640627145767, - -0.051826003938913345, - 0.41152408719062805 + 1.02428138256073, + 1.7308460474014282, + -0.32468941807746887, + 0.3143851161003113, + -0.0669134333729744 ] ] ], "expected_output": [ [ - -0.6673861742019653, - 0.9276661276817322, - -0.05878050625324249, - 0.18775488436222076, - 0.18187952041625977 + 0.4314330816268921, + 0.4416177272796631, + 0.2531324028968811, + -0.3659842610359192, + 0.2938864827156067 ], [ - 0.7460851669311523, - 0.5077575445175171, - -0.5418941974639893, - -0.3667644262313843, - -1.434598445892334 + -0.053353201597929, + -0.06579387933015823, + -0.7478663921356201, + -0.012692078948020935, + 0.2639571726322174 ], [ - -0.4317171275615692, - -0.1382676362991333, - 0.005404322408139706, - -0.5866743326187134, - 0.16861626505851746 + -0.15166622400283813, + 0.991633415222168, + 0.0877852812409401, + 0.6691659092903137, + 0.08769355714321136 ] ], "expected_grad": [ @@ -8209,121 +9154,121 @@ export const testData = { "input": [ [ [ - -2.168846368789673, - 1.213675856590271, - -1.8085858821868896, - 0.19425715506076813, - 0.6679531335830688 + 0.8160833120346069, + -0.8233374357223511, + -2.1418421268463135, + 0.7724379897117615, + -0.6358500719070435 ], [ - -1.1588698625564575, - 0.8675621151924133, - 1.5683906078338623, - -1.4785282611846924, - 0.045808374881744385 + 0.2520127594470978, + 0.9832903742790222, + 0.27252840995788574, + -0.9334322810173035, + -0.120673269033432 ], [ - -0.10694064944982529, - 0.35308536887168884, - 0.3301672339439392, - -0.5309102535247803, - 1.9589688777923584 + -1.6670103073120117, + -2.2226719856262207, + -1.0847980976104736, + 0.612401008605957, + -0.5785004496574402 ], [ - -0.46830111742019653, - -0.16547387838363647, - -0.3069077730178833, - 1.4188532829284668, - -0.4566229581832886 + -0.725740909576416, + 0.42209234833717346, + -1.268004298210144, + 1.395574688911438, + -0.4016047418117523 ] ], [ [ - -1.5976078510284424, - 0.7735506892204285, - -0.0893024280667305, - -2.8384506702423096, - 0.7005379796028137 + -0.47602152824401855, + 0.6024074554443359, + -0.13895398378372192, + -0.5199072957038879, + -0.49655959010124207 ], [ - 1.4387873411178589, - -1.0684497356414795, - -0.16634242236614227, - 0.517611563205719, - -0.7325262427330017 + 1.612599492073059, + -0.3255579173564911, + 0.9303890466690063, + -0.2840443551540375, + 0.8463886380195618 ], [ - 1.6848194599151611, - 0.4438650906085968, - 0.056602153927087784, - -1.5038570165634155, - -0.4485261142253876 + 0.018565375357866287, + -1.6755516529083252, + -1.5852235555648804, + 1.1069889068603516, + -0.6744462847709656 ], [ - 0.5257315635681152, - 0.2619018256664276, - 0.7167068123817444, - -1.2776819467544556, - 0.4211602210998535 + -1.8892930746078491, + -1.842443585395813, + 0.13227719068527222, + -0.792870283126831, + 1.2297093868255615 ] ], [ [ - 1.9249420166015625, - -0.3405316174030304, - -0.43293496966362, - 1.3083903789520264, - 0.6581417322158813 + -0.013317405246198177, + -0.30806609988212585, + -0.3388381898403168, + -0.46696820855140686, + 0.14354214072227478 ], [ - 1.5086971521377563, - 0.40693262219429016, - 0.4082213044166565, - -0.4960733652114868, - -0.9290968179702759 + -0.9078568816184998, + 2.190314531326294, + 0.2566744089126587, + 0.4625372588634491, + -1.1410428285598755 ], [ - -0.1992855966091156, - 0.468250036239624, - -0.9421932697296143, - 1.3477203845977783, - -0.08609210699796677 + 1.7502615451812744, + -0.11171314865350723, + -1.1738200187683105, + -0.6320435404777527, + -1.0962568521499634 ], [ - 0.60735023021698, - 0.227834552526474, - -0.6186387538909912, - 1.1308897733688354, - -0.12078773975372314 + -0.7847272753715515, + -0.5752313137054443, + 0.5138634443283081, + 1.050782322883606, + 1.3841030597686768 ] ] ], "expected_output": [ [ [ - -0.9757395386695862, - 0.5672123432159424, - -0.05423395335674286, - -0.09908202290534973, - 0.5540268421173096 + -0.33116379380226135, + -0.4101566970348358, + -1.055528998374939, + 0.46174535155296326, + -0.4341571629047394 ] ], [ [ - 0.5129326581954956, - 0.10271696746349335, - 0.12941601872444153, - -1.2755944728851318, - -0.014838539063930511 + -0.18353742361068726, + -0.8102864027023315, + -0.16537782549858093, + -0.12245824933052063, + 0.22627303004264832 ] ], [ [ - 0.9604259729385376, - 0.19062140583992004, - -0.39638641476631165, - 0.8227318525314331, - -0.11945873498916626 + 0.011089995503425598, + 0.2988259792327881, + -0.18553009629249573, + 0.10357695817947388, + -0.17741364240646362 ] ] ], @@ -8428,113 +9373,113 @@ export const testData = { "input": [ [ [ - 0.5786823630332947, - -1.099729299545288, - 0.2812545895576477, - 0.08700139075517654, - -0.25706610083580017 + 1.459913969039917, + -1.9324012994766235, + 0.295070618391037, + 1.953094482421875, + 0.062261566519737244 ], [ - 2.2180261611938477, - 1.240154504776001, - -0.6573424935340881, - -0.05131905525922775, - -0.26267147064208984 + -1.1078839302062988, + 0.976121723651886, + -0.07730520516633987, + -0.29665258526802063, + -0.26533499360084534 ], [ - -0.45390239357948303, - 1.4244478940963745, - 2.269195318222046, - 1.3104835748672485, - -0.3178943395614624 + -0.79975426197052, + 1.0418704748153687, + 1.3010565042495728, + -0.40846967697143555, + -0.7162472605705261 ], [ - -0.3773656487464905, - -0.45319506525993347, - 1.2440320253372192, - -0.7194162011146545, - 1.2199066877365112 + -1.0271012783050537, + 0.1834021359682083, + -0.05814415216445923, + 0.3220038414001465, + 0.4668942093849182 ] ], [ [ - 1.435631513595581, - -0.31398269534111023, - 0.8979019522666931, - 0.6358874440193176, - -0.31363436579704285 + 0.014412929303944111, + -1.1832906007766724, + 0.03632983937859535, + 2.4672696590423584, + 1.3323793411254883 ], [ - 0.13522106409072876, - -0.39359593391418457, - -0.02484050951898098, - -0.3632628321647644, - -0.6941221952438354 + -0.09307997673749924, + -1.1491583585739136, + 0.39312395453453064, + -0.3892734944820404, + 0.5293436646461487 ], [ - -0.9816297292709351, - -0.05556102097034454, - -0.6147816777229309, - 1.4754621982574463, - -0.5717736482620239 + -0.6360014081001282, + -0.2509534955024719, + 0.4555503726005554, + -0.27460846304893494, + 0.9494737386703491 ], [ - -1.5560880899429321, - -0.9632699489593506, - -0.4366423487663269, - -0.008548072539269924, - 0.04459971562027931 + -0.8720837235450745, + 0.8029743432998657, + 0.27744394540786743, + 0.33585336804389954, + -0.7603669166564941 ] ], [ [ - -1.2941125631332397, - 0.14418895542621613, - -1.1567072868347168, - 1.8155642747879028, - 0.05806141346693039 + -0.6846820712089539, + -0.7688948512077332, + 1.9104690551757812, + -0.9281872510910034, + -0.49309614300727844 ], [ - -1.070618987083435, - 0.8081686496734619, - -1.5791850090026855, - 0.6206215023994446, - -1.152881145477295 + 0.50408536195755, + 0.998515248298645, + 0.0367455929517746, + 0.2297750562429428, + -1.984581470489502 ], [ - 2.2968475818634033, - 1.649484395980835, - -0.2084096521139145, - 1.9412633180618286, - -0.18736235797405243 + -1.2512000799179077, + 0.6219334602355957, + 0.051693860441446304, + -0.5315346121788025, + 0.5726004242897034 ], [ - -1.7039966583251953, - -2.115445852279663, - 0.9916136860847473, - -2.7026309967041016, - -0.6108700037002563 + 0.3863498866558075, + 0.27223649621009827, + 0.46132177114486694, + 0.13579803705215454, + 0.516796886920929 ] ] ], "expected_output": [ [ - -0.08197140693664551, - 0.49736952781677246, - 0.8464659452438354, - 0.18279236555099487 + 0.3675878643989563, + -0.15421099960803986, + 0.08369116485118866, + -0.022589052096009254 ], [ - 0.4683607518672943, - -0.2681201100349426, - -0.1496567726135254, - -0.5839897394180298 + 0.533420205116272, + -0.14180883765220642, + 0.04869214817881584, + -0.04323578625917435 ], [ - -0.08660104125738144, - -0.47477903962135315, - 1.0983645915985107, - -1.2282660007476807 + -0.19287827610969543, + -0.04309204965829849, + -0.10730139166116714, + 0.35450059175491333 ] ], "expected_grad": [ @@ -8638,136 +9583,136 @@ export const testData = { "input": [ [ [ - 0.00420670909807086, - -1.4650157690048218, - 0.6085794568061829, - -0.07576155662536621, - -0.4139658212661743 + 1.0863715410232544, + -0.48916497826576233, + 1.751997470855713, + -0.3743889033794403, + 0.9508031606674194 ], [ - -1.3813194036483765, - -0.07809803634881973, - -0.3723330795764923, - 0.4985557794570923, - -1.633231520652771 + 1.3071852922439575, + -0.7512642741203308, + 0.005139758810400963, + 1.6046744585037231, + 0.08605138957500458 ], [ - 0.03490933030843735, - 0.5769792199134827, - -0.009515623562037945, - -0.4003794491291046, - 0.5099198222160339 + 1.9344228506088257, + -0.44564706087112427, + -0.47476428747177124, + -0.30261677503585815, + -0.29394063353538513 ], [ - -0.7801733613014221, - 0.5647550821304321, - 0.30276739597320557, - -0.15120232105255127, - -0.47413021326065063 + 2.5355067253112793, + 1.848445177078247, + -1.1966158151626587, + -0.4228180944919586, + -0.7322655916213989 ] ], [ [ - 0.6317481994628906, - -0.22863811254501343, - -0.38931718468666077, - 1.4754453897476196, - 0.23239462077617645 + -0.3979387581348419, + -0.004983691032975912, + -2.165992498397827, + 0.5304996371269226, + 2.260444164276123 ], [ - -0.26003894209861755, - 1.0476551055908203, - 0.545058012008667, - 1.7255419492721558, - 0.5405985116958618 + -0.3309515118598938, + 1.8614799976348877, + -0.11587686836719513, + -0.6822512745857239, + 0.4212978780269623 ], [ - 1.0360978841781616, - 0.5318379998207092, - 1.2613322734832764, - 0.8772295713424683, - -2.291107416152954 + -1.3226412534713745, + 1.2114580869674683, + -0.8475749492645264, + -0.09313177317380905, + -1.2082672119140625 ], [ - 1.8939599990844727, - -2.3213963508605957, - -0.6423410773277283, - 1.5522570610046387, - -2.3087081909179688 + 3.168529987335205, + 2.297508955001831, + -0.14129851758480072, + -1.9953597784042358, + 0.035315316170454025 ] ], [ [ - -0.7946994304656982, - 0.7812591195106506, - 1.9472111463546753, - 0.21231839060783386, - 0.1915358453989029 + -1.0469098091125488, + -0.16152557730674744, + -0.5230178833007812, + -1.1935372352600098, + 1.8063979148864746 ], [ - 0.16352267563343048, - 0.3051132261753082, - 0.7242569923400879, - -0.08786772191524506, - -1.1320451498031616 + 0.9378061294555664, + -0.38452786207199097, + 0.658501386642456, + 0.7616772055625916, + -0.6450856328010559 ], [ - 0.2265060991048813, - 0.5291025042533875, - -1.4391361474990845, - 1.6620672941207886, - 0.14816075563430786 + 1.6012887954711914, + 0.35755881667137146, + 0.26440107822418213, + -0.5598823428153992, + 1.4536970853805542 ], [ - -1.129300832748413, - 1.3774371147155762, - -0.16838155686855316, - -2.7773499488830566, - 0.3025462329387665 + -0.2962888479232788, + -0.4702155888080597, + -1.499106526374817, + -0.01866411603987217, + -1.5055760145187378 ] ] ], "expected_output": [ [ [ - -0.2683914303779602 + 0.5851236581802368 ], [ - -0.5932852625846863 + 0.4503573477268219 ], [ - 0.1423826515674591 + 0.08349082618951797 ], [ - -0.10759668052196503 + 0.40645045042037964 ] ], [ [ - 0.34432658553123474 + 0.04440578073263168 ], [ - 0.719762921333313 + 0.23073963820934296 ], [ - 0.28307804465293884 + -0.4520314633846283 ], [ - -0.3652457296848297 + 0.6729391813278198 ] ], [ [ - 0.46752500534057617 + -0.223718523979187 ], [ - -0.005403992719948292 + 0.26567426323890686 ], [ - 0.2253400981426239 + 0.6234126687049866 ], [ - -0.47900980710983276 + -0.7579702138900757 ] ] ], @@ -8872,96 +9817,96 @@ export const testData = { "input": [ [ [ - 0.3821605145931244, - -0.19578158855438232, - -2.0732667446136475, - 0.6599233150482178, - 1.7670403718948364 + 1.3179066181182861, + 0.7556464672088623, + 1.2471561431884766, + 0.7881364822387695, + 1.5493229627609253 ], [ - -1.169783353805542, - -0.1317385584115982, - -0.6004424095153809, - -0.05841507390141487, - -1.4766151905059814 + -0.6088662147521973, + 1.4112409353256226, + -0.9075624346733093, + 1.1897660493850708, + -0.4802001118659973 ], [ - -1.0946006774902344, - -0.8658109307289124, - 0.8367514610290527, - -0.9400964975357056, - 1.4285417795181274 + 2.2536263465881348, + 1.1717573404312134, + 0.8793008327484131, + -0.7796709537506104, + 1.4039242267608643 ], [ - 0.1983281522989273, - 1.4749457836151123, - -1.4756296873092651, - 0.8483810424804688, - -0.09390979260206223 + 2.2192718982696533, + 0.36377331614494324, + 1.2563191652297974, + -0.1220834031701088, + 0.10120877623558044 ] ], [ [ - -0.13151048123836517, - -0.035332635045051575, - 0.004686277825385332, - 0.15220017731189728, - -0.06878392398357391 + 0.47121289372444153, + 0.6840168237686157, + -0.7728962898254395, + -0.3962509334087372, + 0.6629142165184021 ], [ - -0.6154842972755432, - 1.0898313522338867, - -0.4806813597679138, - -0.630047082901001, - 1.1917531490325928 + 0.6556671857833862, + 0.058465536683797836, + 0.7882350087165833, + -1.0857888460159302, + 1.0519514083862305 ], [ - -1.0328683853149414, - 0.38320526480674744, - -1.2028323411941528, - -2.4587764739990234, - -0.5534238815307617 + 0.2087085098028183, + -1.4547972679138184, + -0.17086558043956757, + -2.0883853435516357, + 0.7963455319404602 ], [ - 0.3374936878681183, - 0.9784513115882874, - 1.1227375268936157, - 0.5851324796676636, - 1.3817517757415771 + 0.4962165355682373, + 0.6029451489448547, + -0.5226418375968933, + 0.06845283508300781, + 0.3298587203025818 ] ], [ [ - 0.8889638781547546, - -1.1525547504425049, - 1.7995572090148926, - 1.6228371858596802, - 1.9551998376846313 + -0.31479185819625854, + 0.02101830020546913, + -0.054547298699617386, + -0.8116031885147095, + -0.441931813955307 ], [ - -0.06532658636569977, - 0.14630116522312164, - 1.1357200145721436, - -0.2688539922237396, - -0.9126741886138916 + 0.01032029278576374, + 1.8312735557556152, + -0.6159215569496155, + -0.6072822213172913, + -2.05973744392395 ], [ - -1.0687869787216187, - 0.38017958402633667, - 1.013214111328125, - -1.1486494541168213, - -0.7915613055229187 + 1.5289140939712524, + 0.3378683924674988, + -0.6198564171791077, + -0.7939390540122986, + 0.6710167527198792 ], [ - -0.3213580846786499, - 0.5456286668777466, - -1.2671267986297607, - -0.12716197967529297, - 0.8282967209815979 + -0.4096096158027649, + -0.530225396156311, + 0.2532861530780792, + -0.19900000095367432, + 0.6101416945457458 ] ] ], - "expected_output": 1.9551998376846313, + "expected_output": 2.2536263465881348, "expected_grad": [ [ [ @@ -8979,7 +9924,7 @@ export const testData = { 0.0 ], [ - 0.0, + 1.0, 0.0, 0.0, 0.0, @@ -9029,7 +9974,7 @@ export const testData = { 0.0, 0.0, 0.0, - 1.0 + 0.0 ], [ 0.0, @@ -9063,180 +10008,180 @@ export const testData = { "input": [ [ [ - -0.13801060616970062, - 0.09937097132205963, - -0.16284485161304474, - 0.18977606296539307, - -1.2571945190429688 + 1.5443801879882812, + -0.35117071866989136, + 0.35557520389556885, + -1.8119957447052002, + 0.46456536650657654 ], [ - 0.25705486536026, - 1.104391098022461, - 1.1175512075424194, - -0.6293240189552307, - -1.676796793937683 + -0.5480050444602966, + -1.0596239566802979, + 0.17400647699832916, + 0.7506431937217712, + -0.6409745812416077 ], [ - 0.6724022030830383, - 1.988852858543396, - 0.8156912922859192, - -1.4682725667953491, - -1.521799087524414 + -0.15132363140583038, + 0.625577986240387, + -0.6219039559364319, + -1.087321400642395, + -1.3252078294754028 ], [ - -1.2172812223434448, - -0.23146040737628937, - 0.5549997091293335, - 0.32450324296951294, - 1.4936802387237549 + 0.37722504138946533, + -1.4066274166107178, + -0.2883475422859192, + -0.9860185384750366, + 1.4865750074386597 ] ], [ [ - 0.5853366255760193, - 0.7599589824676514, - 1.7872188091278076, - -1.3676286935806274, - 0.8856539726257324 + 0.14713206887245178, + -1.366032361984253, + -0.6708536148071289, + 0.9521092176437378, + -2.338611602783203 ], [ - 0.9161636829376221, - 0.4850791096687317, - -1.0356383323669434, - 0.1620996594429016, - -0.34564009308815 + -1.59005606174469, + -0.8660301566123962, + 1.278135895729065, + 0.35259687900543213, + -0.07500791549682617 ], [ - -1.2987875938415527, - -0.2696373760700226, - 0.6803566813468933, - -0.12983323633670807, - 0.09731336683034897 + 0.40587425231933594, + 0.5351168513298035, + -1.4525551795959473, + 1.2706263065338135, + 0.2695809602737427 ], [ - 0.7956935167312622, - -2.1607372760772705, - -0.5694004893302917, - -1.2072747945785522, - 0.7853367924690247 + -0.031602293252944946, + -1.2756946086883545, + -0.6372569799423218, + -0.761553168296814, + -0.4670298099517822 ] ], [ [ - 0.8770406246185303, - -2.0921499729156494, - 1.5937228202819824, - 2.563725471496582, - -0.2689884901046753 + -2.774542808532715, + -0.20163610577583313, + -0.489888072013855, + -1.5937029123306274, + 0.7888379693031311 ], [ - 0.13259819149971008, - 0.4738202393054962, - 0.031055578961968422, - -0.1489359736442566, - -0.3652037978172302 + -0.9375290870666504, + -0.14468862116336823, + -0.974236011505127, + 0.6229617595672607, + -0.34589967131614685 ], [ - -1.8156386613845825, - 1.1129406690597534, - -0.09201753884553909, - -0.981147050857544, - 1.0239890813827515 + -1.7239394187927246, + -0.9909027814865112, + -0.49027347564697266, + 0.09400757402181625, + 0.8530552983283997 ], [ - -1.036582350730896, - -1.997800350189209, - 1.5087897777557373, - 0.19652637839317322, - 1.0685486793518066 + -0.01044454239308834, + 1.114724040031433, + -1.1784462928771973, + 0.6866339445114136, + 1.5644149780273438 ] ] ], "expected_output": [ [ - 0.8770406246185303, - 0.7599589824676514, - 1.7872188091278076, - 2.563725471496582, - 0.8856539726257324 + 1.5443801879882812, + -0.20163610577583313, + 0.35557520389556885, + 0.9521092176437378, + 0.7888379693031311 ], [ - 0.9161636829376221, - 1.104391098022461, - 1.1175512075424194, - 0.1620996594429016, - -0.34564009308815 + -0.5480050444602966, + -0.14468862116336823, + 1.278135895729065, + 0.7506431937217712, + -0.07500791549682617 ], [ - 0.6724022030830383, - 1.988852858543396, - 0.8156912922859192, - -0.12983323633670807, - 1.0239890813827515 + 0.40587425231933594, + 0.625577986240387, + -0.49027347564697266, + 1.2706263065338135, + 0.8530552983283997 ], [ - 0.7956935167312622, - -0.23146040737628937, - 1.5087897777557373, - 0.32450324296951294, - 1.4936802387237549 + 0.37722504138946533, + 1.114724040031433, + -0.2883475422859192, + 0.6866339445114136, + 1.5644149780273438 ] ], "expected_grad": [ [ [ + 1.0, 0.0, - 0.0, - 0.0, + 1.0, 0.0, 0.0 ], [ - 0.0, - 1.0, 1.0, 0.0, + 0.0, + 1.0, 0.0 ], [ + 0.0, 1.0, - 1.0, - 1.0, + 0.0, 0.0, 0.0 ], [ - 0.0, 1.0, 0.0, 1.0, - 1.0 + 0.0, + 0.0 ] ], [ [ 0.0, - 1.0, - 1.0, 0.0, - 1.0 + 0.0, + 1.0, + 0.0 ], [ - 1.0, 0.0, 0.0, 1.0, + 0.0, 1.0 ], [ - 0.0, + 1.0, 0.0, 0.0, 1.0, 0.0 ], [ - 1.0, + 0.0, 0.0, 0.0, 0.0, @@ -9245,15 +10190,15 @@ export const testData = { ], [ [ + 0.0, 1.0, 0.0, 0.0, - 1.0, - 0.0 + 1.0 ], [ 0.0, - 0.0, + 1.0, 0.0, 0.0, 0.0 @@ -9261,16 +10206,16 @@ export const testData = { [ 0.0, 0.0, - 0.0, + 1.0, 0.0, 1.0 ], [ - 0.0, 0.0, 1.0, 0.0, - 0.0 + 1.0, + 1.0 ] ] ] @@ -9283,216 +10228,216 @@ export const testData = { "input": [ [ [ - 0.3579265773296356, - -1.0362085103988647, - 1.0006709098815918, - 0.7048721313476562, - -0.6978404521942139 + 0.15242499113082886, + 0.06238764151930809, + 0.4020906984806061, + 1.6428531408309937, + -0.4024767577648163 ], [ - 0.4728609323501587, - -0.6566532254219055, - -0.8678151965141296, - 0.0302385576069355, - -0.5570979714393616 + -0.6926602125167847, + 0.5779818296432495, + -0.02104124240577221, + 0.3675006031990051, + -1.6424492597579956 ], [ - -0.8829219937324524, - -0.7062578201293945, - -1.2799997329711914, - 0.13592901825904846, - -0.28107115626335144 + 1.6906514167785645, + -1.885027527809143, + -0.7859907150268555, + -1.2742111682891846, + -1.0625808238983154 ], [ - 1.7253460884094238, - -0.7556604743003845, - 2.0246987342834473, - -0.6380594372749329, - 0.5336771607398987 + -0.632580041885376, + -0.8688688278198242, + -1.5556751489639282, + 0.4562793970108032, + 0.26206839084625244 ] ], [ [ - 0.1680675745010376, - -1.0805774927139282, - 0.8652670383453369, - 0.9823195338249207, - -0.5655248165130615 + 0.5024110674858093, + -0.4759514033794403, + 1.6630321741104126, + -1.454459547996521, + 1.3266892433166504 ], [ - 0.43977639079093933, - -0.6277503967285156, - -0.14591790735721588, - -0.42359691858291626, - -1.4881683588027954 + 0.6551998853683472, + 0.6860383749008179, + -0.6831625699996948, + 0.8929892778396606, + 1.6672981977462769 ], [ - 0.8582064509391785, - 3.035121202468872, - 1.7607189416885376, - -0.5611859560012817, - 0.030582552775740623 + -1.0136138200759888, + -1.391968846321106, + -0.8026610612869263, + 0.45739221572875977, + -0.1074383333325386 ], [ - 0.01513738464564085, - 1.1773208379745483, - -0.9649611115455627, - -0.24674776196479797, - -0.6797627210617065 + 2.130958080291748, + 0.24406017363071442, + 1.0900812149047852, + 0.7718657851219177, + 0.01673818565905094 ] ], [ [ - -0.7475828528404236, - -0.21754391491413116, - -1.3795819282531738, - 1.0700255632400513, - 1.608759880065918 + 0.2065047323703766, + -0.3839341402053833, + -0.5727554559707642, + -0.368385910987854, + 1.0989755392074585 ], [ - -0.4297754466533661, - -0.77903813123703, - 1.1783149242401123, - 0.04237056151032448, - -0.610821008682251 + -0.2800213098526001, + -0.4368455111980438, + -0.7779284715652466, + 1.2181257009506226, + -0.1532776802778244 ], [ - -0.6625555157661438, - -0.5495360493659973, - 0.2577652037143707, - -2.150420904159546, - -2.154161214828491 + 0.3922649621963501, + -0.24747081100940704, + 0.2792662978172302, + 0.2393292933702469, + 0.08084768056869507 ], [ - -0.42972853779792786, - 1.4808158874511719, - -2.7135519981384277, - 1.1272135972976685, - 0.5445007681846619 + 0.45395395159721375, + -1.3717968463897705, + -0.47459128499031067, + -0.9676264524459839, + -0.6989938616752625 ] ] ], "expected_output": [ [ [ - 0.3579265773296356, - -0.21754391491413116, - 1.0006709098815918, - 1.0700255632400513, - 1.608759880065918 + 0.5024110674858093, + 0.06238764151930809, + 1.6630321741104126, + 1.6428531408309937, + 1.3266892433166504 ], [ - 0.4728609323501587, - -0.6277503967285156, - 1.1783149242401123, - 0.04237056151032448, - -0.5570979714393616 + 0.6551998853683472, + 0.6860383749008179, + -0.02104124240577221, + 1.2181257009506226, + 1.6672981977462769 ], [ - 0.8582064509391785, - 3.035121202468872, - 1.7607189416885376, - 0.13592901825904846, - 0.030582552775740623 + 1.6906514167785645, + -0.24747081100940704, + 0.2792662978172302, + 0.45739221572875977, + 0.08084768056869507 ], [ - 1.7253460884094238, - 1.4808158874511719, - 2.0246987342834473, - 1.1272135972976685, - 0.5445007681846619 + 2.130958080291748, + 0.24406017363071442, + 1.0900812149047852, + 0.7718657851219177, + 0.26206839084625244 ] ] ], "expected_grad": [ [ [ - 1.0, 0.0, 1.0, 0.0, + 1.0, 0.0 ], [ - 1.0, 0.0, 0.0, + 1.0, 0.0, - 1.0 + 0.0 ], [ + 1.0, 0.0, 0.0, 0.0, - 1.0, 0.0 ], [ - 1.0, 0.0, - 1.0, 0.0, - 0.0 + 0.0, + 0.0, + 1.0 ] ], [ [ + 1.0, 0.0, + 1.0, 0.0, + 1.0 + ], + [ + 1.0, + 1.0, 0.0, 0.0, - 0.0 + 1.0 ], [ 0.0, - 1.0, 0.0, 0.0, + 1.0, 0.0 ], [ 1.0, 1.0, 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, + 1.0, 0.0 ] ], [ [ 0.0, - 1.0, 0.0, - 1.0, - 1.0 - ], - [ 0.0, 0.0, - 1.0, - 1.0, 0.0 ], [ 0.0, 0.0, 0.0, - 0.0, + 1.0, 0.0 ], [ 0.0, 1.0, - 0.0, 1.0, + 0.0, 1.0 + ], + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 ] ] ] @@ -9505,125 +10450,125 @@ export const testData = { "input": [ [ [ - -1.1812111139297485, - 0.29110395908355713, - -1.908882975578308, - -0.06162146106362343, - -0.628868818283081 + 1.1716068983078003, + -1.7179490327835083, + -0.534604549407959, + -1.306166410446167, + -0.9246346950531006 ], [ - -0.0399823822081089, - -0.9634820222854614, - -1.054305911064148, - 1.3201165199279785, - 0.01912905089557171 + 0.6214187741279602, + 0.1785161793231964, + 0.2866869568824768, + 0.4850883483886719, + 0.005962289869785309 ], [ - 0.6439768075942993, - -1.622911810874939, - 0.24067530035972595, - 1.6770813465118408, - -0.09622633457183838 + -0.3370489478111267, + 1.0511995553970337, + -1.3509515523910522, + 0.5409456491470337, + 1.134432315826416 ], [ - -0.6806969046592712, - 0.22181209921836853, - -0.09738165885210037, - -0.3662233054637909, - 0.5110824108123779 + -0.4212900400161743, + -0.10431576520204544, + 0.9755558371543884, + -1.0027341842651367, + 1.28053879737854 ] ], [ [ - 0.947607159614563, - -1.7693769931793213, - 0.9019067287445068, - 0.3177003860473633, - -0.9191910624504089 + 1.2130928039550781, + 0.12110324949026108, + -1.2743698358535767, + 0.884564220905304, + 0.12699493765830994 ], [ - 0.47818925976753235, - 0.627395510673523, - -0.9072081446647644, - -1.1753108501434326, - -1.6300257444381714 + -0.8810292482376099, + 1.8218294382095337, + 1.5863804817199707, + 0.865519106388092, + -0.27654826641082764 ], [ - 0.7812330722808838, - -1.473711609840393, - -0.2650183439254761, - 1.5695449113845825, - -0.9781676530838013 + -0.19467514753341675, + -0.03429529443383217, + 0.7240417003631592, + 0.13301636278629303, + -1.0541536808013916 ], [ - 0.46865877509117126, - -0.03328606113791466, - -0.8684351444244385, - -1.338854193687439, - -0.10444001853466034 + -2.312596321105957, + -0.902730405330658, + -1.4185947179794312, + 0.37751105427742004, + -0.2093215435743332 ] ], [ [ - 0.33355948328971863, - -0.5553439855575562, - 0.8256968259811401, - 1.3953009843826294, - -0.8951465487480164 + -1.1487538814544678, + 0.22709836065769196, + -0.9184321165084839, + 0.9846003651618958, + -0.06645472347736359 ], [ - -0.08590231090784073, - -0.34807300567626953, - -0.9660927653312683, - -0.6545328497886658, - -2.0421197414398193 + 1.2572640180587769, + 0.1582425981760025, + -1.742975115776062, + -1.2938947677612305, + 1.3074569702148438 ], [ - 0.9974169135093689, - 0.3814171552658081, - 0.24766799807548523, - 0.9761032462120056, - -1.2878117561340332 + -0.8769122958183289, + -0.015859045088291168, + -0.6937687397003174, + -0.8013211488723755, + -0.07756809890270233 ], [ - 1.9193944931030273, - -0.9316161870956421, - -0.3878573179244995, - 1.8630023002624512, - 0.6344600915908813 + -0.5014570951461792, + -2.2269856929779053, + -0.17264695465564728, + -0.4442422091960907, + 0.2926892936229706 ] ] ], "expected_output": [ [ - 0.6439768075942993, - 0.29110395908355713, - 0.24067530035972595, - 1.6770813465118408, - 0.5110824108123779 + 1.1716068983078003, + 1.0511995553970337, + 0.9755558371543884, + 0.5409456491470337, + 1.28053879737854 ], [ - 0.947607159614563, - 0.627395510673523, - 0.9019067287445068, - 1.5695449113845825, - -0.10444001853466034 + 1.2130928039550781, + 1.8218294382095337, + 1.5863804817199707, + 0.884564220905304, + 0.12699493765830994 ], [ - 1.9193944931030273, - 0.3814171552658081, - 0.8256968259811401, - 1.8630023002624512, - 0.6344600915908813 + 1.2572640180587769, + 0.22709836065769196, + -0.17264695465564728, + 0.9846003651618958, + 1.3074569702148438 ] ], "expected_grad": [ [ [ - 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0 ], [ @@ -9634,16 +10579,16 @@ export const testData = { 0.0 ], [ - 1.0, 0.0, 1.0, + 0.0, 1.0, 0.0 ], [ 0.0, 0.0, - 0.0, + 1.0, 0.0, 1.0 ] @@ -9652,14 +10597,14 @@ export const testData = { [ 1.0, 0.0, - 1.0, 0.0, - 0.0 + 1.0, + 1.0 ], [ 0.0, 1.0, - 0.0, + 1.0, 0.0, 0.0 ], @@ -9667,7 +10612,7 @@ export const testData = { 0.0, 0.0, 0.0, - 1.0, + 0.0, 0.0 ], [ @@ -9675,37 +10620,37 @@ export const testData = { 0.0, 0.0, 0.0, - 1.0 + 0.0 ] ], [ [ - 0.0, 0.0, 1.0, 0.0, + 1.0, 0.0 ], [ + 1.0, 0.0, 0.0, 0.0, - 0.0, - 0.0 + 1.0 ], [ 0.0, - 1.0, + 0.0, 0.0, 0.0, 0.0 ], [ - 1.0, 0.0, 0.0, 1.0, - 1.0 + 0.0, + 0.0 ] ] ] @@ -9718,131 +10663,131 @@ export const testData = { "input": [ [ [ - -0.15298272669315338, - -0.291658490896225, - 1.3547232151031494, - 1.1477179527282715, - -1.1454607248306274 + 0.05868193879723549, + 1.5382329225540161, + 1.0444575548171997, + -0.26301294565200806, + 0.2191448211669922 ], [ - 0.33044537901878357, - -0.9961053133010864, - 0.06837695091962814, - -0.002813637489452958, - -0.6423792839050293 + 0.05122251436114311, + -0.6351413130760193, + -0.9322060346603394, + -0.2185828685760498, + 0.4121098220348358 ], [ - 0.45413073897361755, - -0.44131579995155334, - 1.692244052886963, - -0.12363708764314651, - 0.5800541639328003 + -1.132474660873413, + -2.3891191482543945, + 0.7177993655204773, + -1.5831094980239868, + 0.6412859559059143 ], [ - -0.3184976875782013, - 1.165942907333374, - -0.24008060991764069, - 0.681287944316864, - -0.34171757102012634 + -0.2708216905593872, + -0.6109879612922668, + 0.11032737791538239, + 0.12355764210224152, + -1.4388847351074219 ] ], [ [ - 0.34814006090164185, - 0.992973804473877, - 0.6181811690330505, - 2.570577383041382, - 2.195984125137329 + -0.45935776829719543, + 0.719353199005127, + -1.2023998498916626, + -0.5769718289375305, + 0.7339244484901428 ], [ - 0.8412518501281738, - -0.6978152394294739, - 1.6602482795715332, - -0.1676439493894577, - -1.480851411819458 + 0.0939386859536171, + 1.0834808349609375, + 0.8089823126792908, + -0.9773237109184265, + -0.26083904504776 ], [ - -0.17118047177791595, - 0.2488422989845276, - 0.08594394475221634, - -0.3800842761993408, - 0.944334864616394 + -0.07018473744392395, + -1.206803798675537, + 1.5053801536560059, + -0.0004540873342193663, + -0.8399935364723206 ], [ - -0.4332982003688812, - -0.9019569158554077, - -1.0107343196868896, - -0.7094535827636719, - -0.1548715978860855 + -0.9963456988334656, + 1.9695827960968018, + -0.6241140961647034, + -0.11510364711284637, + 1.3116685152053833 ] ], [ [ - -1.1838287115097046, - 0.8204308748245239, - -1.0191556215286255, - -0.27120286226272583, - 1.2692794799804688 + 0.9128003120422363, + -0.8139405250549316, + -0.32805025577545166, + -1.6033560037612915, + -0.6016383171081543 ], [ - 2.2910208702087402, - -0.07968119531869888, - -2.142704963684082, - 1.5941132307052612, - 2.5384137630462646 + -0.3473812937736511, + -0.9625334739685059, + 0.9539335370063782, + -1.4123497009277344, + 0.812851071357727 ], [ - 0.8317916393280029, - 0.5718692541122437, - -1.202392816543579, - -0.6351379156112671, - 0.20571336150169373 + 1.4345933198928833, + 0.05774686485528946, + 0.8243234157562256, + 0.3210548460483551, + -0.6046251654624939 ], [ - 1.2084790468215942, - -1.2975432872772217, - -1.7842353582382202, - -1.5064395666122437, - -0.5166544914245605 + -0.6875012516975403, + 0.20559696853160858, + -0.7192203998565674, + -1.1452873945236206, + 0.888896107673645 ] ] ], "expected_output": [ [ [ - 0.45413073897361755, - 1.165942907333374, - 1.692244052886963, - 1.1477179527282715, - 0.5800541639328003 + 0.05868193879723549, + 1.5382329225540161, + 1.0444575548171997, + 0.12355764210224152, + 0.6412859559059143 ] ], [ [ - 0.8412518501281738, - 0.992973804473877, - 1.6602482795715332, - 2.570577383041382, - 2.195984125137329 + 0.0939386859536171, + 1.9695827960968018, + 1.5053801536560059, + -0.0004540873342193663, + 1.3116685152053833 ] ], [ [ - 2.2910208702087402, - 0.8204308748245239, - -1.0191556215286255, - 1.5941132307052612, - 2.5384137630462646 + 1.4345933198928833, + 0.20559696853160858, + 0.9539335370063782, + 0.3210548460483551, + 0.888896107673645 ] ] ], "expected_grad": [ [ [ - 0.0, - 0.0, - 0.0, 1.0, + 1.0, + 1.0, + 0.0, 0.0 ], [ @@ -9853,78 +10798,78 @@ export const testData = { 0.0 ], [ - 1.0, 0.0, - 1.0, + 0.0, + 0.0, 0.0, 1.0 ], [ 0.0, - 1.0, 0.0, 0.0, + 1.0, 0.0 ] ], [ [ 0.0, - 1.0, 0.0, - 1.0, - 1.0 + 0.0, + 0.0, + 0.0 ], [ 1.0, 0.0, - 1.0, + 0.0, 0.0, 0.0 ], [ 0.0, 0.0, - 0.0, - 0.0, + 1.0, + 1.0, 0.0 ], [ 0.0, + 1.0, 0.0, 0.0, - 0.0, - 0.0 + 1.0 ] ], [ [ 0.0, - 1.0, - 1.0, + 0.0, + 0.0, 0.0, 0.0 ], [ - 1.0, 0.0, 0.0, 1.0, - 1.0 + 0.0, + 0.0 ], [ + 1.0, 0.0, 0.0, - 0.0, - 0.0, + 1.0, 0.0 ], [ 0.0, + 1.0, 0.0, 0.0, - 0.0, - 0.0 + 1.0 ] ] ] @@ -9937,143 +10882,143 @@ export const testData = { "input": [ [ [ - 0.7335371971130371, - 0.9938647150993347, - 0.00801965780556202, - -0.28345587849617004, - -1.0710505247116089 + 1.102234125137329, + 0.1452106386423111, + -1.0025994777679443, + -0.8691359758377075, + 1.034902811050415 ], [ - -0.39534568786621094, - -1.0722109079360962, - 0.33898138999938965, - 0.1372641772031784, - -0.28324073553085327 + 1.141363263130188, + -0.6113547086715698, + 0.5669911503791809, + 0.08074041455984116, + 0.769339919090271 ], [ - 0.8449776768684387, - -1.6651710271835327, - 0.9013379216194153, - 0.29200538992881775, - 0.0021756188943982124 + -1.206941843032837, + -0.1684180051088333, + -1.0213230848312378, + 0.45474377274513245, + 0.05628223717212677 ], [ - -0.2805594801902771, - -0.8447388410568237, - -1.7777600288391113, - 1.6797508001327515, - -0.30756810307502747 + 0.1908469796180725, + 1.134475827217102, + -0.6270834803581238, + -0.2348310351371765, + 0.1834784746170044 ] ], [ [ - 0.17818263173103333, - 0.3059806525707245, - 0.3167516589164734, - -0.9520257711410522, - 0.6430982351303101 + 0.8270988464355469, + 0.6817458271980286, + 0.40630635619163513, + 1.706158995628357, + -0.3331676423549652 ], [ - -1.3191593885421753, - -0.5693896412849426, - -1.8995989561080933, - 0.2520817816257477, - 0.7248584032058716 + 1.3781265020370483, + 0.22484587132930756, + -2.3762154579162598, + 0.4015538990497589, + -2.294616460800171 ], [ - -0.30675002932548523, - -0.3078252077102661, - -0.39913156628608704, - -0.545810341835022, - -0.9492759704589844 + 0.9543997049331665, + -0.3883368968963623, + -0.6146398186683655, + -0.4274226725101471, + -1.4890133142471313 ], [ - -0.5826377272605896, - 0.6084815859794617, - 1.8586663007736206, - 0.33828064799308777, - 0.22547557950019836 + 0.5850116610527039, + -0.6405912041664124, + -1.9063634872436523, + -0.21498170495033264, + 0.1672649085521698 ] ], [ [ - 1.375124216079712, - 0.4969656765460968, - -0.5050092339515686, - 1.3103235960006714, - -0.5601279139518738 + -0.02165069803595543, + 0.7171346545219421, + -1.3825470209121704, + 0.5667335987091064, + 0.1853654533624649 ], [ - 0.564572811126709, - 0.28999093174934387, - -0.2832452356815338, - -0.7486765384674072, - -1.4253593683242798 + 1.7064272165298462, + 2.270893096923828, + 0.6268392205238342, + 1.6014127731323242, + 1.196624517440796 ], [ - -0.3249308466911316, - 0.24911366403102875, - -0.6594748497009277, - -1.5963871479034424, - -0.6603827476501465 + 0.07062987983226776, + -0.06806328892707825, + -0.8778694272041321, + -0.666265070438385, + 0.34564408659935 ], [ - -0.9291712641716003, - 1.041069507598877, - 1.7303272485733032, - -0.8963518738746643, - -1.7486891746520996 + -0.1972421109676361, + -1.5218473672866821, + -0.06109791249036789, + -0.49620160460472107, + 1.5591261386871338 ] ] ], "expected_output": [ [ - 0.9938647150993347, - 0.33898138999938965, - 0.9013379216194153, - 1.6797508001327515 + 1.102234125137329, + 1.141363263130188, + 0.45474377274513245, + 1.134475827217102 ], [ - 0.6430982351303101, - 0.7248584032058716, - -0.30675002932548523, - 1.8586663007736206 + 1.706158995628357, + 1.3781265020370483, + 0.9543997049331665, + 0.5850116610527039 ], [ - 1.375124216079712, - 0.564572811126709, - 0.24911366403102875, - 1.7303272485733032 + 0.7171346545219421, + 2.270893096923828, + 0.34564408659935, + 1.5591261386871338 ] ], "expected_grad": [ [ [ - 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0 ], [ + 1.0, 0.0, 0.0, - 1.0, 0.0, 0.0 ], [ 0.0, 0.0, - 1.0, 0.0, + 1.0, 0.0 ], [ 0.0, + 1.0, 0.0, 0.0, - 1.0, 0.0 ] ], @@ -10082,15 +11027,15 @@ export const testData = { 0.0, 0.0, 0.0, - 0.0, - 1.0 + 1.0, + 0.0 ], [ + 1.0, 0.0, 0.0, 0.0, - 0.0, - 1.0 + 0.0 ], [ 1.0, @@ -10100,41 +11045,41 @@ export const testData = { 0.0 ], [ + 1.0, 0.0, 0.0, - 1.0, 0.0, 0.0 ] ], [ [ - 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0 ], [ - 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0 ], [ 0.0, - 1.0, 0.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ 0.0, 0.0, - 1.0, 0.0, - 0.0 + 0.0, + 1.0 ] ] ] @@ -10147,184 +11092,184 @@ export const testData = { "input": [ [ [ - -0.9125152230262756, - 0.4803459644317627, - -0.41451194882392883, - -1.7112841606140137, - 0.3645228147506714 + 0.08976225554943085, + -2.1487770080566406, + -0.26685312390327454, + 0.06450489908456802, + -1.4932622909545898 ], [ - -0.5803453326225281, - -0.7104259729385376, - -0.27301856875419617, - -0.6705332398414612, - 1.595921277999878 + 1.6294554471969604, + -1.738688588142395, + 1.7332375049591064, + 2.0544910430908203, + 1.293807029724121 ], [ - 0.5219618082046509, - 0.34126174449920654, - 1.010899543762207, - -0.04691770300269127, - 0.2992815375328064 + 0.8169977068901062, + -1.0389111042022705, + -1.4858906269073486, + 1.4143908023834229, + 0.7241055965423584 ], [ - -0.4206298589706421, - -1.9771111011505127, - -0.004498381167650223, - 0.023252639919519424, - -1.0357731580734253 + 1.134980320930481, + -0.2217475324869156, + 2.139716625213623, + 0.19970077276229858, + 0.8841625452041626 ] ], [ [ - 0.6917201280593872, - -0.6789452433586121, - -0.9247362613677979, - -0.31068262457847595, - 0.2013172209262848 + 0.949975848197937, + -0.10251139849424362, + 0.9830695986747742, + -1.6503483057022095, + 0.10293407738208771 ], [ - 0.6645943522453308, - -1.7228929996490479, - -0.5210925936698914, - 0.060717396438121796, - 0.42114102840423584 + -1.2885284423828125, + -0.7290129065513611, + -1.3367583751678467, + 0.28592362999916077, + 1.0034847259521484 ], [ - 1.0576668977737427, - 1.3254046440124512, - 0.07843684405088425, - -0.19520922005176544, - 0.7735913395881653 + 0.6469754576683044, + 1.3000932931900024, + -0.634432315826416, + 0.09809456765651703, + -2.255279064178467 ], [ - 0.1407848447561264, - -0.2778305411338806, - 0.015577469952404499, - -0.9061261415481567, - -0.6032977104187012 + -1.0050581693649292, + 0.27072352170944214, + 0.2964065372943878, + -0.010661646723747253, + 0.32635602355003357 ] ], [ [ - 0.7053933143615723, - -0.40017446875572205, - -3.028942346572876, - 0.26209768652915955, - 0.02327004447579384 + -0.779302179813385, + 1.35313880443573, + 0.9089425206184387, + -1.2521377801895142, + -0.1434730738401413 ], [ - -0.6302129626274109, - 0.888484001159668, - 0.1747579276561737, - -2.0527801513671875, - 0.03855415806174278 + 0.10889503359794617, + 0.09379234164953232, + -0.7034569978713989, + -0.17944560945034027, + 0.45458918809890747 ], [ - 1.213753581047058, - -0.08656994998455048, - -0.5959414839744568, - -1.8832926750183105, - 0.5548990964889526 + -0.26298829913139343, + 0.39442673325538635, + 0.3479395806789398, + -1.4978502988815308, + 0.7075753211975098 ], [ - -0.9461650252342224, - -0.7394051551818848, - 0.7492458820343018, - -0.6058419346809387, - -0.384304404258728 + 0.693645179271698, + -0.07173124700784683, + -0.2537860572338104, + 0.2973843812942505, + -1.541783332824707 ] ] ], "expected_output": [ [ [ - 0.4803459644317627 + 0.08976225554943085 ], [ - 1.595921277999878 + 2.0544910430908203 ], [ - 1.010899543762207 + 1.4143908023834229 ], [ - 0.023252639919519424 + 2.139716625213623 ] ], [ [ - 0.6917201280593872 + 0.9830695986747742 ], [ - 0.6645943522453308 + 1.0034847259521484 ], [ - 1.3254046440124512 + 1.3000932931900024 ], [ - 0.1407848447561264 + 0.32635602355003357 ] ], [ [ - 0.7053933143615723 + 1.35313880443573 ], [ - 0.888484001159668 + 0.45458918809890747 ], [ - 1.213753581047058 + 0.7075753211975098 ], [ - 0.7492458820343018 + 0.693645179271698 ] ] ], "expected_grad": [ [ [ - 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0 ], [ 0.0, 0.0, 0.0, - 0.0, - 1.0 + 1.0, + 0.0 ], [ 0.0, 0.0, - 1.0, 0.0, + 1.0, 0.0 ], [ - 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0 ] ], [ [ - 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0 ], [ - 1.0, 0.0, 0.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ 0.0, @@ -10334,39 +11279,39 @@ export const testData = { 0.0 ], [ - 1.0, 0.0, 0.0, 0.0, - 0.0 + 0.0, + 1.0 ] ], [ [ - 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0 ], [ 0.0, - 1.0, 0.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ - 1.0, 0.0, 0.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ + 1.0, 0.0, 0.0, - 1.0, 0.0, 0.0 ] @@ -10381,96 +11326,96 @@ export const testData = { "input": [ [ [ - 0.3851594030857086, - -0.3151880204677582, - 0.039046529680490494, - -0.17162249982357025, - -0.842478334903717 + -1.4054443836212158, + 0.007234930992126465, + 0.5773534178733826, + 0.30951234698295593, + -0.8588898777961731 ], [ - 1.226798415184021, - 0.6258861422538757, - -0.021849583834409714, - -1.4504739046096802, - 0.8094747066497803 + 0.526231050491333, + -0.06828558444976807, + 1.2680625915527344, + 0.23789522051811218, + -1.805619716644287 ], [ - -0.7144426107406616, - 0.7041144371032715, - -1.2723145484924316, - -0.713442862033844, - 0.23755493760108948 + 1.746630311012268, + -1.526967167854309, + 0.3485613167285919, + 0.7839732766151428, + 1.5388095378875732 ], [ - 2.4901089668273926, - -0.9031432867050171, - -1.279140830039978, - -0.4034813344478607, - -0.6024842858314514 + 1.1633633375167847, + 0.8717845678329468, + 0.21581949293613434, + 0.1374770998954773, + -1.1221222877502441 ] ], [ [ - -0.46980521082878113, - 0.5732667446136475, - -0.0040825954638421535, - 0.07298417389392853, - -0.6787295341491699 + 0.1467854380607605, + -0.17452457547187805, + -0.7465326189994812, + -1.163095235824585, + -1.0377240180969238 ], [ - -0.2703229784965515, - -0.15237197279930115, - 0.11046099662780762, - -0.9912855625152588, - -0.8878551721572876 + 0.6390634179115295, + -0.929384708404541, + 0.07479915767908096, + 0.641934871673584, + 1.1865335702896118 ], [ - 1.3682804107666016, - 1.2855982780456543, - 1.5158559083938599, - 0.5367690324783325, - 1.7698261737823486 + -0.7681276798248291, + -0.8917787075042725, + 0.19665859639644623, + 0.6306189298629761, + 1.6684050559997559 ], [ - 1.3941913843154907, - -0.4474734365940094, - -0.8029153347015381, - -0.9047854542732239, - -0.010661765933036804 + 1.258668065071106, + 0.16344283521175385, + 0.8060418367385864, + -0.6885544061660767, + -0.23013491928577423 ] ], [ [ - 0.4942079484462738, - -0.09941978752613068, - 0.5940057635307312, - 0.8259775638580322, - 0.1896892935037613 + 1.1331552267074585, + 0.42492198944091797, + -0.07918443530797958, + 0.3510800898075104, + 0.45417457818984985 ], [ - -0.15840917825698853, - -1.5296630859375, - 1.0559983253479004, - 2.0524368286132812, - -0.3509976267814636 + 0.3879549503326416, + -0.6664285659790039, + -0.5420844554901123, + 2.9302103519439697, + 0.03980718180537224 ], [ - -1.1978983879089355, - 0.5596528053283691, - 1.5097410678863525, - -0.40140989422798157, - 0.8937979340553284 + -1.2734509706497192, + 1.154341697692871, + 0.7456277012825012, + -0.46407395601272583, + 0.354059636592865 ], [ - 0.8215998411178589, - 1.038364052772522, - 0.37289324402809143, - -1.419432282447815, - -0.2249353677034378 + 0.5733898282051086, + -1.9253568649291992, + 1.3460670709609985, + -0.9440423846244812, + 0.5850473642349243 ] ] ], - "expected_output": -1.5296630859375, + "expected_output": -1.9253568649291992, "expected_grad": [ [ [ @@ -10542,7 +11487,7 @@ export const testData = { ], [ 0.0, - 1.0, + 0.0, 0.0, 0.0, 0.0 @@ -10556,7 +11501,7 @@ export const testData = { ], [ 0.0, - 0.0, + 1.0, 0.0, 0.0, 0.0 @@ -10572,151 +11517,151 @@ export const testData = { "input": [ [ [ - 1.1369043588638306, - -0.9767837524414062, - -0.467501699924469, - -0.31253546476364136, - -2.420801877975464 + -0.7561046481132507, + -0.6087163090705872, + 0.06523545831441879, + 0.2073671668767929, + -0.4843977093696594 ], [ - -0.6981193423271179, - -0.8373439908027649, - -0.4472923278808594, - 1.659290075302124, - -0.6820825934410095 + -0.4931473731994629, + 0.695488691329956, + 1.5209262371063232, + -1.5004045963287354, + 1.424126148223877 ], [ - 0.4594089686870575, - -0.11755221337080002, - 0.058173540979623795, - -0.11270477622747421, - 0.6009398698806763 + 0.4264316260814667, + 1.725341796875, + -1.1767886877059937, + -0.5571966767311096, + 2.1753745079040527 ], [ - 0.05460839346051216, - 1.5627477169036865, - -1.3852146863937378, - 1.388021469116211, - -0.41201210021972656 + -0.4421183466911316, + -1.742424488067627, + -0.7672881484031677, + 1.4304224252700806, + 0.39234694838523865 ] ], [ [ - 0.17847855389118195, - -0.4211631417274475, - 0.6745750904083252, - -1.7007237672805786, - -0.2912011444568634 + -1.3970006704330444, + -2.0020906925201416, + -0.26867592334747314, + -0.701147735118866, + 0.31265851855278015 ], [ - -1.4456785917282104, - 1.786425232887268, - 0.15301446616649628, - -0.35936856269836426, - -0.9645422697067261 + -0.3883015811443329, + 0.8928799033164978, + 0.7249560952186584, + 0.4335167407989502, + 0.9744104146957397 ], [ - 0.8855559229850769, - -0.31540220975875854, - 0.08357129991054535, - -0.5507245063781738, - -1.8988375663757324 + -0.21621425449848175, + -0.29577603936195374, + -0.2591007351875305, + 0.7960927486419678, + 0.5791953802108765 ], [ - -0.01925942301750183, - 0.29304513335227966, - 0.24341490864753723, - 2.0406532287597656, - -0.7569413781166077 + -0.13450507819652557, + -1.3556065559387207, + -0.394126832485199, + -0.7559952735900879, + 0.5876944661140442 ] ], [ [ - -0.16658450663089752, - -0.6370474696159363, - -0.4297468662261963, - 0.8156528472900391, - 1.2827181816101074 + -1.3335460424423218, + 0.9432480931282043, + -1.1379897594451904, + -1.1207023859024048, + -0.6139907240867615 ], [ - 0.40247759222984314, - 1.5573612451553345, - 2.0378758907318115, - -0.11328133195638657, - -1.0065470933914185 + 0.9939887523651123, + 0.5297332406044006, + -0.3778044879436493, + 1.417391061782837, + 0.4910713732242584 ], [ - -0.6232604384422302, - 1.0608307123184204, - -1.0525683164596558, - 0.22322431206703186, - 1.0225255489349365 + 0.9159647822380066, + 0.1735081523656845, + -1.438053846359253, + 0.6212812662124634, + -1.969196081161499 ], [ - 0.7757742404937744, - 0.645967423915863, - 0.7403110861778259, - 1.311670184135437, - -1.945209264755249 + -0.2445336878299713, + -0.6776713728904724, + 0.47822806239128113, + -1.8905819654464722, + 0.2990115284919739 ] ] ], "expected_output": [ [ - -0.16658450663089752, - -0.9767837524414062, - -0.467501699924469, - -1.7007237672805786, - -2.420801877975464 + -1.3970006704330444, + -2.0020906925201416, + -1.1379897594451904, + -1.1207023859024048, + -0.6139907240867615 ], [ - -1.4456785917282104, - -0.8373439908027649, - -0.4472923278808594, - -0.35936856269836426, - -1.0065470933914185 + -0.4931473731994629, + 0.5297332406044006, + -0.3778044879436493, + -1.5004045963287354, + 0.4910713732242584 ], [ - -0.6232604384422302, - -0.31540220975875854, - -1.0525683164596558, - -0.5507245063781738, - -1.8988375663757324 + -0.21621425449848175, + -0.29577603936195374, + -1.438053846359253, + -0.5571966767311096, + -1.969196081161499 ], [ - -0.01925942301750183, - 0.29304513335227966, - -1.3852146863937378, - 1.311670184135437, - -1.945209264755249 + -0.4421183466911316, + -1.742424488067627, + -0.7672881484031677, + -1.8905819654464722, + 0.2990115284919739 ] ], "expected_grad": [ [ [ 0.0, - 1.0, - 1.0, 0.0, - 1.0 + 0.0, + 0.0, + 0.0 ], [ - 0.0, - 1.0, 1.0, 0.0, + 0.0, + 1.0, 0.0 ], [ 0.0, 0.0, 0.0, - 0.0, + 1.0, 0.0 ], [ - 0.0, - 0.0, + 1.0, + 1.0, 1.0, 0.0, 0.0 @@ -10724,29 +11669,29 @@ export const testData = { ], [ [ + 1.0, + 1.0, 0.0, 0.0, - 0.0, - 1.0, 0.0 ], [ - 1.0, 0.0, 0.0, - 1.0, + 0.0, + 0.0, 0.0 ], [ - 0.0, 1.0, - 0.0, 1.0, - 1.0 + 0.0, + 0.0, + 0.0 ], [ - 1.0, - 1.0, + 0.0, + 0.0, 0.0, 0.0, 0.0 @@ -10754,25 +11699,25 @@ export const testData = { ], [ [ - 1.0, - 0.0, 0.0, 0.0, - 0.0 + 1.0, + 1.0, + 1.0 ], [ 0.0, - 0.0, - 0.0, + 1.0, + 1.0, 0.0, 1.0 ], [ - 1.0, + 0.0, 0.0, 1.0, 0.0, - 0.0 + 1.0 ], [ 0.0, @@ -10792,124 +11737,124 @@ export const testData = { "input": [ [ [ - 0.4310223162174225, - -0.22314855456352234, - 0.04046724736690521, - 0.3553427457809448, - 1.9382938146591187 + 0.4874853193759918, + -1.5288264751434326, + 0.3616181015968323, + 0.4444722533226013, + 0.37175261974334717 ], [ - -1.254912257194519, - 0.14595302939414978, - 0.2614082098007202, - 0.38991880416870117, - 0.40374335646629333 + 0.17289385199546814, + -1.2141680717468262, + 1.9441745281219482, + -0.5341972708702087, + -0.07878366857767105 ], [ - -0.47906389832496643, - -0.5763978362083435, - -2.3239030838012695, - -0.28545263409614563, - 1.02093505859375 + 0.9717959761619568, + 0.15757296979427338, + -0.1293685883283615, + 0.9459248185157776, + 0.7486283779144287 ], [ - 0.8959177732467651, - -2.674952745437622, - 0.185286283493042, - -1.3125312328338623, - -0.7755544781684875 + 1.3489890098571777, + -0.11803387850522995, + 0.8932477235794067, + 0.8591998815536499, + 1.068840742111206 ] ], [ [ - -0.09462077915668488, - -1.171595811843872, - 0.5055325031280518, - 0.37683606147766113, - -1.171151041984558 + 1.035352349281311, + -1.0888819694519043, + -0.9833644032478333, + 0.18595486879348755, + -0.5669856071472168 ], [ - 0.2559703290462494, - 0.4515315592288971, - -0.7774103879928589, - -2.5792624950408936, - 1.3327691555023193 + -1.0098682641983032, + -0.4541301131248474, + 0.6979333758354187, + 0.546902596950531, + 0.5524624586105347 ], [ - 0.8247588872909546, - 0.1895250678062439, - 0.13722558319568634, - 1.2756917476654053, - 0.4262869358062744 + 0.2402925342321396, + -1.1295276880264282, + 2.641334295272827, + -0.42235150933265686, + 0.3279983699321747 ], [ - 0.1224641352891922, - 0.5574866533279419, - 0.30463987588882446, - 0.5269746780395508, - 1.4476677179336548 + -0.22356857359409332, + 0.6338478326797485, + 1.2712687253952026, + 0.5257611274719238, + -0.08859143406152725 ] ], [ [ - -0.1862286925315857, - -0.16418692469596863, - 0.5037822723388672, - 1.202155351638794, - -0.4691736400127411 + 0.2868587076663971, + 1.34219491481781, + -0.4532349705696106, + 1.0591752529144287, + -0.007002960424870253 ], [ - 3.5406761169433594, - -0.38007304072380066, - -0.2619936764240265, - -0.5226048827171326, - -0.42274436354637146 + 1.0370234251022339, + 0.12661591172218323, + 0.9138452410697937, + 0.15242700278759003, + -1.77699875831604 ], [ - 0.0772174745798111, - 1.6049801111221313, - -1.6840441226959229, - 0.6537221670150757, - 0.36240431666374207 + -0.2700897455215454, + 1.132546067237854, + -0.4591978192329407, + 0.7583627104759216, + -0.25366878509521484 ], [ - -1.1095906496047974, - 0.15686734020709991, - 0.6184999346733093, - 1.4835309982299805, - -0.26363199949264526 + -0.6026967763900757, + 0.41119346022605896, + -0.4785611629486084, + -0.3798253536224365, + -0.6784350275993347 ] ] ], "expected_output": [ [ [ - -0.1862286925315857, - -1.171595811843872, - 0.04046724736690521, - 0.3553427457809448, - -1.171151041984558 + 0.2868587076663971, + -1.5288264751434326, + -0.9833644032478333, + 0.18595486879348755, + -0.5669856071472168 ], [ - -1.254912257194519, - -0.38007304072380066, - -0.7774103879928589, - -2.5792624950408936, - -0.42274436354637146 + -1.0098682641983032, + -1.2141680717468262, + 0.6979333758354187, + -0.5341972708702087, + -1.77699875831604 ], [ - -0.47906389832496643, - -0.5763978362083435, - -2.3239030838012695, - -0.28545263409614563, - 0.36240431666374207 + -0.2700897455215454, + -1.1295276880264282, + -0.4591978192329407, + -0.42235150933265686, + -0.25366878509521484 ], [ - -1.1095906496047974, - -2.674952745437622, - 0.185286283493042, - -1.3125312328338623, - -0.7755544781684875 + -0.6026967763900757, + -0.11803387850522995, + -0.4785611629486084, + -0.3798253536224365, + -0.6784350275993347 ] ] ], @@ -10917,53 +11862,53 @@ export const testData = { [ [ 0.0, - 0.0, - 1.0, 1.0, + 0.0, + 0.0, 0.0 ], [ - 1.0, - 0.0, 0.0, + 1.0, 0.0, + 1.0, 0.0 ], [ - 1.0, - 1.0, - 1.0, - 1.0, + 0.0, + 0.0, + 0.0, + 0.0, 0.0 ], [ 0.0, 1.0, - 1.0, - 1.0, - 1.0 + 0.0, + 0.0, + 0.0 ] ], [ [ - 0.0, - 1.0, 0.0, 0.0, + 1.0, + 1.0, 1.0 ], [ - 0.0, - 0.0, 1.0, + 0.0, 1.0, + 0.0, 0.0 ], [ 0.0, + 1.0, 0.0, - 0.0, - 0.0, + 1.0, 0.0 ], [ @@ -10984,24 +11929,24 @@ export const testData = { ], [ 0.0, - 1.0, + 0.0, 0.0, 0.0, 1.0 ], [ + 1.0, 0.0, - 0.0, - 0.0, + 1.0, 0.0, 1.0 ], [ 1.0, 0.0, - 0.0, - 0.0, - 0.0 + 1.0, + 1.0, + 1.0 ] ] ] @@ -11014,116 +11959,116 @@ export const testData = { "input": [ [ [ - 0.391838014125824, - 0.27027666568756104, - -1.9761329889297485, - -0.6592251062393188, - -0.6763451099395752 + 1.1780027151107788, + 0.3302285671234131, + 0.3409285247325897, + 0.0966181680560112, + 0.8048174381256104 ], [ - 0.07715956121683121, - -0.3971971273422241, - -0.3989383280277252, - -0.23806536197662354, - -0.38905683159828186 + -0.9308503866195679, + -0.7495615482330322, + -1.1345824003219604, + 1.743110179901123, + 0.24290774762630463 ], [ - -0.3005983531475067, - -0.04975222051143646, - 1.6682186126708984, - 0.7086811661720276, - 0.987306535243988 + 0.2789574861526489, + 0.3315619230270386, + -0.05199375003576279, + -0.38996851444244385, + 0.45961233973503113 ], [ - -0.662408173084259, - -0.4409155547618866, - -1.6116207838058472, - 0.7781904339790344, - -0.865123450756073 + 1.5001028776168823, + 0.4969956576824188, + 0.8539602756500244, + -1.2495394945144653, + -1.8244128227233887 ] ], [ [ - -0.41890090703964233, - 0.9132878184318542, - 0.2694464921951294, - 0.020374706014990807, - -0.9279459714889526 + 1.9353760480880737, + 0.32966846227645874, + -0.5037038922309875, + 0.5824847221374512, + -0.04406149685382843 ], [ - -1.0296690464019775, - -1.044813632965088, - -0.8124385476112366, - 0.49416670203208923, - 1.2590702772140503 + 0.26977765560150146, + -1.149574875831604, + 0.5576037764549255, + -0.4423902630805969, + -1.1938692331314087 ], [ - 0.06191536784172058, - -1.3849509954452515, - 0.28555789589881897, - 0.27377936244010925, - -0.7898518443107605 + 0.5121238231658936, + 0.3450745940208435, + 1.2737618684768677, + -0.5269590616226196, + 0.36447712779045105 ], [ - -0.42242521047592163, - 2.0086865425109863, - -0.6715307831764221, - -2.07552170753479, - -0.09107904881238937 + -1.3918713331222534, + -0.13599461317062378, + 0.5021628141403198, + 0.3100223243236542, + 0.08071848005056381 ] ], [ [ - -1.6961005926132202, - -0.42137637734413147, - -1.1771284341812134, - -0.762600839138031, - -2.5596771240234375 + 0.2132561206817627, + -0.21911364793777466, + 1.0261167287826538, + -0.15927140414714813, + 0.12461294233798981 ], [ - -0.4311526417732239, - 0.7832211852073669, - 0.27603602409362793, - 0.3852384686470032, - 0.8465394377708435 + 1.5179888010025024, + 0.2487545758485794, + -0.9334361553192139, + 1.019239902496338, + 0.0731339082121849 ], [ - 0.12128926813602448, - 0.44558772444725037, - -0.10837887972593307, - 0.9687615633010864, - -1.8719896078109741 + -0.531711220741272, + -0.03542341664433479, + -0.5915296077728271, + -0.014602077193558216, + 0.2609618306159973 ], [ - -0.5508694648742676, - 0.14841115474700928, - 0.6105049252510071, - -0.44323164224624634, - 1.2706385850906372 + 0.1303926557302475, + 1.2057738304138184, + 2.191358804702759, + -0.9426639676094055, + -0.3424133360385895 ] ] ], "expected_output": [ [ - -0.662408173084259, - -0.4409155547618866, - -1.9761329889297485, - -0.6592251062393188, - -0.865123450756073 + -0.9308503866195679, + -0.7495615482330322, + -1.1345824003219604, + -1.2495394945144653, + -1.8244128227233887 ], [ - -1.0296690464019775, - -1.3849509954452515, - -0.8124385476112366, - -2.07552170753479, - -0.9279459714889526 + -1.3918713331222534, + -1.149574875831604, + -0.5037038922309875, + -0.5269590616226196, + -1.1938692331314087 ], [ - -1.6961005926132202, - -0.42137637734413147, - -1.1771284341812134, - -0.762600839138031, - -2.5596771240234375 + -0.531711220741272, + -0.21911364793777466, + -0.9334361553192139, + -0.9426639676094055, + -0.3424133360385895 ] ], "expected_grad": [ @@ -11131,14 +12076,14 @@ export const testData = { [ 0.0, 0.0, - 1.0, - 1.0, + 0.0, + 0.0, 0.0 ], [ - 0.0, - 0.0, - 0.0, + 1.0, + 1.0, + 1.0, 0.0, 0.0 ], @@ -11150,10 +12095,10 @@ export const testData = { 0.0 ], [ - 1.0, - 1.0, 0.0, 0.0, + 0.0, + 1.0, 1.0 ] ], @@ -11161,49 +12106,49 @@ export const testData = { [ 0.0, 0.0, + 1.0, 0.0, - 0.0, - 1.0 + 0.0 ], [ - 1.0, 0.0, 1.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ 0.0, - 1.0, 0.0, 0.0, + 1.0, 0.0 ], [ + 1.0, 0.0, 0.0, 0.0, - 1.0, 0.0 ] ], [ [ + 0.0, 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + 0.0, + 0.0, + 0.0 ], [ 0.0, 0.0, - 0.0, + 1.0, 0.0, 0.0 ], [ - 0.0, + 1.0, 0.0, 0.0, 0.0, @@ -11213,8 +12158,8 @@ export const testData = { 0.0, 0.0, 0.0, - 0.0, - 0.0 + 1.0, + 1.0 ] ] ] @@ -11227,139 +12172,132 @@ export const testData = { "input": [ [ [ - -1.0289336442947388, - 0.42619314789772034, - -1.3302918672561646, - -0.7120002508163452, - 1.0063550472259521 + 1.2685400247573853, + 0.1908181607723236, + 0.6423386931419373, + 0.5231516361236572, + 0.3537774980068207 ], [ - 0.7243992686271667, - -0.7196370363235474, - 0.6451484560966492, - -0.8696923851966858, - -0.8558129668235779 + 0.14756281673908234, + -0.6777421832084656, + -0.14288291335105896, + 0.918861985206604, + 0.15021729469299316 ], [ - 0.10319733619689941, - 0.02185261994600296, - -0.6163969039916992, - -0.5053693056106567, - 0.353022038936615 + -0.7345491647720337, + 1.491151213645935, + -1.0409657955169678, + 0.9087132811546326, + 0.3067242503166199 ], [ - 0.4127030372619629, - -0.649102509021759, - 1.3514323234558105, - 0.1669526845216751, - 0.2536453902721405 + 2.699211597442627, + -1.8668535947799683, + 1.0313161611557007, + -1.0959745645523071, + -1.1971251964569092 ] ], [ [ - 0.9374377131462097, - 2.011122703552246, - -0.32855224609375, - 0.6405972242355347, - 1.2246845960617065 + 0.3215359151363373, + -0.21750344336032867, + 0.8391018509864807, + -1.0961977243423462, + 1.1836506128311157 ], [ - 0.5188621282577515, - 0.43879711627960205, - -0.203304260969162, - -0.8538898825645447, - 2.200573205947876 + -1.63896906375885, + -0.5325616598129272, + -0.04153263941407204, + 0.8015749454498291, + -0.6946583986282349 ], [ - -0.02216072380542755, - 0.4223840832710266, - 1.257797122001648, - -0.5768603682518005, - -0.7109366059303284 + 0.20143039524555206, + -0.9889429807662964, + 0.20942160487174988, + 0.9820282459259033, + -1.3028837442398071 ], [ - -0.7689208388328552, - -1.3047925233840942, - 0.5878376364707947, - 0.10670913010835648, - 0.1493469625711441 + -0.561603844165802, + 0.8338823318481445, + -0.26739558577537537, + 0.23192813992500305, + 1.012840986251831 ] ], [ [ - -0.9368554949760437, - 0.11115618795156479, - -0.23906701803207397, - -0.18269838392734528, - -0.35426023602485657 + -1.4937485456466675, + 0.9061921834945679, + -1.4567253589630127, + 1.2727082967758179, + 1.6362823247909546 ], [ - 1.3937491178512573, - -1.6012654304504395, - -0.9598016738891602, - 0.36583781242370605, - -0.7097951173782349 + -0.9645407795906067, + 1.1407610177993774, + 0.41566601395606995, + 2.026231527328491, + -1.0126259326934814 ], [ - -0.7645633816719055, - 0.19768379628658295, - -0.5498691201210022, - 0.25587576627731323, - 0.017203141003847122 + 0.9119246602058411, + -0.28909119963645935, + -0.39347609877586365, + 0.4535541534423828, + -1.1785883903503418 ], [ - -0.47457176446914673, - 1.916212558746338, - -0.9796661734580994, - -0.5351609587669373, - -0.33613622188568115 + 0.789819061756134, + 1.1420683860778809, + 0.5569579005241394, + 0.6643039584159851, + -0.19934415817260742 ] ] ], "expected_output": [ [ [ - -1.0289336442947388, - -0.7196370363235474, - -1.3302918672561646, - -0.8696923851966858, - -0.8558129668235779 + -0.7345491647720337, + -1.8668535947799683, + -1.0409657955169678, + -1.0959745645523071, + -1.1971251964569092 ] ], [ [ - -0.7689208388328552, - -1.3047925233840942, - -0.32855224609375, - -0.8538898825645447, - -0.7109366059303284 + -1.63896906375885, + -0.9889429807662964, + -0.26739558577537537, + -1.0961977243423462, + -1.3028837442398071 ] ], [ [ - -0.9368554949760437, - -1.6012654304504395, - -0.9796661734580994, - -0.5351609587669373, - -0.7097951173782349 + -1.4937485456466675, + -0.28909119963645935, + -1.4567253589630127, + 0.4535541534423828, + -1.1785883903503418 ] ] ], "expected_grad": [ [ [ - 1.0, 0.0, - 1.0, 0.0, - 0.0 - ], - [ 0.0, - 1.0, 0.0, - 1.0, - 1.0 + 0.0 ], [ 0.0, @@ -11369,40 +12307,47 @@ export const testData = { 0.0 ], [ + 1.0, 0.0, + 1.0, 0.0, + 0.0 + ], + [ 0.0, + 1.0, 0.0, - 0.0 + 1.0, + 1.0 ] ], [ [ 0.0, 0.0, - 1.0, 0.0, + 1.0, 0.0 ], [ + 1.0, 0.0, 0.0, 0.0, - 1.0, 0.0 ], [ 0.0, - 0.0, + 1.0, 0.0, 0.0, 1.0 ], [ - 1.0, - 1.0, 0.0, 0.0, + 1.0, + 0.0, 0.0 ] ], @@ -11410,29 +12355,29 @@ export const testData = { [ 1.0, 0.0, - 0.0, + 1.0, 0.0, 0.0 ], [ 0.0, - 1.0, 0.0, 0.0, - 1.0 + 0.0, + 0.0 ], [ 0.0, + 1.0, 0.0, - 0.0, - 0.0, - 0.0 + 1.0, + 1.0 ], [ 0.0, 0.0, - 1.0, - 1.0, + 0.0, + 0.0, 0.0 ] ] @@ -11446,121 +12391,121 @@ export const testData = { "input": [ [ [ - -1.1161184310913086, - 0.14304663240909576, - -0.32119596004486084, - 0.8723122477531433, - -0.49654293060302734 + -0.9770270586013794, + -0.584597110748291, + -1.5499167442321777, + 0.3021530210971832, + -0.34727850556373596 ], [ - 0.05724964290857315, - 0.47545480728149414, - -0.4795941412448883, - -1.4507311582565308, - -0.4242385923862457 + -0.20263050496578217, + -0.27478426694869995, + -0.017359629273414612, + -0.6773730516433716, + 0.6478610038757324 ], [ - 0.4160293638706207, - 0.009711174294352531, - -0.23619726300239563, - -1.4613094329833984, - -0.3903917670249939 + -0.9755827188491821, + 1.8391462564468384, + -0.0034865080378949642, + 0.4103865623474121, + 1.752099633216858 ], [ - -0.14734792709350586, - 1.1412599086761475, - 0.2379687875509262, - 2.7321791648864746, - -0.36258259415626526 + 0.66091388463974, + -1.0182898044586182, + -1.101527452468872, + 0.9167301654815674, + 1.1085376739501953 ] ], [ [ - 0.48279520869255066, - 1.2329903841018677, - -0.7630826830863953, - -1.0484687089920044, - 1.5664156675338745 + -2.0887160301208496, + 2.1544744968414307, + 0.9984968304634094, + -0.013719181530177593, + -0.9246350526809692 ], [ - -0.22833675146102905, - -0.4468657970428467, - -0.5083827376365662, - -0.3354898989200592, - 1.5477113723754883 + -1.5019725561141968, + 0.7051315307617188, + 0.37148424983024597, + -0.714340090751648, + -0.15940190851688385 ], [ - 0.6345664858818054, - -1.4856488704681396, - -0.8773688077926636, - -0.34968942403793335, - -0.6551162004470825 + 0.34379199147224426, + 0.4355435073375702, + -0.2341606765985489, + 0.18855510652065277, + 0.019730882719159126 ], [ - -0.8283827304840088, - 0.4841196835041046, - 1.1001728773117065, - 0.45901453495025635, - 0.26477116346359253 + -0.24155908823013306, + -1.8511996269226074, + 0.2684777081012726, + -0.30269020795822144, + -0.3692476451396942 ] ], [ [ - -1.5105466842651367, - -0.6389901041984558, - -1.726313591003418, - 0.36199653148651123, - 1.421317458152771 + -0.8595789074897766, + 0.2909909188747406, + 0.6529440879821777, + 2.0979738235473633, + 0.43178966641426086 ], [ - -1.9939244985580444, - 0.07572164386510849, - -0.5763441920280457, - -0.5786607265472412, - -1.460897445678711 + -1.228909969329834, + -0.06794015318155289, + -2.2453958988189697, + 1.5783367156982422, + -0.5161778330802917 ], [ - 1.426108717918396, - 1.2192761898040771, - 1.2584720849990845, - -0.5713672637939453, - 0.7841975092887878 + -0.19803878664970398, + 0.8383589386940002, + 1.144734501838684, + -1.3692904710769653, + -0.3902406692504883 ], [ - 0.40953299403190613, - 0.3059408664703369, - -0.23000852763652802, - 0.5811874866485596, - -0.6039872765541077 + 0.950104296207428, + -2.147958517074585, + -0.06174112856388092, + 0.2618931531906128, + 0.4153856635093689 ] ] ], "expected_output": [ [ - -1.1161184310913086, - -1.4507311582565308, - -1.4613094329833984, - -0.36258259415626526 + -1.5499167442321777, + -0.6773730516433716, + -0.9755827188491821, + -1.101527452468872 ], [ - -1.0484687089920044, - -0.5083827376365662, - -1.4856488704681396, - -0.8283827304840088 + -2.0887160301208496, + -1.5019725561141968, + -0.2341606765985489, + -1.8511996269226074 ], [ - -1.726313591003418, - -1.9939244985580444, - -0.5713672637939453, - -0.6039872765541077 + -0.8595789074897766, + -2.2453958988189697, + -1.3692904710769653, + -2.147958517074585 ] ], "expected_grad": [ [ [ - 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0 ], @@ -11572,45 +12517,45 @@ export const testData = { 0.0 ], [ + 1.0, 0.0, 0.0, 0.0, - 1.0, 0.0 ], [ 0.0, 0.0, + 1.0, 0.0, - 0.0, - 1.0 + 0.0 ] ], [ [ + 1.0, 0.0, 0.0, 0.0, - 1.0, 0.0 ], [ + 1.0, 0.0, 0.0, - 1.0, 0.0, 0.0 ], [ 0.0, - 1.0, 0.0, + 1.0, 0.0, 0.0 ], [ - 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0 @@ -11618,16 +12563,16 @@ export const testData = { ], [ [ + 1.0, 0.0, 0.0, - 1.0, 0.0, 0.0 ], [ - 1.0, 0.0, 0.0, + 1.0, 0.0, 0.0 ], @@ -11640,10 +12585,10 @@ export const testData = { ], [ 0.0, + 1.0, 0.0, 0.0, - 0.0, - 1.0 + 0.0 ] ] ] @@ -11656,136 +12601,136 @@ export const testData = { "input": [ [ [ - 0.3473411798477173, - -0.2978079319000244, - 0.2347842901945114, - -0.10979556292295456, - -1.323111653327942 + 0.5631878972053528, + 0.19998317956924438, + 0.8093208074569702, + -0.5293470621109009, + 0.448284387588501 ], [ - -1.7342220544815063, - 1.767889142036438, - -0.7062178254127502, - -0.7460381984710693, - 1.4306825399398804 + -0.8013262152671814, + 0.6317405700683594, + 1.3970056772232056, + -1.3542675971984863, + 0.13657432794570923 ], [ - 1.9143685102462769, - -1.5510687828063965, - -1.430296540260315, - 0.2052573710680008, - 0.9466792941093445 + 0.8511560559272766, + 1.1925286054611206, + 0.5439687371253967, + -1.2077754735946655, + 1.1914323568344116 ], [ - -1.166908860206604, - 0.6379362940788269, - 1.0802478790283203, - -1.2114757299423218, - 0.6006536483764648 + 1.2834670543670654, + 0.8253968954086304, + 1.7004607915878296, + 0.9272356629371643, + 0.026323553174734116 ] ], [ [ - 0.07689109444618225, - -0.8847613334655762, - -0.7983061075210571, - 0.26852527260780334, - -1.751050591468811 + 0.7056452035903931, + 1.0615094900131226, + -1.6115124225616455, + 0.45299890637397766, + -1.1804884672164917 ], [ - -0.028895698487758636, - -0.6638352870941162, - -1.484498143196106, - 0.0809166356921196, - -0.5466802716255188 + 0.5873482823371887, + -0.1269814372062683, + 0.05342012271285057, + 1.0922929048538208, + -1.3024108409881592 ], [ - 0.3434705436229706, - 0.6989194750785828, - -1.3570187091827393, - -1.3314623832702637, - 0.5109858512878418 + 1.3521305322647095, + -1.1749324798583984, + 0.11568229645490646, + 0.21853865683078766, + 1.1232846975326538 ], [ - -1.461991786956787, - 1.4522364139556885, - 1.4651625156402588, - 1.0964486598968506, - 0.831229567527771 + -0.7424628138542175, + 0.22881479561328888, + -0.4537980556488037, + 0.797391414642334, + 1.4051463603973389 ] ], [ [ - 0.061060722917318344, - -0.6163668632507324, - 1.015307068824768, - 0.595319926738739, - -0.008159872144460678 + -0.5578140616416931, + 2.0406908988952637, + -2.4602458477020264, + 1.2475563287734985, + 0.46312710642814636 ], [ - -0.7545639276504517, - 2.069274663925171, - -0.17883431911468506, - 0.809699535369873, - -0.4801141619682312 + 0.3421548902988434, + -0.1932428628206253, + 0.04506998881697655, + 0.10006450116634369, + -0.3069831430912018 ], [ - -0.6375554203987122, - 1.179660439491272, - -0.6031109094619751, - 1.404761552810669, - 0.22640825808048248 + -0.7462528347969055, + -1.4819915294647217, + -0.782849133014679, + -0.3068717420101166, + 1.822840690612793 ], [ - 0.7069153189659119, - 0.660965621471405, - 0.4534458816051483, - -1.3935517072677612, - 0.6880179643630981 + 0.24596092104911804, + 0.26649534702301025, + -0.518925130367279, + -2.0522587299346924, + -1.131065011024475 ] ] ], "expected_output": [ [ [ - -1.323111653327942 + -0.5293470621109009 ], [ - -1.7342220544815063 + -1.3542675971984863 ], [ - -1.5510687828063965 + -1.2077754735946655 ], [ - -1.2114757299423218 + 0.026323553174734116 ] ], [ [ - -1.751050591468811 + -1.6115124225616455 ], [ - -1.484498143196106 + -1.3024108409881592 ], [ - -1.3570187091827393 + -1.1749324798583984 ], [ - -1.461991786956787 + -0.7424628138542175 ] ], [ [ - -0.6163668632507324 + -2.4602458477020264 ], [ - -0.7545639276504517 + -0.3069831430912018 ], [ - -0.6375554203987122 + -1.4819915294647217 ], [ - -1.3935517072677612 + -2.0522587299346924 ] ] ], @@ -11795,51 +12740,51 @@ export const testData = { 0.0, 0.0, 0.0, - 0.0, - 1.0 + 1.0, + 0.0 ], [ - 1.0, 0.0, 0.0, 0.0, + 1.0, 0.0 ], [ 0.0, - 1.0, 0.0, 0.0, + 1.0, 0.0 ], [ 0.0, 0.0, 0.0, - 1.0, - 0.0 + 0.0, + 1.0 ] ], [ [ 0.0, 0.0, + 1.0, 0.0, - 0.0, - 1.0 + 0.0 ], [ 0.0, 0.0, - 1.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ - 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0 ], [ @@ -11853,21 +12798,21 @@ export const testData = { [ [ 0.0, - 1.0, 0.0, + 1.0, 0.0, 0.0 ], [ - 1.0, 0.0, 0.0, 0.0, - 0.0 + 0.0, + 1.0 ], [ - 1.0, 0.0, + 1.0, 0.0, 0.0, 0.0 @@ -11890,232 +12835,232 @@ export const testData = { "out_features": 5, "input": [ [ - 1.1283513307571411, - -0.7886322736740112, - -0.038704462349414825, - 0.6835862398147583, - -0.427450567483902, - -0.7580193877220154, - 0.061286136507987976, - -0.5027238726615906, - -0.27131080627441406, - -0.9536606073379517 - ], - [ - -0.6736571192741394, - 1.259739637374878, - -0.23389844596385956, - -0.848857581615448, - -0.3439099192619324, - -0.7324386835098267, - -0.5639234185218811, - 0.04004557058215141, - -0.4779359698295593, - 2.1152544021606445 - ], - [ - -0.9166030287742615, - 0.21347090601921082, - 0.3113662600517273, - -0.5756134390830994, - 0.3273322880268097, - 0.6297365427017212, - 1.879461407661438, - -0.04444850981235504, - -0.5365133285522461, - 1.4397056102752686 + 1.995280146598816, + -0.6346070170402527, + 1.0690128803253174, + 1.160980463027954, + -1.7790907621383667, + 0.8086466789245605, + -0.1060129776597023, + 2.2590320110321045, + 0.3341250419616699, + -0.27466103434562683 + ], + [ + -0.29712751507759094, + -0.5143458247184753, + 1.5861903429031372, + 1.3935821056365967, + -0.08091596513986588, + -0.561027467250824, + -0.4829641580581665, + 0.4769587814807892, + 0.17047974467277527, + 0.845003604888916 + ], + [ + 1.797692060470581, + 1.4310468435287476, + -0.1232481449842453, + 0.0116643775254488, + 0.3026885390281677, + -0.7567965984344482, + 0.7330871224403381, + -1.003272533416748, + 0.2109839767217636, + 1.4640601873397827 ] ], "weight": [ [ - -0.014760938473045826, - -0.30939099192619324, - -0.22409461438655853, - -0.22140328586101532, - -0.10767091810703278, - -0.16022561490535736, - 0.048675112426280975, - 0.1933113932609558, - 0.2384445071220398, - 0.09963622689247131 - ], - [ - -0.002092500915750861, - -0.056352920830249786, - 0.2147195190191269, - -0.18111325800418854, - 0.22857233881950378, - -0.30446791648864746, - -0.23602305352687836, - 0.08388392627239227, - -0.1302446573972702, - 0.058998893946409225 - ], - [ - 0.2755293548107147, - 0.1444312036037445, - 0.3095139265060425, - -0.13394437730312347, - -0.15100832283496857, - -0.04015190899372101, - -0.06368821114301682, - -0.13909903168678284, - -0.01963338814675808, - 0.2856864631175995 - ], - [ - -0.17334267497062683, - 0.1775881052017212, - 0.14690226316452026, - 0.18313315510749817, - 0.08531231433153152, - -0.11681929230690002, - 0.13051147758960724, - -0.14894190430641174, - -0.19410604238510132, - 0.29560813307762146 - ], - [ - 0.26211726665496826, - -0.2285388559103012, - 0.25685709714889526, - 0.06557296216487885, - 0.081057608127594, - 0.304801344871521, - -0.01660444773733616, - -0.10057568550109863, - 0.19852009415626526, - -0.08168602734804153 + -0.24328012764453888, + 0.028091339394450188, + -0.16780336201190948, + -0.06218525767326355, + -0.04895494133234024, + 0.015718938782811165, + -0.27727454900741577, + 0.2699316143989563, + -0.1345617175102234, + 0.09880602359771729 + ], + [ + 0.2177683264017105, + 0.12743021547794342, + 0.2214605212211609, + 0.17856846749782562, + 0.23155508935451508, + 0.06674247980117798, + 0.2019743025302887, + -0.1374560296535492, + -0.17039762437343597, + 0.15100044012069702 + ], + [ + 0.08297339081764221, + -0.011858473531901836, + -0.26674091815948486, + 0.1033318042755127, + 0.20483756065368652, + -0.036509934812784195, + 0.07265040278434753, + 0.14077845215797424, + -0.312299907207489, + -0.05202847719192505 + ], + [ + -0.11730943620204926, + -0.1616298258304596, + 0.19328103959560394, + 0.3135358691215515, + 0.050457291305065155, + 0.19681504368782043, + -0.2346036732196808, + 0.055711012333631516, + -0.04089835286140442, + -0.1950366348028183 + ], + [ + 0.06484019756317139, + 0.10066336393356323, + -0.015273772180080414, + 0.134284108877182, + 0.15182378888130188, + 0.2868318259716034, + 0.018331248313188553, + 0.011266625486314297, + -0.004526200238615274, + 0.04364045336842537 ] ], "bias": [ - -0.0759141594171524, - -0.12752050161361694, - 0.3112594485282898, - 0.15089142322540283, - -0.05126401409506798 + -0.2050478756427765, + -0.03892422094941139, + -0.2674124538898468, + -0.22181136906147003, + -0.26935896277427673 ], "expected_output": [ [ - -0.07768147438764572, - -0.16203129291534424, - 0.29859665036201477, - -0.15953725576400757, - 0.2675035297870636 + -0.2929801046848297, + -0.029548827558755875, + -0.4331992268562317, + 0.4773373007774353, + -0.0924459844827652 ], [ - 0.016104310750961304, - 0.37431609630584717, - 1.074267864227295, - 0.9962825179100037, - -1.1449365615844727 + -0.18168585002422333, + 0.31021445989608765, + -0.6263059377670288, + 0.49329322576522827, + -0.3180721402168274 ], [ - -0.10849833488464355, - -0.3759457468986511, - 0.49661877751350403, - 1.024014949798584, - -0.33044812083244324 + -0.9667624235153198, + 1.0003747940063477, + -0.24155186116695404, + -1.339890480041504, + -0.11133930087089539 ] ], "expected_grad_input": [ [ - 0.34745049476623535, - -0.27226346731185913, - 0.7038981914520264, - -0.28775477409362793, - 0.13626301288604736, - -0.31686341762542725, - -0.13712912797927856, - -0.11142130196094513, - 0.09298050403594971, - 0.6582436561584473 - ], - [ - 0.34745049476623535, - -0.27226346731185913, - 0.7038981914520264, - -0.28775477409362793, - 0.13626301288604736, - -0.31686341762542725, - -0.13712912797927856, - -0.11142130196094513, - 0.09298050403594971, - 0.6582436561584473 - ], - [ - 0.34745049476623535, - -0.27226346731185913, - 0.7038981914520264, - -0.28775477409362793, - 0.13626301288604736, - -0.31686341762542725, - -0.13712912797927856, - -0.11142130196094513, - 0.09298050403594971, - 0.6582436561584473 + 0.004992350935935974, + 0.08269661664962769, + -0.03507646173238754, + 0.6675350666046143, + 0.5897188186645508, + 0.5295983552932739, + -0.21892227232456207, + 0.34023168683052063, + -0.6626837849617004, + 0.04638180509209633 + ], + [ + 0.004992350935935974, + 0.08269661664962769, + -0.03507646173238754, + 0.6675350666046143, + 0.5897188186645508, + 0.5295983552932739, + -0.21892227232456207, + 0.34023168683052063, + -0.6626837849617004, + 0.04638180509209633 + ], + [ + 0.004992350935935974, + 0.08269661664962769, + -0.03507646173238754, + 0.6675350666046143, + 0.5897188186645508, + 0.5295983552932739, + -0.21892227232456207, + 0.34023168683052063, + -0.6626837849617004, + 0.04638180509209633 ] ], "expected_grad_weight": [ [ - -0.46190881729125977, - 0.6845782995223999, - 0.038763344287872314, - -0.7408847808837891, - -0.44402822852134705, - -0.8607214689254761, - 1.376824140548706, - -0.5071268081665039, - -1.2857601642608643, - 2.601299285888672 - ], - [ - -0.46190881729125977, - 0.6845782995223999, - 0.038763344287872314, - -0.7408847808837891, - -0.44402822852134705, - -0.8607214689254761, - 1.376824140548706, - -0.5071268081665039, - -1.2857601642608643, - 2.601299285888672 - ], - [ - -0.46190881729125977, - 0.6845782995223999, - 0.038763344287872314, - -0.7408847808837891, - -0.44402822852134705, - -0.8607214689254761, - 1.376824140548706, - -0.5071268081665039, - -1.2857601642608643, - 2.601299285888672 - ], - [ - -0.46190881729125977, - 0.6845782995223999, - 0.038763344287872314, - -0.7408847808837891, - -0.44402822852134705, - -0.8607214689254761, - 1.376824140548706, - -0.5071268081665039, - -1.2857601642608643, - 2.601299285888672 - ], - [ - -0.46190881729125977, - 0.6845782995223999, - 0.038763344287872314, - -0.7408847808837891, - -0.44402822852134705, - -0.8607214689254761, - 1.376824140548706, - -0.5071268081665039, - -1.2857601642608643, - 2.601299285888672 + 3.495844841003418, + 0.28209400177001953, + 2.5319552421569824, + 2.5662269592285156, + -1.5573182106018066, + -0.5091773867607117, + 0.14410996437072754, + 1.7327182292938232, + 0.7155888080596924, + 2.034402847290039 + ], + [ + 3.495844841003418, + 0.28209400177001953, + 2.5319552421569824, + 2.5662269592285156, + -1.5573182106018066, + -0.5091773867607117, + 0.14410996437072754, + 1.7327182292938232, + 0.7155888080596924, + 2.034402847290039 + ], + [ + 3.495844841003418, + 0.28209400177001953, + 2.5319552421569824, + 2.5662269592285156, + -1.5573182106018066, + -0.5091773867607117, + 0.14410996437072754, + 1.7327182292938232, + 0.7155888080596924, + 2.034402847290039 + ], + [ + 3.495844841003418, + 0.28209400177001953, + 2.5319552421569824, + 2.5662269592285156, + -1.5573182106018066, + -0.5091773867607117, + 0.14410996437072754, + 1.7327182292938232, + 0.7155888080596924, + 2.034402847290039 + ], + [ + 3.495844841003418, + 0.28209400177001953, + 2.5319552421569824, + 2.5662269592285156, + -1.5573182106018066, + -0.5091773867607117, + 0.14410996437072754, + 1.7327182292938232, + 0.7155888080596924, + 2.034402847290039 ] ], "expected_grad_bias": [ @@ -12133,147 +13078,147 @@ export const testData = { "input": [ [ [ - 0.648219883441925, - 1.850017786026001, - -0.8941981196403503, - 1.5534266233444214 + -0.3233233392238617, + -0.3046680688858032, + -0.22401957213878632, + 0.2504769563674927 ], [ - 0.17955924570560455, - -1.1150798797607422, - -0.9356100559234619, - -0.41874298453330994 + 1.7058311700820923, + 1.3944706916809082, + 1.136904239654541, + 1.1797000169754028 ], [ - -0.20334042608737946, - -1.6620466709136963, - 0.8806517720222473, - 0.34086135029792786 + 0.6420789957046509, + -3.0800278186798096, + -1.3616151809692383, + -0.2960043251514435 ] ], [ [ - -0.9606906771659851, - -0.8203177452087402, - 1.1280782222747803, - 1.5793778896331787 + 1.1283513307571411, + -0.7886322736740112, + -0.038704462349414825, + 0.6835862398147583 ], [ - -1.171597957611084, - 1.6002179384231567, - -0.3856680691242218, - 1.3663055896759033 + 0.5444626212120056, + 0.454408198595047, + 0.9106372594833374, + 0.9990993142127991 ], [ - -1.4047266244888306, - -0.5991130471229553, - -1.49435293674469, - 1.004637360572815 + -0.27131080627441406, + -0.9536606073379517, + -0.6736571192741394, + 1.259739637374878 ] ] ], "weight": [ [ - 0.05675828456878662, - -0.4988272786140442, - 0.00441056489944458, - 0.38382667303085327 + 0.13263213634490967, + -0.20593488216400146, + 0.0932854413986206, + 0.43565016984939575 ], [ - 0.05767112970352173, - 0.11913007497787476, - -0.4709845185279846, - -0.09404438734054565 + 0.22836577892303467, + 0.4893844723701477, + -0.21178466081619263, + -0.23876512050628662 ] ], "bias": [ - 0.29504191875457764, - -0.3666014075279236 + -0.06348574161529541, + -0.10069990158081055 ], "expected_output": [ [ [ - 0.0012971162796020508, - 0.16623735427856445 + 0.04459554702043533, + -0.33599695563316345 ], [ - 0.6966143846511841, - -0.009047269821166992 + 0.49558526277542114, + 0.44883573055267334 ], [ - 1.2472907304763794, - -1.0231574773788452 + 0.39998650550842285, + -1.1023441553115845 ] ], [ [ - 1.2608944177627563, - -1.1995689868927002 + 0.5427707433700562, + -0.3839870095252991 ], [ - -0.04696476459503174, - -0.1903843879699707 + 0.4353559911251068, + -0.18539203703403473 ], [ - 0.8931816816329956, - 0.09035056829452515 + 0.5828850865364075, + -0.7874763607978821 ] ] ], "expected_grad_input": [ [ [ - 0.11442941427230835, - -0.37969720363616943, - -0.46657395362854004, - 0.2897822856903076 + 0.36099791526794434, + 0.28344959020614624, + -0.11849921941757202, + 0.19688504934310913 ], [ - 0.11442941427230835, - -0.37969720363616943, - -0.46657395362854004, - 0.2897822856903076 + 0.36099791526794434, + 0.28344959020614624, + -0.11849921941757202, + 0.19688504934310913 ], [ - 0.11442941427230835, - -0.37969720363616943, - -0.46657395362854004, - 0.2897822856903076 + 0.36099791526794434, + 0.28344959020614624, + -0.11849921941757202, + 0.19688504934310913 ] ], [ [ - 0.11442941427230835, - -0.37969720363616943, - -0.46657395362854004, - 0.2897822856903076 + 0.36099791526794434, + 0.28344959020614624, + -0.11849921941757202, + 0.19688504934310913 ], [ - 0.11442941427230835, - -0.37969720363616943, - -0.46657395362854004, - 0.2897822856903076 + 0.36099791526794434, + 0.28344959020614624, + -0.11849921941757202, + 0.19688504934310913 ], [ - 0.11442941427230835, - -0.37969720363616943, - -0.46657395362854004, - 0.2897822856903076 + 0.36099791526794434, + 0.28344959020614624, + -0.11849921941757202, + 0.19688504934310913 ] ] ], "expected_grad_weight": [ [ - -2.91257643699646, - -0.7463215589523315, - -1.701099157333374, - 5.425865650177002 + 3.4260900020599365, + -3.2781100273132324, + -0.250454843044281, + 4.076597690582275 ], [ - -2.91257643699646, - -0.7463215589523315, - -1.701099157333374, - 5.425865650177002 + 3.4260900020599365, + -3.2781100273132324, + -0.250454843044281, + 4.076597690582275 ] ], "expected_grad_bias": [ @@ -12291,70 +13236,70 @@ export const testData = { }, "initial_weight": [ [ - -0.5548203587532043, - -0.16434448957443237, - -0.4784829616546631 + 1.1711158752441406, + -0.2590734362602234, + -0.3033114969730377 ], [ - 0.38463443517684937, - -0.3245149850845337, - -1.5829708576202393 + 0.2349793165922165, + 1.0358152389526367, + 0.715836763381958 ], [ - -0.6101211309432983, - 0.2677954137325287, - 1.1987781524658203 + -0.7037585973739624, + -0.284278929233551, + 0.7185912728309631 ] ], "input_x": [ [ - 1.122973918914795, - 1.4562538862228394, - 0.9092239141464233 + 1.8401010036468506, + 0.04152654483914375, + -1.7044862508773804 ], [ - 0.9442354440689087, - 2.31821870803833, - 0.64822918176651 + -0.3476502001285553, + -0.3426065444946289, + 0.11469119042158127 ], [ - -0.4594375491142273, - 0.8558579683303833, - 1.3270264863967896 + -0.4225151538848877, + 0.7643097639083862, + -0.5040589570999146 ] ], "expected_grad": [ [ - 1.122973918914795, - 1.4562538862228394, - 0.9092239141464233 + 1.8401010036468506, + 0.04152654483914375, + -1.7044862508773804 ], [ - 0.9442354440689087, - 2.31821870803833, - 0.64822918176651 + -0.3476502001285553, + -0.3426065444946289, + 0.11469119042158127 ], [ - -0.4594375491142273, - 0.8558579683303833, - 1.3270264863967896 + -0.4225151538848877, + 0.7643097639083862, + -0.5040589570999146 ] ], "expected_updated_weight": [ [ - -0.6671177744865417, - -0.30996987223625183, - -0.5694053769111633 + 0.9871057868003845, + -0.26322609186172485, + -0.1328628659248352 ], [ - 0.29021090269088745, - -0.5563368797302246, - -1.6477937698364258 + 0.269744336605072, + 1.0700758695602417, + 0.7043676376342773 ], [ - -0.564177393913269, - 0.18220961093902588, - 1.0660754442214966 + -0.6615070700645447, + -0.36070990562438965, + 0.7689971923828125 ] ] }, @@ -12367,70 +13312,70 @@ export const testData = { }, "initial_weight": [ [ - 0.9446682333946228, - -0.30597713589668274, - 0.44008857011795044 + -0.9779782891273499, + 1.0851811170578003, + 0.24460527300834656 ], [ - -0.17014701664447784, - 0.12107481062412262, - 0.10815810412168503 + 0.10595189034938812, + 0.9393600821495056, + 0.3916529417037964 ], [ - 0.5580024719238281, - -1.8953827619552612, - 0.12464731931686401 + 0.4106380343437195, + -0.0652524009346962, + 0.5183061361312866 ] ], "input_x": [ [ - -0.3046552538871765, - -0.7077358961105347, - -1.7160437107086182 + 0.05883641913533211, + 0.5554778575897217, + 1.053452968597412 ], [ - -0.5965784788131714, - -0.6017999053001404, - 0.8372399806976318 + -0.2609460651874542, + -1.6987152099609375, + -0.08697007596492767 ], [ - -0.5020561218261719, - -0.10574329644441605, - -0.16421273350715637 + 2.333068609237671, + -0.035302918404340744, + 2.392319917678833 ] ], "expected_grad": [ [ - -0.3046552538871765, - -0.7077358961105347, - -1.7160437107086182 + 0.05883641913533211, + 0.5554778575897217, + 1.053452968597412 ], [ - -0.5965784788131714, - -0.6017999053001404, - 0.8372399806976318 + -0.2609460651874542, + -1.6987152099609375, + -0.08697007596492767 ], [ - -0.5020561218261719, - -0.10574329644441605, - -0.16421273350715637 + 2.333068609237671, + -0.035302918404340744, + 2.392319917678833 ] ], "expected_updated_weight": [ [ - 0.9751337766647339, - -0.2352035492658615, - 0.6116929650306702 + -0.9838619232177734, + 1.0296332836151123, + 0.13925997912883759 ], [ - -0.11048916727304459, - 0.1812548041343689, - 0.024434104561805725 + 0.13204649090766907, + 1.1092315912246704, + 0.4003499448299408 ], [ - 0.6082080602645874, - -1.8848084211349487, - 0.14106859266757965 + 0.17733116447925568, + -0.061722107231616974, + 0.27907413244247437 ] ] }, @@ -12442,70 +13387,70 @@ export const testData = { }, "initial_weight": [ [ - -0.7310932874679565, - 0.3742406666278839, - 0.07989589124917984 + 0.861420214176178, + 1.0063271522521973, + 0.9432656168937683 ], [ - 0.8226869702339172, - 0.528905987739563, - 0.3527827858924866 + 0.22092591226100922, + -1.1125500202178955, + 0.1605069637298584 ], [ - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 + 1.8549803495407104, + -0.16434448957443237, + -0.4784829616546631 ] ], "input_x": [ [ - -1.4255669116973877, - 0.8732106685638428, - -2.0518009662628174 + 0.38463443517684937, + -0.3245149850845337, + -1.5829708576202393 ], [ - -0.9301124811172485, - 0.7590786218643188, - -0.012546157464385033 + -0.6101211309432983, + 0.2677954137325287, + 1.1987781524658203 ], [ - -0.16888298094272614, - -0.7453446984291077, - -1.6509697437286377 + 1.122973918914795, + 1.4562538862228394, + 0.9092239141464233 ] ], "expected_grad": [ [ - -1.4255669116973877, - 0.8732106685638428, - -2.0518009662628174 + 0.38463443517684937, + -0.3245149850845337, + -1.5829708576202393 ], [ - -0.9301124811172485, - 0.7590786218643188, - -0.012546157464385033 + -0.6101211309432983, + 0.2677954137325287, + 1.1987781524658203 ], [ - -0.16888298094272614, - -0.7453446984291077, - -1.6509697437286377 + 1.122973918914795, + 1.4562538862228394, + 0.9092239141464233 ] ], "expected_updated_weight": [ [ - -0.6310932636260986, - 0.2742406725883484, - 0.17989589273929596 + 0.7614202499389648, + 1.1063271760940552, + 1.0432655811309814 ], [ - 0.9226869344711304, - 0.42890599370002747, - 0.45278269052505493 + 0.32092589139938354, + -1.2125500440597534, + 0.06050696223974228 ], [ - -0.3038589358329773, - 0.5434445738792419, - -0.5249487161636353 + 1.7549803256988525, + -0.2643444836139679, + -0.578482985496521 ] ] }, @@ -12521,70 +13466,70 @@ export const testData = { }, "initial_weight": [ [ - 0.06193928048014641, - -1.7777185440063477, - -0.5515789985656738 + 0.9442354440689087, + 2.31821870803833, + 0.64822918176651 ], [ - 0.45636066794395447, - -0.9359204769134521, - 0.031871069222688675 + -0.4594375491142273, + 0.8558579683303833, + 1.3270264863967896 ], [ - 0.12983688712120056, - -0.07866957783699036, - -0.38718998432159424 + 0.9446682333946228, + -0.30597713589668274, + 0.44008857011795044 ] ], "input_x": [ [ - 0.43904364109039307, - -0.7205687761306763, - -0.5494226813316345 + -0.17014701664447784, + 0.12107481062412262, + 0.10815810412168503 ], [ - 1.25302255153656, - -1.1181309223175049, - 0.7164333462715149 + 0.5580024719238281, + -1.8953827619552612, + 0.12464731931686401 ], [ - -0.858248770236969, - 0.20800915360450745, - 0.880598783493042 + -0.3046552538871765, + -0.7077358961105347, + -1.7160437107086182 ] ], "expected_grad": [ [ - 0.43904364109039307, - -0.7205687761306763, - -0.5494226813316345 + -0.17014701664447784, + 0.12107481062412262, + 0.10815810412168503 ], [ - 1.25302255153656, - -1.1181309223175049, - 0.7164333462715149 + 0.5580024719238281, + -1.8953827619552612, + 0.12464731931686401 ], [ - -0.858248770236969, - 0.20800915360450745, - 0.880598783493042 + -0.3046552538871765, + -0.7077358961105347, + -1.7160437107086182 ] ], "expected_updated_weight": [ [ - -0.038060713559389114, - -1.6777185201644897, - -0.4515790045261383 + 1.0442354679107666, + 2.2182188034057617, + 0.5482292175292969 ], [ - 0.35636067390441895, - -0.835920512676239, - -0.06812892854213715 + -0.5594375133514404, + 0.9558579921722412, + 1.2270264625549316 ], [ - 0.22983688116073608, - -0.17866957187652588, - -0.48718997836112976 + 1.044668197631836, + -0.20597714185714722, + 0.5400885939598083 ] ] } @@ -12593,15 +13538,15 @@ export const testData = { { "test_name": "expand_1D_expand", "input": [ - 1.2542186975479126 + -0.5965784788131714 ], "expand_shape": [ 3 ], "expected_output": [ - 1.2542186975479126, - 1.2542186975479126, - 1.2542186975479126 + -0.5965784788131714, + -0.5965784788131714, + -0.5965784788131714 ], "expected_grad": [ 3.0 @@ -12610,9 +13555,9 @@ export const testData = { { "test_name": "expand_prepend_2D", "input": [ - 0.13348865509033203, - 0.39146795868873596, - 0.9119104146957397 + -0.6017999053001404, + 0.8372399806976318, + -0.5020561218261719 ], "expand_shape": [ 2, @@ -12620,14 +13565,14 @@ export const testData = { ], "expected_output": [ [ - 0.13348865509033203, - 0.39146795868873596, - 0.9119104146957397 + -0.6017999053001404, + 0.8372399806976318, + -0.5020561218261719 ], [ - 0.13348865509033203, - 0.39146795868873596, - 0.9119104146957397 + -0.6017999053001404, + 0.8372399806976318, + -0.5020561218261719 ] ], "expected_grad": [ @@ -12640,9 +13585,9 @@ export const testData = { "test_name": "expand_expand_dim_0", "input": [ [ - -0.17490753531455994, - -0.37665173411369324, - -0.9659009575843811 + -0.10574329644441605, + -0.16421273350715637, + -0.7310932874679565 ] ], "expand_shape": [ @@ -12651,24 +13596,24 @@ export const testData = { ], "expected_output": [ [ - -0.17490753531455994, - -0.37665173411369324, - -0.9659009575843811 + -0.10574329644441605, + -0.16421273350715637, + -0.7310932874679565 ], [ - -0.17490753531455994, - -0.37665173411369324, - -0.9659009575843811 + -0.10574329644441605, + -0.16421273350715637, + -0.7310932874679565 ], [ - -0.17490753531455994, - -0.37665173411369324, - -0.9659009575843811 + -0.10574329644441605, + -0.16421273350715637, + -0.7310932874679565 ], [ - -0.17490753531455994, - -0.37665173411369324, - -0.9659009575843811 + -0.10574329644441605, + -0.16421273350715637, + -0.7310932874679565 ] ], "expected_grad": [ @@ -12684,18 +13629,18 @@ export const testData = { "input": [ [ [ - 0.9704499244689941, - 0.2379537969827652, - -0.7329998016357422, - -0.7835293412208557 + 0.3742406666278839, + 0.07989589124917984, + 0.8226869702339172, + 0.528905987739563 ] ], [ [ - 0.41817715764045715, - -0.9935426712036133, - 0.88087397813797, - -0.38332679867744446 + 0.3527827858924866, + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ] ] ], @@ -12707,66 +13652,66 @@ export const testData = { "expected_output": [ [ [ - 0.9704499244689941, - 0.2379537969827652, - -0.7329998016357422, - -0.7835293412208557 + 0.3742406666278839, + 0.07989589124917984, + 0.8226869702339172, + 0.528905987739563 ], [ - 0.9704499244689941, - 0.2379537969827652, - -0.7329998016357422, - -0.7835293412208557 + 0.3742406666278839, + 0.07989589124917984, + 0.8226869702339172, + 0.528905987739563 ], [ - 0.9704499244689941, - 0.2379537969827652, - -0.7329998016357422, - -0.7835293412208557 + 0.3742406666278839, + 0.07989589124917984, + 0.8226869702339172, + 0.528905987739563 ], [ - 0.9704499244689941, - 0.2379537969827652, - -0.7329998016357422, - -0.7835293412208557 + 0.3742406666278839, + 0.07989589124917984, + 0.8226869702339172, + 0.528905987739563 ], [ - 0.9704499244689941, - 0.2379537969827652, - -0.7329998016357422, - -0.7835293412208557 + 0.3742406666278839, + 0.07989589124917984, + 0.8226869702339172, + 0.528905987739563 ] ], [ [ - 0.41817715764045715, - -0.9935426712036133, - 0.88087397813797, - -0.38332679867744446 + 0.3527827858924866, + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ], [ - 0.41817715764045715, - -0.9935426712036133, - 0.88087397813797, - -0.38332679867744446 + 0.3527827858924866, + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ], [ - 0.41817715764045715, - -0.9935426712036133, - 0.88087397813797, - -0.38332679867744446 + 0.3527827858924866, + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ], [ - 0.41817715764045715, - -0.9935426712036133, - 0.88087397813797, - -0.38332679867744446 + 0.3527827858924866, + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ], [ - 0.41817715764045715, - -0.9935426712036133, - 0.88087397813797, - -0.38332679867744446 + 0.3527827858924866, + -0.4038589298725128, + 0.4434446096420288, + -0.6249487400054932 ] ] ], @@ -12794,13 +13739,13 @@ export const testData = { "input": [ [ [ - 0.5941327810287476 + -1.4255669116973877 ], [ - -0.8920964002609253 + 0.8732106685638428 ], [ - 0.6283209323883057 + -2.0518009662628174 ] ] ], @@ -12812,42 +13757,42 @@ export const testData = { "expected_output": [ [ [ - 0.5941327810287476, - 0.5941327810287476, - 0.5941327810287476, - 0.5941327810287476 + -1.4255669116973877, + -1.4255669116973877, + -1.4255669116973877, + -1.4255669116973877 ], [ - -0.8920964002609253, - -0.8920964002609253, - -0.8920964002609253, - -0.8920964002609253 + 0.8732106685638428, + 0.8732106685638428, + 0.8732106685638428, + 0.8732106685638428 ], [ - 0.6283209323883057, - 0.6283209323883057, - 0.6283209323883057, - 0.6283209323883057 + -2.0518009662628174, + -2.0518009662628174, + -2.0518009662628174, + -2.0518009662628174 ] ], [ [ - 0.5941327810287476, - 0.5941327810287476, - 0.5941327810287476, - 0.5941327810287476 + -1.4255669116973877, + -1.4255669116973877, + -1.4255669116973877, + -1.4255669116973877 ], [ - -0.8920964002609253, - -0.8920964002609253, - -0.8920964002609253, - -0.8920964002609253 + 0.8732106685638428, + 0.8732106685638428, + 0.8732106685638428, + 0.8732106685638428 ], [ - 0.6283209323883057, - 0.6283209323883057, - 0.6283209323883057, - 0.6283209323883057 + -2.0518009662628174, + -2.0518009662628174, + -2.0518009662628174, + -2.0518009662628174 ] ] ], @@ -12881,54 +13826,54 @@ export const testData = { "input": [ [ [ - 0.6961200833320618, - 1.6817193031311035, - -1.6232244968414307, - 1.4739271402359009, - -0.3031364381313324 + -0.9301124811172485, + -0.16888298094272614, + -0.7453446984291077, + -1.6509697437286377, + 0.06193928048014641 ] ] ], "weight": [ [ [ - -0.06942257285118103, - 0.01881338469684124, - 0.28348493576049805 + -0.144717276096344, + 0.425019770860672, + -0.10819941759109497 ] ] ], "expected_output": [ [ [ - -0.6306472420692444, - 0.11674860864877701, - -0.0993165373802185 + -0.2816556394100189, + -0.5388382077217102, + -1.0256586074829102 ] ] ], "expected_grad_input": [ [ [ - -0.06942257285118103, - -0.05060918629169464, - 0.2328757494688034, - 0.30229830741882324, - 0.28348493576049805 + -0.144717276096344, + 0.280302494764328, + 0.17210307717323303, + 0.316820353269577, + -0.10819941759109497 ] ] ], "expected_grad_weight": [ [ [ - 0.7546148300170898, - 1.5324219465255737, - -0.4524337947368622 + -1.8443400859832764, + -2.565197467803955, + -2.3343751430511475 ] ] ], "bias": [ - -0.153799906373024 + -0.42512625455856323 ], "expected_grad_bias": [ 3.0 @@ -12948,189 +13893,189 @@ export const testData = { "input": [ [ [ - 0.6954406499862671, - -0.32303762435913086, - 0.5969774723052979, - -0.6247759461402893, - -0.3959338068962097, - 1.804771900177002 + 0.5684458613395691, + 0.5110347270965576, + 0.9753285646438599, + 1.9773973226547241, + -1.2740811109542847, + -0.7873809337615967 ], [ - -0.013955703936517239, - 0.33602362871170044, - -1.6720243692398071, - -0.8870291113853455, - -0.9315488338470459, - 1.888498306274414 + 2.1380560398101807, + 0.3426303565502167, + 0.6963862776756287, + -1.3928022384643555, + 0.9271320104598999, + 0.5793041586875916 ] ], [ [ - -1.3799183368682861, - -0.21034009754657745, - 0.8919094204902649, - 0.18319325149059296, - -0.811191976070404, - 0.6481902003288269 + -0.9904320240020752, + 1.2730960845947266, + 0.5620912313461304, + -0.7692673802375793, + 0.3543089032173157, + -0.041875794529914856 ], [ - -0.6447557210922241, - 1.492192268371582, - -0.16011619567871094, - -1.608611822128296, - 0.1806594282388687, - 1.864193320274353 + 0.5964854955673218, + 0.18470343947410583, + 0.4074154198169708, + -0.3804090619087219, + -0.09747593849897385, + -1.6269235610961914 ] ] ], "weight": [ [ [ - -0.46550750732421875, - 0.4468115568161011 + -0.0565146803855896, + 0.19237661361694336 ], [ - -0.24810147285461426, - 0.432242751121521 + -0.3971105217933655, + 0.2664335370063782 ] ], [ [ - -0.1569221019744873, - 0.4875195026397705 + 0.4777756929397583, + 0.2603725790977478 ], [ - 0.14750081300735474, - -0.024153947830200195 + -0.19769030809402466, + 0.40765953063964844 ] ], [ [ - 0.19086652994155884, - -0.015548527240753174 + -0.4735388159751892, + -0.05999833345413208 ], [ - -0.24799185991287231, - 0.2735045552253723 + -0.12388789653778076, + -0.4987332224845886 ] ] ], "expected_output": [ [ [ - 0.6290085911750793, - -0.06466558575630188, - 0.25565797090530396, - -0.9843642115592957 + 0.3937676250934601, + -0.0770099014043808, + 0.1580221951007843, + -0.4707871079444885 ], [ - 0.27673861384391785, - 0.369040310382843, - -0.26596060395240784, - -0.06729292869567871 + 0.6553137302398682, + 0.34996968507766724, + 0.9020213484764099, + -0.8550072312355042 ], [ - 0.4556798040866852, - -0.14126674830913544, - 0.3224104046821594, - 0.34644821286201477 + -0.9660398960113525, + -0.5558861494064331, + -1.0153863430023193, + 0.43547213077545166 ] ], [ [ - -0.5709445476531982, - 0.38131606578826904, - 0.35376980900764465, - -0.43993663787841797 + -0.31685012578964233, + -0.21385188400745392, + -0.04850868135690689, + 0.3631971478462219 ], [ - -0.7198030948638916, - 0.6291579008102417, - -0.7284935712814331, - 0.1106153056025505 + -0.37901127338409424, + 0.5198872685432434, + -0.6041116714477539, + -0.06267312169075012 ], [ - 0.3154219388961792, - 0.0024510433431714773, - 0.9662219285964966, - 0.13172286748886108 + -0.10367739945650101, + -0.7282735705375671, + 0.5731480717658997, + 0.35577142238616943 ] ] ], "expected_grad_input": [ [ [ - 0.9187825322151184, - -0.4315630793571472, - 0.9187825322151184, - -0.4315630793571472, - 0.9187825322151184, - -0.4315630793571472 + 0.3927508592605591, + -0.05227780342102051, + 0.3927508592605591, + -0.05227780342102051, + 0.3927508592605591, + -0.05227780342102051 ], [ - 0.6815933585166931, - -0.34859251976013184, - 0.6815933585166931, - -0.34859251976013184, - 0.6815933585166931, - -0.34859251976013184 + 0.175359845161438, + -0.7186887264251709, + 0.175359845161438, + -0.7186887264251709, + 0.175359845161438, + -0.7186887264251709 ] ], [ [ - 0.9187825322151184, - -0.4315630793571472, - 0.9187825322151184, - -0.4315630793571472, - 0.9187825322151184, - -0.4315630793571472 + 0.3927508592605591, + -0.05227780342102051, + 0.3927508592605591, + -0.05227780342102051, + 0.3927508592605591, + -0.05227780342102051 ], [ - 0.6815933585166931, - -0.34859251976013184, - 0.6815933585166931, - -0.34859251976013184, - 0.6815933585166931, - -0.34859251976013184 + 0.175359845161438, + -0.7186887264251709, + 0.175359845161438, + -0.7186887264251709, + 0.175359845161438, + -0.7186887264251709 ] ] ], "expected_grad_weight": [ [ [ - 1.478001594543457, - -0.40271657705307007 + 2.163003921508789, + 0.19566136598587036 ], [ - 3.085266590118408, - -3.241741418838501 + -2.29349684715271, + 4.667999267578125 ] ], [ [ - 1.478001594543457, - -0.40271657705307007 + 2.163003921508789, + 0.19566136598587036 ], [ - 3.085266590118408, - -3.241741418838501 + -2.29349684715271, + 4.667999267578125 ] ], [ [ - 1.478001594543457, - -0.40271657705307007 + 2.163003921508789, + 0.19566136598587036 ], [ - 3.085266590118408, - -3.241741418838501 + -2.29349684715271, + 4.667999267578125 ] ] ], "bias": [ - 0.3243098855018616, - -0.06263935565948486, - 0.470309853553772 + -0.2852379083633423, + -0.3642929196357727, + 0.13438546657562256 ], "expected_grad_bias": [ 8.0, @@ -13152,94 +14097,94 @@ export const testData = { "input": [ [ [ - 0.6144998073577881, - 0.4801225960254669, - 0.07178732752799988, - -1.3224995136260986, - -0.5643792152404785 + -0.5552166700363159, + 2.030524492263794, + 1.191868543624878, + -0.06635937094688416, + 0.1066870242357254 ], [ - 1.2230476140975952, - -1.3995004892349243, - -0.4572429955005646, - -0.4214997887611389, - -0.7015021443367004 + -0.5176211595535278, + 0.5926820039749146, + -0.25894099473953247, + 0.2768661379814148, + -1.449656367301941 ] ] ], "weight": [ [ [ - 0.3132607340812683, - 0.011339008808135986 + 0.3875494599342346, + -0.2733243703842163 ], [ - -0.01703113317489624, - 0.05102437734603882 + 0.28149646520614624, + 0.30508261919021606 ] ], [ [ - -0.224409818649292, - 0.4134613871574402 + -0.47784996032714844, + -0.3831656575202942 ], [ - -0.04957634210586548, - -0.18205493688583374 + 0.21601104736328125, + 0.046203017234802246 ] ] ], "expected_output": [ [ [ - 0.1491522192955017, - 0.13773603737354279, - -0.01191769540309906 + -0.7656475305557251, + 1.0563712120056152, + -0.08240810036659241 ], [ - -0.08560937643051147, - -0.5084284543991089, - -0.09907843172550201 + -0.31514859199523926, + -0.8040415644645691, + -0.7333257794380188 ] ] ], "expected_grad_input": [ [ [ - 0.08885091543197632, - 0.08885091543197632, - 0.5136513113975525, - 0.42480039596557617, - 0.42480039596557617 + -0.09030050039291382, + -0.09030050039291382, + -0.7467905282974243, + -0.6564900279045105, + -0.6564900279045105 ], [ - -0.06660747528076172, - -0.06660747528076172, - -0.19763803482055664, - -0.13103055953979492, - -0.13103055953979492 + 0.4975075125694275, + 0.4975075125694275, + 0.8487931489944458, + 0.3512856364250183, + 0.3512856364250183 ] ] ], "expected_grad_weight": [ [ [ - 1.1664097309112549, - -1.8150913715362549 + 2.6671762466430664, + 1.2321962118148804 ], [ - -0.6336958408355713, - -1.580245018005371 + -0.18388015031814575, + -1.4317312240600586 ] ], [ [ - 1.1664097309112549, - -1.8150913715362549 + 2.6671762466430664, + 1.2321962118148804 ], [ - -0.6336958408355713, - -1.580245018005371 + -0.18388015031814575, + -1.4317312240600586 ] ] ], @@ -13260,216 +14205,216 @@ export const testData = { "input": [ [ [ - -1.5568547248840332, - -1.2001843452453613, - 0.2736855447292328, - -0.6129935383796692, - 0.14779093861579895, - -0.5190516710281372 + -0.3783835768699646, + 0.23239530622959137, + -0.7321792840957642, + -0.40373992919921875, + 1.2062691450119019, + -0.6938396096229553 ], [ - 0.2923465669155121, - -0.5539951920509338, - -1.2117003202438354, - 0.23923887312412262, - -0.7021881937980652, - 1.0326601266860962 + -1.5164529085159302, + 2.0242106914520264, + -0.1935255229473114, + 1.383492350578308, + -0.2420232743024826, + -0.30263814330101013 ], [ - 0.9352383017539978, - 0.30303436517715454, - -0.5343928933143616, - -0.2886335253715515, - 0.7341271638870239, - -1.3263294696807861 + 0.1517062932252884, + 1.0345447063446045, + -0.9610977172851562, + -1.2026211023330688, + 1.1932176351547241, + -0.8363521695137024 ], [ - 0.24674031138420105, - 1.4741090536117554, - -1.2584627866744995, - 0.08387812972068787, - 0.9973886609077454, - -0.7661278247833252 + 0.07792648673057556, + 0.6653022766113281, + -1.825669527053833, + 0.6015728712081909, + 0.6289637684822083, + -0.39405086636543274 ] ] ], "weight": [ [ [ - 0.12207754701375961, - 0.40559911727905273, - 0.1231803372502327 + 0.06892253458499908, + -0.380085289478302, + 0.36482012271881104 ], [ - -0.393903911113739, - -0.13032309710979462, - 0.38015538454055786 + -0.2025740146636963, + 0.35292473435401917, + -0.1281263679265976 ] ], [ [ - -0.14388829469680786, - -0.19640615582466125, - -0.3254093527793884 + 0.3980580270290375, + 0.12043391168117523, + -0.019721616059541702 ], [ - -0.2253584861755371, - -0.22320778667926788, - 0.09750071167945862 + 0.1558418720960617, + -0.012695319950580597, + -0.20248451828956604 ] ], [ [ - 0.16310562193393707, - 0.3896220326423645, - 0.26792049407958984 + 0.2233155369758606, + 0.2647979259490967, + -0.05114482343196869 ], [ - 0.006032273638993502, - 0.2201666384935379, - 0.2333495020866394 + 0.38400641083717346, + 0.025926170870661736, + -0.21590395271778107 ] ], [ [ - -0.3521243631839752, - 0.20600011944770813, - -0.27926933765411377 + -0.2224746197462082, + 0.27468135952949524, + -0.16537627577781677 ], [ - 0.3152562081813812, - -0.17756487429141998, - 0.08470655232667923 + 0.25785261392593384, + -0.39656978845596313, + 0.01406295970082283 ] ] ], "expected_output": [ [ [ - -1.0323456525802612, - -1.1510744094848633, - 0.3517197370529175, - -0.0221832487732172, - 0.3066757321357727, - -0.05481366068124771 + -0.848025381565094, + 0.3827834129333496, + -0.7906762361526489, + 0.8194673657417297, + -1.3484156131744385, + 0.006999105215072632 ], [ - 0.7664621472358704, - 0.49971258640289307, - 0.9264512658119202, - 0.37353020906448364, - 0.6209883689880371, - 0.1978299468755722 + -0.2959577143192291, + -0.18621432781219482, + 0.1948830783367157, + -0.21776551008224487, + 0.42302078008651733, + 0.5075432062149048 ], [ - 0.9073842167854309, - 0.22331207990646362, - -0.4212228059768677, - 0.3041822016239166, - -0.011575311422348022, - -0.4961872100830078 + 0.17718645930290222, + 1.129868745803833, + 0.4478544592857361, + -1.083827018737793, + 0.7541118860244751, + 0.6078572273254395 ], [ - -0.10705599188804626, - -0.7043604254722595, - 0.2629602551460266, - -0.6995928883552551, - 0.11157292127609253, - -0.3773989677429199 + 0.009685128927230835, + 0.30059313774108887, + 0.7693951725959778, + -0.8536713719367981, + 0.7944182753562927, + -0.016091808676719666 ] ] ], "expected_grad_input": [ [ [ - 0.18738222122192383, - -0.0148468017578125, - -0.0148468017578125, - -0.0148468017578125, - -0.0148468017578125, - 0.006963938474655151 + 0.20732921361923218, + 0.5524277091026306, + 0.5524277091026306, + 0.5524277091026306, + 0.5524277091026306, + 0.08544713258743286 ], [ - -0.9727932810783386, - -0.49513718485832214, - -0.49513718485832214, - -0.49513718485832214, - -0.49513718485832214, - 0.12412521243095398 + 0.2934972643852234, + -0.03711360692977905, + -0.03711360692977905, + -0.03711360692977905, + -0.03711360692977905, + 0.009618550539016724 ], [ - 0.40660345554351807, - 0.39525461196899414, - 0.39525461196899414, - 0.39525461196899414, - 0.39525461196899414, - 0.5842733383178711 + 0.5403201580047607, + 0.3237990736961365, + 0.3237990736961365, + 0.3237990736961365, + 0.3237990736961365, + 0.32295817136764526 ], [ - 0.36389026045799255, - 0.6819462776184082, - 0.6819462776184082, - 0.6819462776184082, - 0.6819462776184082, - 0.36065781116485596 + 0.27121543884277344, + 0.0693744421005249, + 0.0693744421005249, + 0.0693744421005249, + 0.0693744421005249, + -0.5724846124649048 ] ] ], "expected_grad_weight": [ [ [ - -2.9485559463500977, - -3.4676079750061035, - -1.9107531309127808 + -0.07563827931880951, + -0.769477903842926, + -0.3910943865776062 ], [ - -1.9362983703613281, - -0.9036381840705872, - -1.1959846019744873 + 1.455701231956482, + 1.153063178062439, + 2.669516086578369 ] ], [ [ - -2.9485559463500977, - -3.4676079750061035, - -1.9107531309127808 + -0.07563827931880951, + -0.769477903842926, + -0.3910943865776062 ], [ - -1.9362983703613281, - -0.9036381840705872, - -1.1959846019744873 + 1.455701231956482, + 1.153063178062439, + 2.669516086578369 ] ], [ [ - 1.1493734121322632, - -0.17695605754852295, - -1.112194299697876 + 0.2157498002052307, + -0.6206024289131165, + -0.7723087072372437 ], [ - 1.5436534881591797, - 0.7775256037712097, - 0.5307852625846863 + 0.148095965385437, + -0.24595487117767334, + -0.32388150691986084 ] ], [ [ - 1.1493734121322632, - -0.17695605754852295, - -1.112194299697876 + 0.2157498002052307, + -0.6206024289131165, + -0.7723087072372437 ], [ - 1.5436534881591797, - 0.7775256037712097, - 0.5307852625846863 + 0.148095965385437, + -0.24595487117767334, + -0.32388150691986084 ] ] ], "bias": [ - -0.0043439180590212345, - 0.18940408527851105, - 0.06349903345108032, - -0.29614126682281494 + -0.2820773720741272, + 0.14481520652770996, + 0.3315476179122925, + 0.1606505662202835 ], "expected_grad_bias": [ 6.0, @@ -13493,39 +14438,39 @@ export const testData = { [ [ [ - -0.15365807712078094, - 1.032126545906067, - 0.36852389574050903, - 2.4601800441741943, - 0.13030865788459778 + -1.467360258102417, + 1.7191014289855957, + -0.3673190176486969, + 2.3575830459594727, + -0.459722101688385 ], [ - -0.9205528497695923, - 1.5234228372573853, - 1.3897676467895508, - -1.6782877445220947, - 1.655027985572815 + -0.058640673756599426, + 1.1636638641357422, + 0.5507457852363586, + -2.0428922176361084, + 1.0865724086761475 ], [ - 0.5495442748069763, - 0.1979023516178131, - -0.33105704188346863, - -1.3217003345489502, - -0.24350062012672424 + -0.172266885638237, + 0.5808969140052795, + 0.053119998425245285, + 0.6127946376800537, + 0.6289454698562622 ], [ - -0.4956028163433075, - 1.6506794691085815, - -0.8902555108070374, - 0.6958364844322205, - -0.9322998523712158 + -0.0685209259390831, + -1.2115036249160767, + 1.2690211534500122, + -0.5605306625366211, + -2.0018928050994873 ], [ - 0.18523266911506653, - 0.039212681353092194, - -1.0234346389770508, - 0.31960463523864746, - -0.8433935046195984 + 0.8131555318832397, + 1.2148545980453491, + 0.9846591353416443, + 1.6213051080703735, + 0.5066256523132324 ] ] ] @@ -13534,19 +14479,19 @@ export const testData = { [ [ [ - 0.29462969303131104, - 0.3235141932964325, - -0.07830675691366196 + -0.10344748198986053, + 0.18141815066337585, + -0.28466638922691345 ], [ - 0.1112322062253952, - -0.2927438020706177, - -0.06486010551452637 + -0.09609787166118622, + -0.14009928703308105, + 0.30844438076019287 ], [ - -0.10368549823760986, - 0.0946246013045311, - -0.21840083599090576 + 0.13302838802337646, + -0.2486542910337448, + 0.12918822467327118 ] ] ] @@ -13555,19 +14500,19 @@ export const testData = { [ [ [ - -0.2726651728153229, - 0.4109613299369812, - 1.467284083366394 + 0.4131501019001007, + -1.5985389947891235, + 1.093879222869873 ], [ - 0.6114932298660278, - 0.8991829752922058, - 0.5365865230560303 + 0.4609568417072296, + 0.13063298165798187, + -0.5913594961166382 ], [ - 0.0512884259223938, - 0.3551037609577179, - -0.3557467460632324 + 0.6020535826683044, + -0.34000104665756226, + -0.9480313062667847 ] ] ] @@ -13576,39 +14521,39 @@ export const testData = { [ [ [ - 0.29462969303131104, - 0.6181439161300659, - 0.5398371815681458, - 0.24520742893218994, - -0.07830675691366196 + -0.10344748198986053, + 0.07797066867351532, + -0.20669572055339813, + -0.1032482385635376, + -0.28466638922691345 ], [ - 0.40586191415786743, - 0.43663233518600464, - 0.2934654951095581, - -0.1123964786529541, - -0.14316686987876892 + -0.19954535365104675, + -0.15822649002075195, + -0.13444849848747253, + 0.06509685516357422, + 0.02377799153327942 ], [ - 0.30217641592025757, - 0.42757144570350647, - 0.06600376963615417, - -0.23617270588874817, - -0.3615677058696747 + -0.06651696562767029, + -0.2738524079322815, + -0.12088616192340851, + -0.054369211196899414, + 0.1529662162065506 ], [ - 0.007546707987785339, - -0.19057247042655945, - -0.4738334119319916, - -0.4813801348209381, - -0.28326094150543213 + 0.03693051636219025, + -0.3518230617046356, + 0.08580954372882843, + 0.048879027366638184, + 0.43763262033462524 ], [ - -0.10368549823760986, - -0.009060896933078766, - -0.22746172547340393, - -0.12377623468637466, - -0.21840083599090576 + 0.13302838802337646, + -0.11562590301036835, + 0.013562321662902832, + -0.11946606636047363, + 0.12918822467327118 ] ] ] @@ -13617,25 +14562,25 @@ export const testData = { [ [ [ - 3.656019449234009, - 3.640878438949585, - 2.429262399673462 + 2.001941204071045, + 4.627694606781006, + 2.419827938079834 ], [ - 2.6738481521606445, - 1.2363080978393555, - -1.6564688682556152 + 2.106515884399414, + 0.41531574726104736, + -0.4041163921356201 ], [ - -0.11777856945991516, - -0.6632119417190552, - -4.570200443267822 + 3.4634158611297607, + 4.564617156982422, + 3.1140480041503906 ] ] ] ], "bias": [ - 0.07201576232910156 + -0.007069031707942486 ], "expected_grad_bias": [ 9.0 @@ -13655,205 +14600,205 @@ export const testData = { "input": [ [ [ + [ + -0.8043005466461182, + -0.28731220960617065, + 1.8125576972961426, + -0.2427283376455307, + -0.49898141622543335, + -0.9646658897399902 + ], + [ + 1.1177937984466553, + -2.260744571685791, + 0.731488823890686, + -0.4989534318447113, + 0.7293177843093872, + 0.1701146513223648 + ], + [ + 0.739496648311615, + -1.1954078674316406, + 2.1079015731811523, + -1.823443055152893, + -0.15365807712078094, + 1.032126545906067 + ], + [ + 0.36852389574050903, + 2.4601800441741943, + 0.13030865788459778, + -0.9205528497695923, + 1.5234228372573853, + 1.3897676467895508 + ], + [ + -1.6782877445220947, + 1.8284801244735718, + -0.968523383140564, + 0.4811331629753113, + 0.19745779037475586, + 0.1997281163930893 + ], + [ + 0.13673236966133118, + 0.21775121986865997, + 0.3381371796131134, + 1.025931715965271, + -0.6230042576789856, + -0.6034882664680481 + ] + ], + [ + [ + 1.0356813669204712, + -0.316057026386261, + -0.21146954596042633, + 0.3081285357475281, + 0.03471093624830246, + -1.8955014944076538 + ], + [ + 1.2220596075057983, + 0.6842809319496155, + 0.482809454202652, + -0.1810940057039261, + 0.10777772217988968, + 0.4828875958919525 + ], + [ + 1.6506794691085815, + 0.7990935444831848, + 0.25144144892692566, + 0.5849565863609314, + 1.04137122631073, + -0.6260819435119629 + ], + [ + 1.1246347427368164, + 0.8956797122955322, + -0.8433935046195984, + -2.1094107627868652, + 0.4968266487121582, + 1.6480950117111206 + ], + [ + 0.03010670095682144, + -0.9876852631568909, + 1.1092876195907593, + 0.49909794330596924, + -0.2840602993965149, + -0.10638472437858582 + ], + [ + 0.2790530323982239, + -2.164227247238159, + 0.7445889115333557, + -2.1047589778900146, + 0.7448800802230835, + -0.7210500240325928 + ] + ] + ], + [ + [ + [ + 0.5612776279449463, + -0.006535662803798914, + 0.34217989444732666, + -1.073784351348877, + 1.5708034038543701, + -1.1401112079620361 + ], + [ + -0.2012692391872406, + -0.4230685234069824, + -0.7898051142692566, + -0.5088178515434265, + -0.9016579985618591, + 0.6364835500717163 + ], [ 0.7696021795272827, 0.582319974899292, 0.2216803878545761, -0.1759732961654663, - 0.42830219864845276, - 1.2776193618774414 + 1.837676763534546, + -0.2276618480682373 ], [ - 0.9624823927879333, - 0.04533285275101662, + 0.556129515171051, + 0.1394495666027069, -0.7639250159263611, -0.6143314838409424, 0.6616799235343933, -0.05819060653448105 ], [ - -0.7563550472259521, - 0.20380251109600067, - 0.36853712797164917, - -0.2603956162929535, + 0.926749587059021, + -0.16234397888183594, + -0.18278858065605164, + 1.7139904499053955, -1.0269054174423218, 0.5982120633125305 ], [ 0.8188145160675049, -1.2973971366882324, - 1.243552803993225, - -0.6079679131507874, - -0.36244451999664307, - -0.12838764488697052 - ], + -1.6458345651626587, + 0.15697401762008667, + 0.29413074254989624, + 0.2593991756439209 + ] + ], + [ [ 0.5408645272254944, -1.3398406505584717, 0.14272356033325195, 0.3211787939071655, - -1.4200862646102905, - 0.7608973383903503 + -1.402301549911499, + -0.8660640120506287 ], [ - 0.8337363600730896, - 0.1786288470029831, + -0.8508381843566895, + 0.1697680652141571, 0.3121674954891205, 1.2302255630493164, 0.12507683038711548, 1.026518702507019 - ] - ], - [ + ], [ - -0.03989891707897186, - 0.8457168936729431, - 0.8489260077476501, - 0.4735972583293915, + 1.4250038862228394, + 0.3661484718322754, + 0.18309427797794342, + -0.9111728668212891, 0.7800946235656738, 0.3574816882610321 ], [ 0.14799346029758453, 1.138214111328125, - 0.9666075706481934, - -0.6567904949188232, - 0.7314628958702087, - 1.6726516485214233 + -0.7696079015731812, + -1.0346392393112183, + -0.42179074883461, + -0.14516009390354156 ], [ -0.3307901918888092, 0.752140462398529, -1.1388487815856934, 0.601990818977356, - 0.8349303603172302, - -0.1024642139673233 + -0.025565603747963905, + -1.8534711599349976 ], [ - 0.2129386067390442, - 0.8061029314994812, + 0.2496940791606903, + -0.663693368434906, -0.29064902663230896, -0.08062736690044403, 0.18424205482006073, -0.26781368255615234 - ], - [ - -0.842875063419342, - -1.4834386110305786, - -1.013265609741211, - 1.365964651107788, - 0.5897303223609924, - 0.05003054440021515 - ], - [ - -0.7778317928314209, - -2.4351913928985596, - 0.11171633005142212, - 0.9481878280639648, - -1.2265124320983887, - 0.7861263155937195 - ] - ] - ], - [ - [ - [ - -0.11475960910320282, - 1.580405592918396, - 1.2975212335586548, - -0.33260318636894226, - -1.0625550746917725, - 0.38694456219673157 - ], - [ - 1.4818024635314941, - -0.9132123589515686, - -0.9041587114334106, - 0.8335179090499878, - 0.8654338121414185, - -0.4001701772212982 - ], - [ - -0.22977444529533386, - -0.1719079464673996, - 0.2926573157310486, - 0.9981994032859802, - -1.0177124738693237, - 1.7738550901412964 - ], - [ - -0.23209598660469055, - -0.4985274374485016, - -0.5410075187683105, - 0.6815518140792847, - -0.4239010512828827, - 1.3261003494262695 - ], - [ - 0.6056780219078064, - -0.019913967698812485, - -1.0039576292037964, - -0.8306655287742615, - 1.1431289911270142, - -0.35668206214904785 - ], - [ - 1.0129450559616089, - -0.07218152284622192, - 1.905303955078125, - 0.7196555137634277, - 1.2182841300964355, - -0.2805838882923126 - ] - ], - [ - [ - -1.4755696058273315, - 0.2024499773979187, - -0.06308790296316147, - 0.9503589868545532, - -0.6049215793609619, - 1.088989019393921 - ], - [ - -0.5790899395942688, - 1.3511621952056885, - -0.02688431739807129, - -1.4886178970336914, - -0.40090087056159973, - -0.08886078000068665 - ], - [ - 0.43563491106033325, - 0.3141688108444214, - -0.8474487066268921, - -0.5701133608818054, - -2.5571954250335693, - 0.09272336214780807 - ], - [ - 0.0977560505270958, - 0.8891482949256897, - -0.7126783132553101, - 2.1329596042633057, - -0.21151213347911835, - 0.760424017906189 - ], - [ - 0.5244688391685486, - -0.921648383140564, - 0.7664128541946411, - 0.4324735403060913, - -0.8171257972717285, - 1.0141600370407104 - ], - [ - 0.7154613733291626, - -1.0755102634429932, - -0.1033744290471077, - 0.23104271292686462, - 0.958231508731842, - 0.2724153697490692 ] ] ] @@ -13862,66 +14807,66 @@ export const testData = { [ [ [ - 0.2175293266773224, - -0.22950278222560883 + 0.02643534541130066, + -0.002493660431355238 ], [ - -0.2151593267917633, - -0.35030069947242737 + -0.09351104497909546, + 0.21940048038959503 ] ], [ [ - 0.11319576948881149, - -0.2659381926059723 + 0.018684372305870056, + -0.20529168844223022 ], [ - -0.29634103178977966, - -0.22661609947681427 + -0.09356790035963058, + -0.2078663557767868 ] ] ], [ [ [ - -0.34954825043678284, - -0.2878783941268921 + -0.12472891807556152, + -0.33350855112075806 ], [ - 0.3153572082519531, - 0.19748975336551666 + 0.06177648901939392, + -0.2739461660385132 ] ], [ [ - 0.31325748562812805, - -0.17150205373764038 + 0.1367422491312027, + 0.2421981245279312 ], [ - -0.14501044154167175, - -0.12405052036046982 + -0.2630181312561035, + -0.18658122420310974 ] ] ], [ [ [ - 0.006905086804181337, - -0.2537684142589569 + -0.2793554663658142, + 0.09435301274061203 ], [ - 0.05183164402842522, - -0.22659194469451904 + 0.06841082125902176, + -0.18248572945594788 ] ], [ [ - 0.05586855486035347, - 0.3238540291786194 + 0.21357481181621552, + 0.14670585095882416 ], [ - 0.05971483513712883, - 0.25789743661880493 + -0.3194490969181061, + -0.0192315224558115 ] ] ] @@ -13930,160 +14875,160 @@ export const testData = { [ [ [ - -0.5123543739318848, - -0.8977512121200562, - -0.6811044812202454, - -0.6326321363449097 + -0.5439481735229492, + 0.345872163772583, + -0.2750261127948761, + 0.11536405980587006 ], [ - -0.17213934659957886, - -0.3325940668582916, - -0.7580173015594482, - -0.17347155511379242 + -0.5867418646812439, + 0.1471027433872223, + -0.3271189033985138, + -0.17661553621292114 ], [ - -0.49480879306793213, - 0.2566264569759369, - -0.46907752752304077, - -0.4885876476764679 + -0.7584733963012695, + -0.41925880312919617, + -0.31106430292129517, + -0.09339094161987305 ], [ - -0.23629358410835266, - -0.5899532437324524, - 0.4206080734729767, - 0.060480158776044846 + -0.209829181432724, + -0.3405829668045044, + -0.31577032804489136, + -0.18162673711776733 ] ], [ [ - 0.10704323649406433, - -0.05042387172579765, - -0.18625164031982422, - 0.3011731207370758 + -0.034206323325634, + -0.45301008224487305, + -0.027123337611556053, + 0.37765491008758545 ], [ - -0.46069151163101196, - 0.5142151117324829, - -0.8326210379600525, - 0.6979251503944397 + -0.6486839652061462, + -0.7211645841598511, + -0.6596684455871582, + 0.21194230020046234 ], [ - -0.11075891554355621, - 0.2944490909576416, - -0.24029767513275146, - 0.14378775656223297 + 0.5423190593719482, + -0.06232115626335144, + -0.7253143787384033, + 0.031036945059895515 ], [ - -0.15650972723960876, - -0.984201967716217, - -0.008548552170395851, - -0.16245263814926147 + -0.03931796923279762, + -0.31683745980262756, + -0.0888896957039833, + -0.08462823927402496 ] ], [ [ - -0.4029870927333832, - 0.031077677384018898, - -0.09501723945140839, - -0.13074353337287903 + 0.32371586561203003, + -0.048529937863349915, + 0.17221303284168243, + 0.7363828420639038 ], [ - -0.32855695486068726, - 0.03075524792075157, - 0.280192106962204, - -0.10037711262702942 + 0.31491804122924805, + 0.3878597319126129, + 0.07859956473112106, + 0.5230802893638611 ], [ - -0.6970707178115845, - -1.043624758720398, - 0.4967159032821655, - -0.19173437356948853 + 0.7023065686225891, + 0.1854657530784607, + 0.06303960084915161, + 0.2082606554031372 ], [ - -0.6817915439605713, - -0.39616724848747253, - -0.5857944488525391, - -0.167303666472435 + 0.2507000267505646, + -0.18505442142486572, + -0.48876702785491943, + 0.21144984662532806 ] ] ], [ [ [ - 0.12278426438570023, - -1.0920629501342773, - 0.04742713272571564, - -0.6577708125114441 + -0.14148390293121338, + 0.019183289259672165, + 0.5542840361595154, + 0.03544783219695091 ], [ - -0.4561113715171814, - -0.04943810775876045, - 0.5591838955879211, - -0.7580505609512329 + -0.10438832640647888, + -0.3004642426967621, + 0.17664918303489685, + -0.12835535407066345 ], [ - -0.5555568337440491, - 0.509503185749054, - 0.1267319768667221, - -0.10105518996715546 + 0.08811988681554794, + 0.17408053576946259, + -0.5394258499145508, + -0.03896549344062805 ], [ - -0.6745461225509644, - -0.799030065536499, - -0.6035346388816833, - -0.28200289607048035 + -0.20550291240215302, + -0.13512679934501648, + -0.18811459839344025, + -0.15034757554531097 ] ], [ [ - 0.11048654466867447, - 0.6832133531570435, - -0.4273984730243683, - -0.08578380942344666 + -0.31597769260406494, + 0.1703275591135025, + -0.3807855546474457, + 0.09605579078197479 ], [ - -0.47657740116119385, - 1.0206303596496582, - -0.4742591083049774, - 0.6080998182296753 + -0.6769576072692871, + 0.19847336411476135, + 0.08119788765907288, + -0.10841041803359985 ], [ - 0.054709840565919876, - 0.5148905515670776, - 0.5407938361167908, - -0.5347684025764465 + -0.4030931293964386, + 0.20003023743629456, + -0.2153528332710266, + 0.4505578279495239 ], [ - -0.464202880859375, - -0.8923424482345581, - -0.7441295981407166, - 0.1335189789533615 + -0.2739088833332062, + 0.4882705807685852, + -0.14537908136844635, + -0.13027870655059814 ] ], [ [ - -0.5728536248207092, - -0.4345853924751282, - -0.09404174983501434, - -0.13322682678699493 + 0.08403339982032776, + 0.5592362284660339, + -0.23887935280799866, + 0.3955276310443878 ], [ - -0.6174727082252502, - -0.20340797305107117, - -1.056370735168457, - -0.12856057286262512 + -0.11479949206113815, + 0.20147770643234253, + 0.46370449662208557, + 0.10852185636758804 ], [ - -0.12973688542842865, - 0.10348469763994217, - -0.5423545837402344, - -0.12459800392389297 + 0.10828724503517151, + 0.019894912838935852, + 0.260893851518631, + 0.815127432346344 ], [ - -0.24366001784801483, - -0.7958813905715942, - -0.19926922023296356, - -0.20502960681915283 + 0.3107494115829468, + 0.21961763501167297, + 0.1905701756477356, + 0.06719737499952316 ] ] ] @@ -14092,204 +15037,204 @@ export const testData = { [ [ [ - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533 + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022 ], [ - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598 + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751 ], [ - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533 + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022 ], [ - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598 + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751 ], [ - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533 + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022 ], [ - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598 + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751 ] ], [ [ - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935 + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432 ], [ - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445 + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946 ], [ - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935 + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432 ], [ - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445 + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946 ], [ - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935 + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432 ], [ - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445 + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946 ] ] ], [ [ [ - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533 + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022 ], [ - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598 + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751 ], [ - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533 + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022 ], [ - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598 + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751 ], [ - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533, - -0.37940287590026855, - 0.15202952921390533 + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022, + -0.23703141510486603, + 0.03667626529932022 ], [ - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598, - -0.7711496353149414, - -0.1251138299703598 + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751, + -0.24164918065071106, + -0.3776490390300751 ] ], [ [ - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935 + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432 ], [ - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445 + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946 ], [ - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935 + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432 ], [ - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445 + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946 ], [ - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935, - -0.09276917576789856, - -0.3816366493701935 + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432, + -0.4136790931224823, + -0.6760351657867432 ], [ - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445, - -0.11358621716499329, - 0.4823218286037445 + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946, + 0.18361228704452515, + 0.36900144815444946 ] ] ] @@ -14298,74 +15243,74 @@ export const testData = { [ [ [ - 1.1705816984176636, - 8.213747024536133 + -0.7294929623603821, + 2.4809837341308594 ], [ - 4.995451927185059, - -0.8214102387428284 + -0.8639777302742004, + 5.7739386558532715 ] ], [ [ - 4.895022869110107, - -0.20302361249923706 + -2.196805477142334, + 3.045524835586548 ], [ - 5.464581489562988, - -4.95082950592041 + -4.312042236328125, + 4.832023620605469 ] ] ], [ [ [ - 1.1705816984176636, - 8.213747024536133 + -0.7294929623603821, + 2.4809837341308594 ], [ - 4.995451927185059, - -0.8214102387428284 + -0.8639777302742004, + 5.7739386558532715 ] ], [ [ - 4.895022869110107, - -0.20302361249923706 + -2.196805477142334, + 3.045524835586548 ], [ - 5.464581489562988, - -4.95082950592041 + -4.312042236328125, + 4.832023620605469 ] ] ], [ [ [ - 1.1705816984176636, - 8.213747024536133 + -0.7294929623603821, + 2.4809837341308594 ], [ - 4.995451927185059, - -0.8214102387428284 + -0.8639777302742004, + 5.7739386558532715 ] ], [ [ - 4.895022869110107, - -0.20302361249923706 + -2.196805477142334, + 3.045524835586548 ], [ - 5.464581489562988, - -4.95082950592041 + -4.312042236328125, + 4.832023620605469 ] ] ] ], "bias": [ - -0.2518039345741272, - -0.0498947873711586, - -0.218311607837677 + -0.15220095217227936, + -0.06130267307162285, + 0.196860209107399 ], "expected_grad_bias": [ 32.0, @@ -14388,76 +15333,76 @@ export const testData = { [ [ [ - 0.03995849937200546, - 1.5177383422851562, - -2.1199755668640137, - -0.600395917892456, - 0.22108443081378937 + 0.9263717532157898, + 0.06930986046791077, + 0.6712534427642822, + -0.02775866538286209, + -0.9041587114334106 ], [ - 1.921225905418396, - 0.7144214510917664, - 1.472544550895691, - -0.1465783715248108, - 0.9949571490287781 + 0.8335179090499878, + 0.8654338121414185, + -0.4001701772212982, + 1.4326399564743042, + 0.34999290108680725 ], [ - -2.086519479751587, - -1.8325921297073364, - 0.6720287203788757, - -0.46412497758865356, - -0.5884720087051392 + 0.6649242639541626, + -1.9941226243972778, + -1.0177124738693237, + 1.7738550901412964, + -0.23209598660469055 ], [ - -0.8352398872375488, - 0.9850609302520752, - -0.23145577311515808, - 0.6784274578094482, - -1.0587496757507324 + -0.4985274374485016, + 0.6896741390228271, + 0.7225849628448486, + -1.5831043720245361, + -0.3734499514102936 ], [ - 0.07416296005249023, - -1.5832154750823975, - -2.017490863800049, - 0.856982946395874, - 0.6308630108833313 + 0.6056780219078064, + -0.019913967698812485, + -1.0039576292037964, + -0.8306655287742615, + -1.3570464849472046 ] ], [ [ - -0.6896459460258484, - -0.23252737522125244, - 1.0665576457977295, - 1.0091438293457031, - 1.4308871030807495 + 0.4011816382408142, + 1.1124663352966309, + 0.4233713448047638, + 1.905303955078125, + 0.7196555137634277 ], [ - -0.9748004078865051, - 0.9013839960098267, - -1.6900079250335693, - -1.1190448999404907, - -0.0805031880736351 + 1.2182841300964355, + -0.2805838882923126, + 1.9091075658798218, + -0.4942598342895508, + -1.0949782133102417 ], [ - -0.6609653830528259, - -1.0767394304275513, - -1.3419830799102783, - 0.40884074568748474, - -0.13771961629390717 + 0.5647533535957336, + -0.7126783132553101, + 2.1329596042633057, + -0.21151213347911835, + 0.760424017906189 ], [ - -0.48222219944000244, - -0.9596375823020935, - -1.219414472579956, - 0.036487940698862076, - -1.5120867490768433 + 0.5244688391685486, + -0.921648383140564, + -0.2014247626066208, + 0.5469425320625305, + -0.8171257972717285 ], [ - 2.1745407581329346, - -0.059072766453027725, - 1.432356357574463, - -0.3214779198169708, - -0.32065340876579285 + 1.0141600370407104, + 0.7154613733291626, + -1.0755102634429932, + -0.1033744290471077, + 0.23104271292686462 ] ] ] @@ -14466,44 +15411,44 @@ export const testData = { [ [ [ - -0.08688648790121078, - -0.1804211288690567 + 0.26463213562965393, + 0.16901569068431854 ], [ - 0.28104352951049805, - -0.2520372271537781 + 0.2000877410173416, + -0.23677533864974976 ] ], [ [ - 0.21281561255455017, - 0.0672207698225975 + -0.23679085075855255, + 0.15098260343074799 ], [ - -0.10753397643566132, - 0.2881980836391449 + 0.12837570905685425, + 0.31905919313430786 ] ] ], [ [ [ - 0.19674864411354065, - -0.01236567460000515 + -0.04603291302919388, + -0.06499334424734116 ], [ - -0.23963071405887604, - -0.10405980795621872 + 0.24237388372421265, + 0.011418171226978302 ] ], [ [ - 0.1139952540397644, - 0.3063434362411499 + 0.33192384243011475, + -0.18033814430236816 ], [ - -0.1193094253540039, - -0.14693082869052887 + -0.11600156873464584, + 0.01527633611112833 ] ] ] @@ -14512,36 +15457,36 @@ export const testData = { [ [ [ - -0.7675158381462097, - -0.16964507102966309, - 0.9092788100242615 + 1.4545789957046509, + -0.9400842189788818, + 0.4009864926338196 ], [ - -1.2296440601348877, - 0.30054324865341187, - -0.7753838896751404 + -0.11507278680801392, + 1.0320004224777222, + -0.7176908254623413 ], [ - 0.5374605059623718, - -0.7059400081634521, - -1.2195123434066772 + 0.3382055163383484, + 0.16048336029052734, + -0.6427193284034729 ] ], [ [ - 0.9882943630218506, - 1.1445107460021973, - 0.22063326835632324 + 0.08715254068374634, + -0.3593597114086151, + -0.4465169608592987 ], [ - 0.19188177585601807, - -0.29519984126091003, - 0.5934002995491028 + -0.12876389920711517, + 0.1274016946554184, + 1.008573055267334 ], [ - -1.1830170154571533, - -0.007825799286365509, - 0.23835396766662598 + -0.16039958596229553, + -0.3207898437976837, + 0.5022419095039368 ] ] ] @@ -14550,76 +15495,76 @@ export const testData = { [ [ [ - 0.10986215621232986, - 0.10986215621232986, - -0.08292464166879654, - -0.1927867978811264, - -0.1927867978811264 + 0.21859923005104065, + 0.21859923005104065, + 0.32262158393859863, + 0.10402234643697739, + 0.10402234643697739 ], [ - 0.10986215621232986, - 0.10986215621232986, - -0.08292464166879654, - -0.1927867978811264, - -0.1927867978811264 + 0.21859923005104065, + 0.21859923005104065, + 0.32262158393859863, + 0.10402234643697739, + 0.10402234643697739 ], [ - 0.15127497911453247, - 0.15127497911453247, - -0.3976088762283325, - -0.548883855342865, - -0.548883855342865 + 0.6610608100891113, + 0.6610608100891113, + 0.5397260189056396, + -0.12133482843637466, + -0.12133482843637466 ], [ - 0.04141281545162201, - 0.04141281545162201, - -0.3146842122077942, - -0.3560970425605774, - -0.3560970425605774 + 0.44246160984039307, + 0.44246160984039307, + 0.21710443496704102, + -0.22535717487335205, + -0.22535717487335205 ], [ - 0.04141281545162201, - 0.04141281545162201, - -0.3146842122077942, - -0.3560970425605774, - -0.3560970425605774 + 0.44246160984039307, + 0.44246160984039307, + 0.21710443496704102, + -0.22535717487335205, + -0.22535717487335205 ] ], [ [ - 0.3268108665943146, - 0.3268108665943146, - 0.7003750801086426, - 0.373564213514328, - 0.373564213514328 + 0.0951329916715622, + 0.0951329916715622, + 0.06577745079994202, + -0.029355540871620178, + -0.029355540871620178 ], [ - 0.3268108665943146, - 0.3268108665943146, - 0.7003750801086426, - 0.373564213514328, - 0.373564213514328 + 0.0951329916715622, + 0.0951329916715622, + 0.06577745079994202, + -0.029355540871620178, + -0.029355540871620178 ], [ - 0.09996746480464935, - 0.09996746480464935, - 0.614798903465271, - 0.5148314833641052, - 0.5148314833641052 + 0.1075071319937706, + 0.1075071319937706, + 0.41248711943626404, + 0.30497997999191284, + 0.30497997999191284 ], [ - -0.22684340178966522, - -0.22684340178966522, - -0.0855761468410492, - 0.14126725494861603, - 0.14126725494861603 + 0.012374140322208405, + 0.012374140322208405, + 0.346709668636322, + 0.3343355357646942, + 0.3343355357646942 ], [ - -0.22684340178966522, - -0.22684340178966522, - -0.0855761468410492, - 0.14126725494861603, - 0.14126725494861603 + 0.012374140322208405, + 0.012374140322208405, + 0.346709668636322, + 0.3343355357646942, + 0.3343355357646942 ] ] ] @@ -14628,44 +15573,44 @@ export const testData = { [ [ [ - 0.29883068799972534, - -0.5589319467544556 + 0.6188055276870728, + 1.6458454132080078 ], [ - -6.855260372161865, - -1.52199125289917 + -1.8513727188110352, + -3.90159273147583 ] ], [ [ - -4.698728084564209, - -0.45382946729660034 + 6.768861770629883, + 6.050072193145752 ], [ - -2.1931378841400146, - -2.9756503105163574 + 2.040541410446167, + 1.2624212503433228 ] ] ], [ [ [ - 0.29883068799972534, - -0.5589319467544556 + 0.6188055276870728, + 1.6458454132080078 ], [ - -6.855260372161865, - -1.52199125289917 + -1.8513727188110352, + -3.90159273147583 ] ], [ [ - -4.698728084564209, - -0.45382946729660034 + 6.768861770629883, + 6.050072193145752 ], [ - -2.1931378841400146, - -2.9756503105163574 + 2.040541410446167, + 1.2624212503433228 ] ] ] @@ -14688,106 +15633,106 @@ export const testData = { [ [ [ - 0.30319663882255554, - -0.4958910644054413, - -0.7257808446884155, - -1.3323580026626587 + 0.88399738073349, + -1.1032230854034424, + 0.4613407552242279, + -0.6266279220581055 ], [ - 1.375339150428772, - 2.910996437072754, - -1.52516508102417, - -0.5475828647613525 + 1.1519485712051392, + -0.7845342755317688, + -0.6696850061416626, + 1.264907717704773 ], [ - 1.3771235942840576, - 1.2624166011810303, - -0.018705634400248528, - 0.3129563331604004 + -1.381635308265686, + -0.36659157276153564, + -1.3767681121826172, + -0.6575090289115906 ], [ - -1.563161849975586, - 0.908475399017334, - -0.4392400085926056, - 0.8512726426124573 + -2.4963321685791016, + -0.03116716258227825, + -1.162872076034546, + -0.05399742349982262 ] ], [ [ - 0.42560550570487976, - 0.5939986109733582, - -0.7561457753181458, - -0.43741750717163086 + -0.30355918407440186, + 0.07046826928853989, + -1.5127924680709839, + 1.3581115007400513 ], [ - 0.5924250483512878, - -0.040707770735025406, - -0.14659816026687622, - 1.4060865640640259 + 0.23847708106040955, + 1.1590290069580078, + 0.13452637195587158, + -0.2990451753139496 ], [ - 1.1744377613067627, - -2.7486398220062256, - 0.9348365664482117, - -0.935459554195404 + -0.8544708490371704, + -0.8357695937156677, + 1.2985942363739014, + -0.7110929489135742 ], [ - -0.6719938516616821, - -0.020147060975432396, - -0.273457407951355, - -0.7440562844276428 + -0.004657623823732138, + -0.9602146744728088, + 0.03523630276322365, + 0.6553695797920227 ] ], [ [ - 0.8459939956665039, - -0.37988412380218506, - 0.06514627486467361, - 2.3749144077301025 + -1.226547122001648, + 1.3209213018417358, + 1.0341976881027222, + -0.49460795521736145 ], [ - 0.289336234331131, - 0.6385092735290527, - 1.729801893234253, - 0.6545563340187073 + 1.004910945892334, + -0.7041428685188293, + -0.3250839412212372, + 2.8139994144439697 ], [ - -0.35224831104278564, - 1.9751471281051636, - 0.40175172686576843, - -0.832302451133728 + 0.08612233400344849, + -1.7298319339752197, + 0.08109258860349655, + 1.2689827680587769 ], [ - 0.8574435114860535, - -0.951160728931427, - -0.2013353407382965, - -1.0537327527999878 + -1.36784029006958, + 0.22102324664592743, + -0.5776031613349915, + 1.5733610391616821 ] ], [ [ - -0.5371747016906738, - -1.025568962097168, - 0.31649506092071533, - -0.7055220007896423 + -0.540728747844696, + 0.5175154209136963, + -1.1346107721328735, + 0.4711856544017792 ], [ - 0.8945609927177429, - 0.593503475189209, - -0.7963547110557556, - 1.6775418519973755 + -0.6981925368309021, + -0.3024372160434723, + 0.3560723662376404, + 0.7634297609329224 ], [ - 0.6755470037460327, - 0.5524077415466309, - -0.03397471085190773, - 0.138251394033432 + 2.888267755508423, + -0.5556330680847168, + 0.017246929928660393, + -0.3958292305469513 ], [ - -0.45805519819259644, - -0.1399012804031372, - 1.572408676147461, - 0.23830513656139374 + 0.4055117070674896, + -0.2378912717103958, + -0.044524792581796646, + 0.6570231914520264 ] ] ] @@ -14796,144 +15741,144 @@ export const testData = { [ [ [ - 0.16055501997470856, - 0.024069391191005707, - 0.14210942387580872 + -0.16846626996994019, + -0.19352877140045166, + -0.05792432650923729 ], [ - 0.06072945147752762, - 0.15028801560401917, - 0.002978995442390442 + -0.12028075754642487, + 0.18736235797405243, + -0.16802482306957245 ], [ - 0.07864969968795776, - 0.23250140249729156, - -0.07679080218076706 + 0.14187708497047424, + 0.0448138453066349, + -0.07168931514024734 ] ], [ [ - -0.09591394662857056, - 0.1710985004901886, - 0.09013232588768005 + 0.19213205575942993, + 0.1311657726764679, + -0.008243783377110958 ], [ - -0.2224813848733902, - 0.08383052796125412, - -0.23116599023342133 + -0.15975381433963776, + -0.06937320530414581, + 0.07599683851003647 ], [ - -0.12796811759471893, - 0.09224065393209457, - 0.12416206300258636 + 0.2042289674282074, + -0.07953961938619614, + -0.09795388579368591 ] ] ], [ [ [ - -0.05322037264704704, - 0.1995139867067337, - 0.23423711955547333 + -0.23029308021068573, + 0.14487296342849731, + 0.23005151748657227 ], [ - 0.18379464745521545, - -0.2164824903011322, - -0.0857338011264801 + 0.1622759848833084, + -0.1313360184431076, + 0.16885194182395935 ], [ - 0.014340324327349663, - 0.19157220423221588, - -0.039538465440273285 + -0.07145748287439346, + 0.12322963029146194, + 0.13781873881816864 ] ], [ [ - 0.04923802614212036, - 0.12405998259782791, - -0.12331926077604294 + -0.19216682016849518, + 0.05832885205745697, + 0.09409772604703903 ], [ - -0.14274021983146667, - 0.2330939918756485, - -0.00525936484336853 + -0.14169660210609436, + 0.21791832149028778, + 0.1840069591999054 ], [ - 0.16678005456924438, - -0.22983136773109436, - -0.089967280626297 + 0.1969916969537735, + -0.002126280451193452, + -0.12610980868339539 ] ] ], [ [ [ - 0.16538912057876587, - -0.022819316014647484, - 0.07939044386148453 + -0.12880636751651764, + 0.08330836147069931, + -0.04682663828134537 ], [ - -0.19745250046253204, - 0.22941529750823975, - -0.11764149367809296 + 0.1873403787612915, + 0.1974017322063446, + 0.018188921734690666 ], [ - -0.0119181452319026, - -0.15438413619995117, - -0.10457484424114227 + -0.19296586513519287, + 0.09355738013982773, + 0.2109287977218628 ] ], [ [ - -0.20206452906131744, - -0.2063073366880417, - -0.048152972012758255 + -0.059201207011938095, + -0.12335500121116638, + -0.055137068033218384 ], [ - -0.10396576672792435, - 0.17411290109157562, - -0.0011403813259676099 + 0.03376912325620651, + -0.17488259077072144, + 0.12587366998195648 ], [ - 0.18328124284744263, - -0.03947766125202179, - 0.050005409866571426 + 0.10075010359287262, + -0.0901164561510086, + -0.08731470257043839 ] ] ], [ [ [ - 0.22636906802654266, - -0.18238647282123566, - -0.1021074578166008 + -0.11183871328830719, + 0.18424758315086365, + 0.1397935152053833 ], [ - 0.20150226354599, - -0.05403875187039375, - -0.06347790360450745 + 0.06699356436729431, + -0.010571525432169437, + 0.058881621807813644 ], [ - 0.018916010856628418, - -0.12653489410877228, - 0.01695120893418789 + 0.22740556299686432, + 0.07462751120328903, + -0.11755186319351196 ] ], [ [ - -0.09796470403671265, - 0.07477407157421112, - -0.0500338152050972 + 0.09117675572633743, + -0.09353625029325485, + -0.00836957711726427 ], [ - -0.07909317314624786, - -0.08879054337739944, - 0.061237432062625885 + -0.15181048214435577, + -0.006896039471030235, + 0.012296343222260475 ], [ - 0.11828479170799255, - -0.21548843383789062, - -0.16438578069210052 + -0.14294812083244324, + 0.15153303742408752, + 0.21769195795059204 ] ] ] @@ -14942,106 +15887,106 @@ export const testData = { [ [ [ - -0.1379297971725464, - 0.6497488617897034, - -0.38112884759902954, - -0.437771201133728 + 0.15562714636325836, + -0.5394341349601746, + 0.34747612476348877, + -0.20965653657913208 ], [ - 0.10171595215797424, - 0.23069876432418823, - -0.7280157804489136, - -0.5361753106117249 + 0.18866421282291412, + -0.8261902332305908, + -0.9921233654022217, + 0.14765621721744537 ], [ - 0.7651550769805908, - -0.49138355255126953, - 1.0020471811294556, - -0.3403889834880829 + -0.5696333646774292, + 0.41791433095932007, + -0.19561073184013367, + -0.6705589294433594 ], [ - -0.34435099363327026, - -0.22472456097602844, - 0.5050238370895386, - -0.37167200446128845 + -0.548848569393158, + 0.4616500735282898, + 0.18045620620250702, + 0.39692628383636475 ] ], [ [ - 0.1988697499036789, - 1.176051139831543, - -0.2968924045562744, - -0.20334996283054352 + -0.4001096487045288, + -0.02919364720582962, + 0.04673450440168381, + 0.9666410088539124 ], [ - -0.18382324278354645, - 0.6787427663803101, - -0.041671231389045715, - 0.40882623195648193 + -0.2005985975265503, + -0.3149549961090088, + -0.056465305387973785, + 0.15684770047664642 ], [ - 0.8475394248962402, - -0.4431191086769104, - 0.17501917481422424, - 0.10867039859294891 + -0.2335754632949829, + -0.6499486565589905, + 0.06040894240140915, + -0.03156033903360367 ], [ - 1.2691245079040527, - -0.4678799510002136, - 0.34053659439086914, - -0.295981228351593 + -0.1997881531715393, + -0.5451706051826477, + 0.37432679533958435, + -0.044711120426654816 ] ], [ [ - 0.20610792934894562, - -0.3903793394565582, - 0.03086024522781372, - 0.21915286779403687 + -0.18639610707759857, + -0.7671643495559692, + 1.1248012781143188, + 0.10564678907394409 ], [ - 0.28264015913009644, - 0.29007643461227417, - 0.5793764591217041, - 0.5104618072509766 + -0.5876757502555847, + 0.38320043683052063, + 0.324480265378952, + 0.1853906214237213 ], [ - -0.21027329564094543, - 0.74181067943573, - 0.07184755802154541, - 0.46394896507263184 + -0.6299664974212646, + -0.17470739781856537, + -0.49781695008277893, + 0.5286859273910522 ], [ - 0.4046594500541687, - -0.4858566224575043, - 0.8705565929412842, - -0.08342111110687256 + -0.7671483755111694, + -0.5986586213111877, + 0.09837397933006287, + 0.06622444093227386 ] ], [ [ - -0.5792911648750305, - 0.1761595904827118, - -0.6771392822265625, - -0.8098530769348145 + 0.040119193494319916, + 0.3281589150428772, + -0.31515181064605713, + 0.39752304553985596 ], [ - -0.5884037613868713, - -0.5537676811218262, - -0.2649165391921997, - -0.4222998023033142 + 0.43356120586395264, + -0.05420731008052826, + -0.2896234393119812, + -0.46131598949432373 ], [ - -0.4426496624946594, - -0.9145894050598145, - -0.6739007234573364, - 0.6296873688697815 + -0.14020667970180511, + -1.1087311506271362, + 0.3279479146003723, + 0.5531594157218933 ], [ - -0.294874370098114, - -0.3487393856048584, - -0.059063732624053955, - -0.09920541942119598 + -0.5165536999702454, + -0.23714134097099304, + 0.44804590940475464, + 0.16338694095611572 ] ] ] @@ -15050,106 +15995,106 @@ export const testData = { [ [ [ - 0.5092476010322571, - 0.8028393983840942, - 0.8028393983840942, - 0.45098066329956055 + -0.3493936061859131, + -0.1764393001794815, + -0.1764393001794815, + 0.18032483756542206 ], [ - 1.0263112783432007, - 1.2035737037658691, - 1.2035737037658691, - 0.7587249875068665 + -0.11093051731586456, + 0.12815320491790771, + 0.12815320491790771, + 0.4144977331161499 ], [ - 1.0263112783432007, - 1.2035737037658691, - 1.2035737037658691, - 0.7587249875068665 + -0.11093051731586456, + 0.12815320491790771, + 0.12815320491790771, + 0.4144977331161499 ], [ - 0.6953932046890259, - 0.49630922079086304, - 0.49630922079086304, - 0.1587950438261032 + 0.3364846706390381, + 0.4034411609172821, + 0.4034411609172821, + 0.29102635383605957 ] ], [ [ - 0.20018544793128967, - -0.06942684948444366, - -0.06942684948444366, - 0.3424707055091858 + 0.036554545164108276, + 0.38241228461265564, + 0.38241228461265564, + 0.6838974952697754 ], [ - 0.10140667855739594, - -0.13401083648204803, - -0.13401083648204803, - 0.23907478153705597 + 0.3561093211174011, + 0.47790342569351196, + 0.47790342569351196, + 0.37816792726516724 ], [ - 0.10140667855739594, - -0.13401083648204803, - -0.13401083648204803, - 0.23907478153705597 + 0.3561093211174011, + 0.47790342569351196, + 0.47790342569351196, + 0.37816792726516724 ], [ - -0.14707587659358978, - -0.34930646419525146, - -0.34930646419525146, - -0.022896766662597656 + 0.1666494607925415, + 0.20258954167366028, + 0.20258954167366028, + 0.10281932353973389 ] ], [ [ - 0.3659787178039551, - 0.1621423214673996, - 0.1621423214673996, - -0.23366564512252808 + 0.4680750370025635, + 0.6381124258041382, + 0.6381124258041382, + 0.6244235634803772 ], [ - 0.09205755591392517, - -0.19940245151519775, - -0.19940245151519775, - -0.6022083163261414 + 0.6706995964050293, + 0.9341139197349548, + 0.9341139197349548, + 0.8859853744506836 ], [ - 0.09205755591392517, - -0.19940245151519775, - -0.19940245151519775, - -0.6022083163261414 + 0.6706995964050293, + 0.9341139197349548, + 0.9341139197349548, + 0.8859853744506836 ], [ - -0.09449483454227448, - -0.3632378578186035, - -0.3632378578186035, - -0.374285489320755 + 0.6437886953353882, + 0.8142361640930176, + 0.8142361640930176, + 0.5254625678062439 ] ], [ [ - -0.5292990207672119, - -0.5673888325691223, - -0.5673888325691223, - -0.08430065214633942 + -0.4847356677055359, + -0.41007232666015625, + -0.41007232666015625, + -0.32400649785995483 ], [ - -0.48269906640052795, - -0.635169267654419, - -0.635169267654419, - -0.45364707708358765 + -0.4655171036720276, + -0.2604764997959137, + -0.2604764997959137, + -0.13221266865730286 ], [ - -0.48269906640052795, - -0.635169267654419, - -0.635169267654419, - -0.45364707708358765 + -0.4655171036720276, + -0.2604764997959137, + -0.2604764997959137, + -0.13221266865730286 ], [ - -0.05113664269447327, - -0.10541994869709015, - -0.10541994869709015, - -0.22392705082893372 + -0.280601441860199, + -0.01205413043498993, + -0.01205413043498993, + 0.14818523824214935 ] ] ] @@ -15158,153 +16103,153 @@ export const testData = { [ [ [ - 4.463529586791992, - 2.89654541015625, - -0.15911412239074707 + -3.185150384902954, + -3.2043797969818115, + -3.8586905002593994 ], [ - 3.3696036338806152, - 2.6538915634155273, - 1.1613938808441162 + -6.875521659851074, + -6.948748588562012, + -5.106727600097656 ], [ - 4.288078784942627, - 4.904724597930908, - 3.715423822402954 + -7.117636680603027, + -6.564235687255859, + -3.838216781616211 ] ], [ [ - 0.029211997985839844, - 0.062421560287475586, - -2.130046844482422 + -0.6054971814155579, + -0.257523775100708, + 0.6620292663574219 ], [ - -0.9363863468170166, - -1.647233009338379, - -3.1677074432373047 + -1.5351331233978271, + -0.5317901968955994, + 0.3924204707145691 ], [ - -1.1998448371887207, - -1.4732739925384521, - -2.568142890930176 + 0.2107502818107605, + -0.144018292427063, + 0.47663313150405884 ] ] ], [ [ [ - 4.463529586791992, - 2.89654541015625, - -0.15911412239074707 + -3.185150384902954, + -3.2043797969818115, + -3.8586905002593994 ], [ - 3.3696036338806152, - 2.6538915634155273, - 1.1613938808441162 + -6.875521659851074, + -6.948748588562012, + -5.106727600097656 ], [ - 4.288078784942627, - 4.904724597930908, - 3.715423822402954 + -7.117636680603027, + -6.564235687255859, + -3.838216781616211 ] ], [ [ - 0.029211997985839844, - 0.062421560287475586, - -2.130046844482422 + -0.6054971814155579, + -0.257523775100708, + 0.6620292663574219 ], [ - -0.9363863468170166, - -1.647233009338379, - -3.1677074432373047 + -1.5351331233978271, + -0.5317901968955994, + 0.3924204707145691 ], [ - -1.1998448371887207, - -1.4732739925384521, - -2.568142890930176 + 0.2107502818107605, + -0.144018292427063, + 0.47663313150405884 ] ] ], [ [ [ - 5.213554382324219, - 7.410722732543945, - 6.627640724182129 + -0.45836102962493896, + 3.1300134658813477, + 3.2655272483825684 ], [ - 4.918501853942871, - 6.06193733215332, - 4.421411991119385 + -2.182781219482422, + 2.978954315185547, + 4.482308387756348 ], [ - 4.387245178222656, - 3.155766487121582, - 2.3612351417541504 + -3.3113529682159424, + 2.3449902534484863, + 2.6217973232269287 ] ], [ [ - 0.639441192150116, - 1.7497124671936035, - 0.7167791128158569 + 0.5475001335144043, + 1.3862863779067993, + -0.2630601227283478 ], [ - 1.6138933897018433, - 2.9624695777893066, - 2.387591600418091 + 0.6705957651138306, + 2.166405200958252, + 0.11154699325561523 ], [ - 2.8601419925689697, - 4.91424036026001, - 3.802187442779541 + 1.8284196853637695, + 2.853043556213379, + 0.2574566900730133 ] ] ], [ [ [ - 5.213554382324219, - 7.410722732543945, - 6.627640724182129 + -0.45836102962493896, + 3.1300134658813477, + 3.2655272483825684 ], [ - 4.918501853942871, - 6.06193733215332, - 4.421411991119385 + -2.182781219482422, + 2.978954315185547, + 4.482308387756348 ], [ - 4.387245178222656, - 3.155766487121582, - 2.3612351417541504 + -3.3113529682159424, + 2.3449902534484863, + 2.6217973232269287 ] ], [ [ - 0.639441192150116, - 1.7497124671936035, - 0.7167791128158569 + 0.5475001335144043, + 1.3862863779067993, + -0.2630601227283478 ], [ - 1.6138933897018433, - 2.9624695777893066, - 2.387591600418091 + 0.6705957651138306, + 2.166405200958252, + 0.11154699325561523 ], [ - 2.8601419925689697, - 4.91424036026001, - 3.802187442779541 + 1.8284196853637695, + 2.853043556213379, + 0.2574566900730133 ] ] ] ], "bias": [ - -0.22620761394500732, - 0.11002491414546967, - 0.17677107453346252, - -0.22646307945251465 + -0.19714997708797455, + 0.06829815357923508, + -0.16282400488853455, + -0.0468476265668869 ], "expected_grad_bias": [ 16.0, @@ -15329,187 +16274,187 @@ export const testData = { [ [ [ - -0.2605237364768982, - 1.5151708126068115, - -1.521173357963562, - -1.1669979095458984, - 0.0013506141258403659 + -0.6729629635810852, + 0.8545035123825073, + -1.1793856620788574, + -0.9540548324584961, + -0.969673752784729 ], [ - -0.05947119742631912, - -0.2440771758556366, - 0.19028306007385254, - -0.19014781713485718, - -0.9898110032081604 + 0.3141362965106964, + 1.2000207901000977, + -0.1831716001033783, + -0.18045181035995483, + -0.1034746766090393 ], [ - 0.3790753483772278, - 1.921068549156189, - -1.5326861143112183, - 1.1929512023925781, - -0.4898732602596283 + -0.10869846493005753, + 0.5782245993614197, + 1.7499538660049438, + 0.002034955658018589, + 0.36500951647758484 ], [ - 0.12802691757678986, - -0.23840101063251495, - -0.682720422744751, - 0.46212872862815857, - -0.9165003299713135 + -0.8946718573570251, + -0.3625917434692383, + 1.179726004600525, + 0.8268131613731384, + 1.457729697227478 ], [ - 0.0817260891199112, - 0.5295277833938599, - -0.5030823349952698, - -1.2537989616394043, - 0.1978939324617386 + -1.029435634613037, + -1.2957319021224976, + 0.2842133045196533, + -2.20194673538208, + 0.5491127967834473 ] ], [ [ - -0.032255567610263824, - -0.9255485534667969, - 1.1699923276901245, - -1.6703119277954102, - -0.35372135043144226 + -1.2930694818496704, + 0.4510805904865265, + -0.3953653573989868, + 1.7161552906036377, + 0.15392881631851196 ], [ - -0.871559202671051, - 0.7829732298851013, - -0.5156939625740051, - 0.022917015478014946, - -0.6746217608451843 + -1.4651801586151123, + -0.5170696377754211, + -0.8793548941612244, + -0.8100994825363159, + 0.6788665652275085 ], [ - 1.309282898902893, - -0.780421257019043, - -1.1116023063659668, - -0.8699957132339478, - 0.7165693044662476 + 0.33716168999671936, + -0.5290454030036926, + 0.9324967265129089, + 0.6762214303016663, + 0.14378660917282104 ], [ - -0.37322181463241577, - 0.6090918779373169, - -0.7589855194091797, - -0.6492360830307007, - -1.5364243984222412 + 2.18232798576355, + 0.037647929042577744, + 0.21775013208389282, + 2.395190954208374, + 0.4023849368095398 ], [ - -0.23750557005405426, - 1.9767659902572632, - 0.4533178508281708, - -0.4910755455493927, - -0.32521501183509827 + 1.6874338388442993, + -2.743908405303955, + -1.9040486812591553, + 0.9187806844711304, + 0.12344544380903244 ] ], [ [ - 0.13093096017837524, - 0.624261200428009, - 0.8069661855697632, - 0.22351838648319244, - -0.9217655062675476 + 2.8273682594299316, + 0.47407886385917664, + -1.9149128198623657, + -1.5384353399276733, + -0.6529980897903442 ], [ - 1.927629828453064, - -0.32004305720329285, - 0.20433473587036133, - -1.9621531963348389, - -0.5470468401908875 + 0.16414928436279297, + -0.19700200855731964, + 1.038715124130249, + -0.3908529281616211, + 1.0207839012145996 ], [ - -0.6754456758499146, - 0.23817801475524902, - -0.21150951087474823, - 1.2133946418762207, - -0.19310960173606873 + -1.2268577814102173, + -2.0579991340637207, + 0.5987722277641296, + -0.13595744967460632, + -0.219259113073349 ], [ - 1.5767059326171875, - 0.11904352903366089, - 0.2899794280529022, - 0.7022011280059814, - -2.0729122161865234 + -0.47011202573776245, + -0.9500816464424133, + -0.6808398962020874, + -0.9808987379074097, + -0.7519583702087402 ], [ - 0.11511249840259552, - -0.6224449276924133, - 0.5478768348693848, - -1.3495665788650513, - -0.44743525981903076 + -1.0324863195419312, + -1.8080289363861084, + 0.21794334053993225, + 0.6857624053955078, + 0.43733805418014526 ] ], [ [ - -0.7099960446357727, - -1.4830405712127686, - 2.076340913772583, - -0.12465640902519226, - 0.055092550814151764 + -1.9561761617660522, + 1.2915894985198975, + -1.6977379322052002, + -1.2025177478790283, + -1.646543025970459 ], [ - 1.2065165042877197, - 0.1894015073776245, - -0.6532776355743408, - -0.2359209805727005, - -0.8944653868675232 + -0.789655864238739, + -1.313944935798645, + 1.211775779724121, + 0.9332025647163391, + -0.2605237364768982 ], [ - -2.372612953186035, - -0.9387015104293823, - 0.6141673922538757, - -0.3576895296573639, - -0.9380688667297363 + 1.5151708126068115, + -1.521173357963562, + -1.1669979095458984, + -2.0334060192108154, + -0.08260460197925568 ], [ - 1.4365062713623047, - 1.5855119228363037, - -0.6202625036239624, - 0.0565016008913517, - -0.21099819242954254 + 1.4479997158050537, + 0.1535591334104538, + -0.19014781713485718, + -0.9898110032081604, + 0.3790753483772278 ], [ - -1.262048602104187, - 0.021685972809791565, - 0.28762421011924744, - 0.39912644028663635, - 2.4587013721466064 + 1.921068549156189, + 0.03124547004699707, + 0.3133164942264557, + -1.2002359628677368, + -0.22739538550376892 ] ], [ [ - -0.2349012941122055, - -0.7608221173286438, - 0.4603550434112549, - 0.9160549640655518, - -1.498667597770691 + -0.23840101063251495, + -0.682720422744751, + 0.46212872862815857, + -0.9165003299713135, + -1.665152907371521 ], [ - 0.6427391171455383, - 0.18222902715206146, - -1.0757185220718384, - -1.0593551397323608, - 1.0983757972717285 + 0.7060098052024841, + 0.9033956527709961, + -0.3824882507324219, + 0.1978939324617386, + 0.6745620965957642 ], [ - -0.25671127438545227, - -2.2621774673461914, - 0.16864269971847534, - -1.6143133640289307, - -0.011093960143625736 + 0.8720393776893616, + -0.5882147550582886, + -1.3370387554168701, + 1.169712781906128, + -0.5579738020896912 ], [ - 1.2098065614700317, - -0.8380993604660034, - 1.3612878322601318, - -1.3062708377838135, - 1.6407432556152344 + 0.38680657744407654, + -0.4910755455493927, + 0.3231601417064667, + -1.1188082695007324, + 2.2093753814697266 ], [ - -0.33931660652160645, - 0.13347899913787842, - -0.9141297936439514, - -0.15479597449302673, - 1.739033579826355 + 0.6792762279510498, + 0.3959449231624603, + 0.66949063539505, + -0.19622361660003662, + -0.32004305720329285 ] ] ] @@ -15520,53 +16465,53 @@ export const testData = { [ [ [ - 0.17951110005378723, - -0.1034713163971901, - 0.1840350478887558 + -0.0833703875541687, + 0.16452591121196747, + -0.04412245377898216 ], [ - -0.12285948544740677, - 0.03490522876381874, - 0.056901540607213974 + -0.051829490810632706, + 0.015444858931005001, + -0.1033153161406517 ], [ - -0.04546049237251282, - 0.15007531642913818, - -0.17448945343494415 + 0.013840604573488235, + -0.07998784631490707, + 0.061052776873111725 ] ], [ [ - -0.07997027039527893, - -0.0302941482514143, - 0.1473943591117859 + -0.040852438658475876, + -0.0645793005824089, + -0.0724971741437912 ], [ - 0.08913317322731018, - 0.12379425019025803, - 0.08283822983503342 + 0.0500001534819603, + 0.09657912701368332, + -0.17594556510448456 ], [ - 0.17309513688087463, - -0.047928161919116974, - -0.059411607682704926 + -0.1342204213142395, + -0.18469774723052979, + 0.08983496576547623 ] ], [ [ - -0.026427024975419044, - 0.07570745050907135, - -0.056436121463775635 + 0.14433297514915466, + -0.18490633368492126, + 0.05002942681312561 ], [ - 0.07068327814340591, - 0.052763912826776505, - 0.0452510342001915 + 0.039029642939567566, + -0.10327497869729996, + 0.04157921299338341 ], [ - 0.15679700672626495, - 0.030652407556772232, - 0.12770666182041168 + 0.14839382469654083, + 0.1887684017419815, + 0.08322030305862427 ] ] ] @@ -15577,53 +16522,53 @@ export const testData = { [ [ [ - 0.5218961834907532, - -0.45145943760871887, - -0.4321322739124298 + 0.28478875756263733, + -0.5549619197845459, + -0.4311979115009308 ], [ - 0.012468090280890465, - -0.3760489523410797, - -0.21536529064178467 + -0.2621602416038513, + -0.7002687454223633, + -0.4942232072353363 ], [ - -0.5466360449790955, - 0.7558611631393433, - -0.5679531693458557 + -0.04055577516555786, + -0.29789477586746216, + 0.3332073390483856 ] ], [ [ - 0.02960394322872162, - -0.9709864258766174, - -0.6766385436058044 + 0.2114555388689041, + 0.05554547160863876, + -0.5434311628341675 ], [ - -0.2846550941467285, - 0.06001253053545952, - 0.20641230046749115 + 0.2842505872249603, + -0.37528324127197266, + -0.20882901549339294 ], [ - 0.4755805432796478, - 0.14038777351379395, - 0.3236936032772064 + 1.2247246503829956, + 0.27538585662841797, + -0.11705755442380905 ] ], [ [ - -0.15587808191776276, - -1.1645735502243042, - -0.10228501260280609 + -0.392910361289978, + -0.46385008096694946, + 0.8468499183654785 ], [ - 0.337634414434433, - -0.8189818263053894, - 0.5548167824745178 + -0.2620808780193329, + 0.5499442219734192, + -0.5437593460083008 ], [ - -0.4976823925971985, - 0.745236873626709, - -0.8393828868865967 + 0.4071813225746155, + 0.9465052485466003, + -0.03718952089548111 ] ] ] @@ -15634,187 +16579,187 @@ export const testData = { [ [ [ - 0.17951110005378723, - 0.07603978365659714, - 0.26007482409477234, - 0.0805637314915657, - 0.1840350478887558 + -0.0833703875541687, + 0.08115552365779877, + 0.037033069878816605, + 0.12040345370769501, + -0.04412245377898216 ], [ - 0.05665161460638046, - -0.01191447302699089, - 0.22902211546897888, - 0.17237050831317902, - 0.24093659222126007 + -0.1351998746395111, + 0.04477089270949364, + -0.10266687721014023, + 0.03253299742937088, + -0.14743776619434357 ], [ - 0.011191122233867645, - 0.09270034730434418, - 0.1591474860906601, - 0.14795635640621185, - 0.06644713878631592 + -0.12135927379131317, + -0.0213763490319252, + -0.10776134580373764, + 0.013597927987575531, + -0.08638498932123184 ], [ - -0.168319970369339, - 0.016660571098327637, - -0.10092733800411224, - 0.06739263236522675, - -0.11758790910243988 + -0.03798888623714447, + -0.10253187268972397, + -0.14479443430900574, + -0.10680552572011948, + -0.04226253926753998 ], [ - -0.04546049237251282, - 0.10461482405662537, - -0.06987462937831879, - -0.02441413700580597, - -0.17448945343494415 + 0.013840604573488235, + -0.06614723801612854, + -0.005094461143016815, + -0.01893506944179535, + 0.061052776873111725 ] ], [ [ - 0.0995408296585083, - -0.03422463685274124, - 0.29720476269721985, - 0.19766393303871155, - 0.3314294219017029 + -0.12422282993793488, + -0.024276215583086014, + -0.14089584350585938, + -0.016673021018505096, + -0.11661963164806366 ], [ - 0.06581451743841171, - 0.09074852615594864, - 0.5619177222251892, - 0.4961032271385193, - 0.4711691737174988 + -0.12605217099189758, + 0.08591843396425247, + -0.30996203422546387, + -0.18390992283821106, + -0.3958805203437805 ], [ - 0.19344916939735413, - 0.32053032517433167, - 0.5577985048294067, - 0.36434927582740784, - 0.2372681200504303 + -0.24643197655677795, + -0.29914698004722595, + -0.5441396832466125, + -0.29770776629447937, + -0.24499276280403137 ], [ - 0.09390833973884583, - 0.3547549843788147, - 0.2605936825275421, - 0.1666853427886963, - -0.09416128695011139 + -0.12220915406942368, + -0.27487075328826904, + -0.40324392914772034, + -0.2810347378253937, + -0.1283731460571289 ], [ - 0.12763464450836182, - 0.22978180646896362, - -0.004119262099266052, - -0.13175390660762787, - -0.23390105366706848 + -0.12037982046604156, + -0.3850654065608978, + -0.23417767882347107, + -0.11379785090684891, + 0.15088774263858795 ] ], [ [ - 0.0731138065457344, - 0.015055790543556213, - 0.29004907608032227, - 0.21693527698516846, - 0.27499330043792725 + 0.020110145211219788, + -0.06484957039356232, + -0.13143977522850037, + -0.15154993534088135, + -0.06659020483493805 ], [ - 0.11007077246904373, - 0.2634761333465576, - 0.7234602570533752, - 0.6133894920349121, - 0.45998409390449524 + 0.057310447096824646, + -0.018900267779827118, + -0.32317209243774414, + -0.38048258423805237, + -0.3042718768119812 ], [ - 0.3945024013519287, - 0.6807073354721069, - 1.0344971418380737, - 0.6399946212768555, - 0.35378968715667725 + 0.08532446622848511, + -0.06680344045162201, + -0.1369672268629074, + -0.2222917079925537, + -0.07016381621360779 ], [ - 0.3213886022567749, - 0.6656515598297119, - 0.7444479465484619, - 0.423059344291687, - 0.07879640907049179 + 0.06521431356668472, + -0.0019538700580596924, + -0.0055275410413742065, + -0.07074178755283356, + -0.0035736262798309326 ], [ - 0.2844316363334656, - 0.4172312021255493, - 0.3110368251800537, - 0.026605159044265747, - -0.1061943918466568 + 0.028014004230499268, + -0.04790318012237549, + 0.18620485067367554, + 0.15819084644317627, + 0.23410804569721222 ] ], [ [ - -0.10639729350805283, - -0.06098400056362152, - 0.02997424453496933, - 0.13637153804302216, - 0.09095823764801025 + 0.10348053276538849, + -0.14600509405136108, + -0.16847284138202667, + -0.27195337414741516, + -0.02246774733066559 ], [ - 0.05341915786266327, - 0.275390625, - 0.49443814158439636, - 0.4410189986228943, - 0.21904751658439636 + 0.19251033663749695, + -0.06367114931344986, + -0.2205052673816681, + -0.41301557421684265, + -0.15683409571647644 ], [ - 0.38331127166748047, - 0.5880069732666016, - 0.8753495216369629, - 0.4920382499694824, - 0.28734254837036133 + 0.20668374001979828, + -0.04542708396911621, + -0.029205963015556335, + -0.235889732837677, + 0.016221165657043457 ], [ - 0.4897086024284363, - 0.6489909887313843, - 0.8453752994537354, - 0.3556666970252991, - 0.19638431072235107 + 0.1032031998038292, + 0.10057801008224487, + 0.13926690816879272, + 0.03606371581554413, + 0.038688916712999344 ], [ - 0.3298921585083008, - 0.31261640787124634, - 0.3809114694595337, - 0.051019296050071716, - 0.06829505413770676 + 0.01417340338230133, + 0.018244057893753052, + 0.19129931926727295, + 0.1771259307861328, + 0.1730552613735199 ] ], [ [ - -0.026427024975419044, - 0.049280427396297455, - -0.00715569406747818, - 0.019271329045295715, - -0.056436121463775635 + 0.14433297514915466, + -0.0405733585357666, + 0.009456068277359009, + -0.13487690687179565, + 0.05002942681312561 ], [ - 0.04425625503063202, - 0.17272761464118958, - 0.16154253482818604, - 0.11728627234697342, - -0.011185087263584137 + 0.18336261808872223, + -0.10481869429349899, + -0.013210054486989975, + -0.1965726613998413, + 0.09160864353179932 ], [ - 0.20105326175689697, - 0.36017704010009766, - 0.4766985774040222, - 0.27564534544944763, - 0.11652157455682755 + 0.33175644278526306, + 0.23234352469444275, + 0.40717247128486633, + 0.07541604340076447, + 0.17482894659042358 ], [ - 0.22748029232025146, - 0.3108966052532196, - 0.4838542938232422, - 0.2563740015029907, - 0.17295768857002258 + 0.1874234676361084, + 0.27291688323020935, + 0.3977164030075073, + 0.21029293537139893, + 0.12479951977729797 ], [ - 0.15679700672626495, - 0.1874494105577469, - 0.31515607237815857, - 0.15835906565189362, - 0.12770666182041168 + 0.14839382469654083, + 0.33716222643852234, + 0.4203825294971466, + 0.2719886898994446, + 0.08322030305862427 ] ] ] @@ -15825,60 +16770,60 @@ export const testData = { [ [ [ - 2.138136148452759, - -2.9163527488708496, - -9.179944038391113 + -1.0994131565093994, + -1.5909004211425781, + -1.430722951889038 ], [ - 1.2998350858688354, - -2.119128704071045, - -10.910270690917969 + 0.008406639099121094, + 2.578151226043701, + 8.369916915893555 ], [ - 2.546753406524658, - -0.8000010251998901, - -9.619416236877441 + -7.090886116027832, + -4.349546909332275, + 7.289556503295898 ] ], [ [ - -0.32073187828063965, - -3.9941210746765137, - -5.132316589355469 + -8.079184532165527, + -8.977784156799316, + -5.922861099243164 ], [ - 1.885986566543579, - -3.3577966690063477, - -11.19390869140625 + -4.117936134338379, + -7.149350166320801, + 1.0563101768493652 ], [ - 1.2160885334014893, - 0.35297536849975586, - -4.404627323150635 + -4.687833786010742, + -11.71389389038086, + -2.1212964057922363 ] ], [ [ - -2.482264518737793, - -5.141534328460693, - -4.461568832397461 + -5.006127834320068, + -10.796634674072266, + -10.494353294372559 ], [ - 2.728120803833008, - -6.530619144439697, - -6.614537239074707 + -4.042076110839844, + -9.996551513671875, + -1.5225372314453125 ], [ - -1.607851505279541, - -3.451260566711426, - 1.077123999595642 + -3.995260238647461, + -12.888031005859375, + -5.185653209686279 ] ] ] ] ], "bias": [ - -0.05365540832281113 + -0.038159918040037155 ], "expected_grad_bias": [ 27.0 @@ -15899,6 +16844,144 @@ export const testData = { [ [ [ + [ + 1.5721423625946045, + 1.0094727277755737, + 0.4029425382614136, + 1.6145533323287964 + ], + [ + 0.4475519359111786, + 0.5499113202095032, + 0.21999366581439972, + -0.019641423597931862 + ], + [ + 0.20199595391750336, + -0.305207222700119, + -0.11879883706569672, + 0.8017854690551758 + ], + [ + -0.3870505392551422, + 1.560797929763794, + 0.04964430257678032, + -0.33324524760246277 + ] + ], + [ + [ + 0.9817765355110168, + 1.0983757972717285, + -0.25671127438545227, + -2.2621774673461914 + ], + [ + 0.16864269971847534, + -1.6143133640289307, + -0.011093960143625736, + 1.2098065614700317 + ], + [ + -1.4476906061172485, + 1.3612878322601318, + -1.3062708377838135, + 1.6407432556152344 + ], + [ + -0.33931660652160645, + 0.13347899913787842, + -0.9141297936439514, + -0.15479597449302673 + ] + ], + [ + [ + 0.39503413438796997, + -0.09881415218114853, + -1.8138774633407593, + -0.6933608055114746 + ], + [ + 1.3770830631256104, + 1.0369852781295776, + 0.522045910358429, + -2.008735179901123 + ], + [ + -0.7871567606925964, + 0.07242458313703537, + -1.9583851099014282, + -0.1682676076889038 + ], + [ + -0.09407275170087814, + -1.5021157264709473, + 0.9083237051963806, + -0.627318799495697 + ] + ], + [ + [ + 1.345549464225769, + 0.32771772146224976, + 1.3408823013305664, + 1.2158557176589966 + ], + [ + 0.95885169506073, + 0.5136737823486328, + 0.5763065814971924, + 0.0778578370809555 + ], + [ + -1.061161994934082, + 2.042306900024414, + 0.6509259343147278, + -1.0072094202041626 + ], + [ + 0.35781362652778625, + -1.0799492597579956, + 0.04710597172379494, + 2.201401472091675 + ] + ] + ], + [ + [ + [ + 0.7588040828704834, + -1.5863133668899536, + -0.6730678081512451, + -1.2264569997787476 + ], + [ + 1.3401838541030884, + -1.162084698677063, + 1.4780147075653076, + 1.5603762865066528 + ], + [ + -0.3231433033943176, + 2.119018793106079, + 0.7877871990203857, + -1.9625552892684937 + ], + [ + -0.526032567024231, + 2.639968156814575, + 1.171855092048645, + 1.2722933292388916 + ] + ], + [ + [ + -0.699771523475647, + -1.096972107887268, + -0.55166095495224, + -0.3263216018676758 + ], [ 0.6205294132232666, -1.4098610877990723, @@ -15906,25 +16989,25 @@ export const testData = { 3.068681478500366 ], [ - -0.9697644114494324, - -0.6346449851989746, - -1.3389408588409424, - -0.8127626180648804 + 0.3701395094394684, + -0.7284356355667114, + -0.9289583563804626, + 0.8983376026153564 ], [ -0.48385927081108093, 0.032833296805620193, -0.10948953032493591, 0.46667027473449707 - ], - [ - -0.397339403629303, - -1.1817593574523926, - -0.626708984375, - 0.2615565061569214 ] ], [ + [ + -1.1001535654067993, + 0.8703535795211792, + 0.9143402576446533, + -0.9333758354187012 + ], [ -1.9243427515029907, 0.5441842079162598, @@ -15932,25 +17015,25 @@ export const testData = { -0.1457550972700119 ], [ - -0.5444673299789429, - 0.276648610830307, - 0.25740426778793335, - 0.7235954999923706 + -0.663499116897583, + 1.2121490240097046, + 0.9221742749214172, + 0.5710628032684326 ], [ -0.7049512267112732, 2.053586959838867, 0.9570578932762146, -1.0222344398498535 - ], - [ - -1.2120782136917114, - 0.5006001591682434, - -0.4498424530029297, - 0.7352223992347717 ] ], [ + [ + 0.2908516526222229, + -0.08251824229955673, + 1.5195056200027466, + -0.3584267199039459 + ], [ -0.6102548837661743, -1.5060930252075195, @@ -15958,25 +17041,29 @@ export const testData = { 1.0847911834716797 ], [ - 0.5897902846336365, - -0.1373262107372284, - -1.664083480834961, - -0.6784767508506775 + 1.4872429370880127, + 0.6041548848152161, + -1.1257244348526, + 0.3761575222015381 ], [ 1.959293246269226, -0.7958163619041443, 0.4539487659931183, -2.5069937705993652 - ], - [ - -0.3836418688297272, - -0.7841960787773132, - -1.3441016674041748, - -0.6836838722229004 ] - ], + ] + ] + ], + [ + [ [ + [ + 0.4042589068412781, + -1.5217982530593872, + -0.5133728981018066, + -1.3806458711624146 + ], [ -0.5332193970680237, 1.0821458101272583, @@ -15984,27 +17071,25 @@ export const testData = { -1.729612946510315 ], [ - -1.380746603012085, - 1.090315580368042, - 1.5219553709030151, - -1.1226063966751099 + -2.14782977104187, + 0.4973359704017639, + -1.268904685974121, + -0.24232769012451172 ], [ -1.0745846033096313, -0.6819858551025391, 1.0070197582244873, -0.8279359936714172 - ], - [ - 1.0574713945388794, - 0.07679933309555054, - 0.135556161403656, - 0.48973140120506287 ] - ] - ], - [ + ], [ + [ + 0.6613953113555908, + -0.03297487273812294, + -0.13994985818862915, + 1.0257868766784668 + ], [ -1.9717178344726562, 0.5998077988624573, @@ -16012,25 +17097,25 @@ export const testData = { -0.173064723610878 ], [ - -0.19370204210281372, - 1.1805676221847534, - 0.9929208755493164, - 0.3026696443557739 + 0.7555463910102844, + -0.14636565744876862, + -0.09429822862148285, + 0.29657915234565735 ], [ 0.11924134939908981, 0.1167483851313591, -0.5673035979270935, -1.7532938718795776 - ], - [ - -0.503811240196228, - -1.0558961629867554, - -0.9048318862915039, - -0.006893915124237537 ] ], [ + [ + -0.5004768371582031, + -0.8111429214477539, + 2.0269458293914795, + -2.568801164627075 + ], [ 1.0234973430633545, -0.5307855606079102, @@ -16038,25 +17123,25 @@ export const testData = { 0.9496951103210449 ], [ - -0.6222965717315674, - -0.6353561282157898, - -2.6204559803009033, - 1.2924344539642334 + 1.4498697519302368, + 1.9099774360656738, + -0.41487377882003784, + -2.154376745223999 ], [ -1.1843920946121216, -0.13271500170230865, -0.6129738092422485, 1.0654757022857666 - ], - [ - -0.578273355960846, - -0.59147047996521, - 0.09498756378889084, - -0.4672579765319824 ] ], [ + [ + -1.361000418663025, + 1.183761477470398, + -1.1673825979232788, + -0.25077250599861145 + ], [ 0.33264845609664917, 1.1230510473251343, @@ -16064,25 +17149,27 @@ export const testData = { 0.273639976978302 ], [ - 1.1153037548065186, - -0.0976748913526535, - 1.1017417907714844, - 0.7865778803825378 + 0.2801147401332855, + 0.7281787991523743, + 0.02403142862021923, + 2.3937904834747314 ], [ -1.3129955530166626, -0.48624828457832336, 0.4012764096260071, 1.0767757892608643 - ], - [ - -0.1310465782880783, - 0.4173567295074463, - -0.39924731850624084, - -0.03817286342382431 ] - ], + ] + ], + [ [ + [ + 2.587069511413574, + -0.7386665940284729, + 0.3296529948711395, + 2.8114237785339355 + ], [ -0.879487931728363, -0.33060166239738464, @@ -16090,29 +17177,25 @@ export const testData = { 0.17840361595153809 ], [ - -2.1722629070281982, - 0.387355238199234, - 0.8891183733940125, - -0.09997355192899704 + -1.1289931535720825, + -0.3602311313152313, + -2.383305549621582, + 1.3506853580474854 ], [ -0.4065081775188446, -0.30150434374809265, -1.5348396301269531, 1.6021355390548706 - ], - [ - 0.8561490178108215, - 1.2442771196365356, - 1.471459150314331, - -0.3713514506816864 ] - ] - ] - ], - [ - [ + ], [ + [ + -1.0694472789764404, + 0.08452916890382767, + 0.33887022733688354, + -1.223060965538025 + ], [ 0.19821691513061523, 0.38515371084213257, @@ -16120,25 +17203,25 @@ export const testData = { 0.8780375719070435 ], [ - 0.5718429088592529, - 0.11539655178785324, - 0.4864003360271454, - -1.3612200021743774 + 0.12963341176509857, + -0.6663824319839478, + 0.4921484887599945, + -0.9834228754043579 ], [ -1.2953417301177979, -1.5002580881118774, 1.1558160781860352, -0.7528656125068665 - ], - [ - 0.9919346570968628, - -1.7107722759246826, - -0.31297874450683594, - -0.1376810520887375 ] ], [ + [ + 0.589937686920166, + -1.330565333366394, + 1.276455044746399, + -1.1509960889816284 + ], [ 1.4542961120605469, 0.21978320181369781, @@ -16146,25 +17229,25 @@ export const testData = { 0.7749262452125549 ], [ - 0.2638930678367615, - -0.34526365995407104, - 1.8549134731292725, - -0.44352102279663086 + 0.12985540926456451, + 1.0439496040344238, + -1.7788974046707153, + 0.3559875190258026 ], [ -0.05403977632522583, 0.07127834856510162, -0.8058504462242126, -0.35074129700660706 - ], - [ - -0.023307736963033676, - 0.9396457672119141, - 0.5839836597442627, - 1.0035940408706665 ] ], [ + [ + 1.1279785633087158, + 0.02586616761982441, + -0.14947263896465302, + 0.39506977796554565 + ], [ 1.9742354154586792, -0.4404173791408539, @@ -16172,154 +17255,16 @@ export const testData = { -0.34589144587516785 ], [ - 0.12100548297166824, - -0.12694284319877625, - 0.2732967436313629, - -0.4074859023094177 + 2.694831609725952, + -0.8544124364852905, + -0.27781322598457336, + 0.7772916555404663 ], [ -0.43923330307006836, 1.1729096174240112, 1.397361159324646, -0.41255858540534973 - ], - [ - 0.6318085193634033, - 1.6719400882720947, - 1.4667576551437378, - -0.46806567907333374 - ] - ], - [ - [ - 1.5237687826156616, - 1.2984881401062012, - 0.6588833928108215, - -0.8222662210464478 - ], - [ - -2.1720073223114014, - -0.23861387372016907, - 0.29227569699287415, - 0.5224646925926208 - ], - [ - 0.5731524229049683, - 1.3903805017471313, - -0.23513318598270416, - -0.5386273264884949 - ], - [ - -1.4448024034500122, - -0.7072859406471252, - -0.8268908262252808, - -0.8726862072944641 - ] - ] - ], - [ - [ - [ - 1.9504122734069824, - 1.0814120769500732, - 0.7843427658081055, - 1.8615505695343018 - ], - [ - 0.7698028087615967, - -0.9483721852302551, - -0.046345002949237823, - 0.4453408420085907 - ], - [ - -0.3184575140476227, - 1.1182889938354492, - 1.8907326459884644, - 0.19988827407360077 - ], - [ - 0.6960347890853882, - -0.821993350982666, - -0.7360109686851501, - 0.25674745440483093 - ] - ], - [ - [ - -0.9977543950080872, - 0.45807182788848877, - 0.7924372553825378, - -0.9643475413322449 - ], - [ - -0.27225175499916077, - 0.5005932450294495, - 1.8431296348571777, - -0.17798323929309845 - ], - [ - 0.7460726499557495, - 0.26590028405189514, - -1.0854178667068481, - -1.5084643363952637 - ], - [ - 0.8140530586242676, - -0.6385701298713684, - -0.3107047379016876, - -0.5998176336288452 - ] - ], - [ - [ - 0.5251074433326721, - -0.8383287787437439, - 1.7227904796600342, - -1.1731188297271729 - ], - [ - 0.1619594246149063, - 1.0863298177719116, - 0.29311972856521606, - -1.1984928846359253 - ], - [ - -0.20503655076026917, - -0.5375787019729614, - 1.2967820167541504, - -1.6138769388198853 - ], - [ - -0.8897020220756531, - -1.540779709815979, - 0.5420194268226624, - 0.7579821944236755 - ] - ], - [ - [ - -1.1333380937576294, - -0.7435185313224792, - -0.7013434171676636, - -0.42178988456726074 - ], - [ - -1.4793615341186523, - -1.5361236333847046, - -0.3792397677898407, - 0.2467799037694931 - ], - [ - 0.019135747104883194, - -0.7149955034255981, - -0.7025302648544312, - 0.7700265645980835 - ], - [ - 0.2053217887878418, - 0.5622282028198242, - -0.9420557022094727, - 2.099351644515991 ] ] ] @@ -16330,44 +17275,44 @@ export const testData = { [ [ [ - -0.24626165628433228, - 0.23581910133361816 + -0.04464086890220642, + 0.13030219078063965 ], [ - -0.13763979077339172, - 0.057132333517074585 + 0.19273826479911804, + 0.19454172253608704 ] ], [ [ - 0.15548455715179443, - -0.038823604583740234 + -0.18497413396835327, + 0.017949223518371582 ], [ - 0.19538354873657227, - 0.16201353073120117 + -0.20529252290725708, + -0.17236840724945068 ] ] ], [ [ [ - -0.050332069396972656, - 0.06554695963859558 + 0.1919710338115692, + -0.19917979836463928 ], [ - 0.018945902585983276, - 0.2445722222328186 + -0.12260425090789795, + 0.11989259719848633 ] ], [ [ - 0.17308229207992554, - -0.1665104329586029 + 0.24324333667755127, + -0.2428540289402008 ], [ - 0.024087965488433838, - 0.13483983278274536 + -0.1613200604915619, + -0.0980333685874939 ] ] ] @@ -16376,44 +17321,44 @@ export const testData = { [ [ [ - 0.1911259889602661, - 0.08535802364349365 + 0.19366449117660522, + 0.14569279551506042 ], [ - 0.10622924566268921, - -0.046158403158187866 + 0.1558559536933899, + 0.16019022464752197 ] ], [ [ - 0.005422472953796387, - -0.17302614450454712 + -0.06256577372550964, + 0.18433409929275513 ], [ - 0.20581024885177612, - 0.19685980677604675 + -0.007025092840194702, + 0.023488402366638184 ] ] ], [ [ [ - -0.1376614272594452, - -0.2140360176563263 + -0.06629806756973267, + 0.10605272650718689 ], [ - 0.19494691491127014, - -0.22157776355743408 + 0.11164060235023499, + -0.02650010585784912 ] ], [ [ - 0.16033044457435608, - -0.2435099482536316 + 0.22008481621742249, + -0.06474655866622925 ], [ - -0.12781327962875366, - -0.10584864020347595 + 0.06327742338180542, + 0.22706493735313416 ] ] ] @@ -16422,44 +17367,44 @@ export const testData = { [ [ [ - 0.23495128750801086, - -0.042303770780563354 + 0.14085400104522705, + -0.09103536605834961 ], [ - 0.21564671397209167, - 0.07263556122779846 + -0.11324527859687805, + 0.048248857259750366 ] ], [ [ - 0.242195725440979, - 0.165586918592453 + -0.0018947124481201172, + 0.017594724893569946 ], [ - 0.1841185986995697, - 0.21796229481697083 + 0.1610410511493683, + 0.08738741278648376 ] ] ], [ [ [ - -0.07386279106140137, - -0.06873634457588196 + -0.14021095633506775, + -0.2041163444519043 ], [ - 0.08055216073989868, - 0.22023555636405945 + 0.23635441064834595, + -0.027522504329681396 ] ], [ [ - -0.0920020043849945, - -0.1966536045074463 + -0.09849092364311218, + -0.18361523747444153 ], [ - -0.19556531310081482, - -0.11550003290176392 + 0.24006971716880798, + 0.1261514127254486 ] ] ] @@ -16470,159 +17415,159 @@ export const testData = { [ [ [ - -0.12544064223766327, - -0.10488642007112503, - 0.6352924108505249 + -0.5038596987724304, + -0.11328840255737305, + -0.29208752512931824 ], [ - 0.04748120158910751, - -0.05280660092830658, - 0.014852432534098625 + -0.4790585935115814, + -1.2338014841079712, + 0.3766993582248688 ], [ - 0.13920727372169495, - -0.1516159176826477, - 0.07936608046293259 + -0.037682030349969864, + -0.08873514086008072, + 0.21263472735881805 ] ], [ [ - 0.12625285983085632, - 0.5247550010681152, - 0.29648762941360474 + -0.011624469421803951, + 0.1745271384716034, + -0.261569619178772 ], [ - -0.527458667755127, - -0.6843790411949158, - -0.4757048189640045 + 0.19541247189044952, + -0.7095012068748474, + 0.8612315058708191 ], [ - -0.24712897837162018, - -0.08450428396463394, - -0.23055703938007355 + 0.06318911164999008, + 0.3058077394962311, + -0.19460046291351318 ] ], [ [ - -0.20567108690738678, - 0.07920943200588226, - 0.28133490681648254 + 0.1381525844335556, + 0.3578319549560547, + 0.11980266869068146 ], [ - -0.5889145135879517, - -0.06061249226331711, - 0.46568891406059265 + 0.05987616628408432, + 0.06979464739561081, + -0.1939573585987091 ], [ - 0.3453812003135681, - 0.08676793426275253, - -0.06201987341046333 + -0.5021116137504578, + -0.3473271131515503, + -0.7380265593528748 ] ] ], [ [ [ - 0.30193081498146057, - -0.6216078996658325, - 0.6247559785842896 + -0.006691743154078722, + -0.46675175428390503, + -0.30486610531806946 ], [ - 0.07815887033939362, - 0.17712479829788208, - 0.3353296220302582 + -0.288819819688797, + -0.24890491366386414, + -0.0010907119140028954 ], [ - 0.16250303387641907, - 0.1241421103477478, - -0.028617149218916893 + -0.25320446491241455, + 0.200725257396698, + 0.08494552969932556 ] ], [ [ - -0.3222348392009735, - -1.5121803283691406, - 0.3290128707885742 + -0.2806292176246643, + 0.02707899920642376, + -0.6591119170188904 ], [ - 0.5038116574287415, - 0.9266672134399414, - -0.5005884766578674 + -0.1579609364271164, + -0.25223442912101746, + 0.30185988545417786 ], [ - 0.08967182040214539, - 0.481889933347702, - 0.1660858392715454 + -0.28836485743522644, + 0.31437602639198303, + -0.462564080953598 ] ], [ [ - 0.19055739045143127, - -0.15107333660125732, - -0.17788636684417725 + -0.008080392144620419, + 0.0004768797953147441, + -0.06643328815698624 ], [ - 0.4578288495540619, - 0.22812111675739288, - -0.005346504505723715 + -0.3503379225730896, + 0.5052304267883301, + -0.3877430558204651 ], [ - -0.12191318720579147, - -0.48891517519950867, - 0.11579104512929916 + 0.04400258883833885, + -0.31729790568351746, + 0.3766254782676697 ] ] ], [ [ [ - 0.29631558060646057, - -0.6913065314292908, - 0.5321769118309021 + 0.4502900540828705, + -0.050775207579135895, + 0.18275459110736847 ], [ - -0.3083934485912323, - -0.7210930585861206, - 0.13744239509105682 + -0.04413630813360214, + 0.6116383075714111, + -0.27849501371383667 ], [ - -0.03338782861828804, - -0.18157877027988434, - -0.002687789499759674 + 0.3069579303264618, + -0.2600867450237274, + 0.09250245988368988 ] ], [ [ - -0.15246857702732086, - -0.20002339780330658, - 0.12461421638727188 + 0.17954453825950623, + -0.013814925216138363, + 0.06049893796443939 ], [ - 0.1441238522529602, - 0.0658457800745964, - -1.0355932712554932 + 0.2202102690935135, + -0.1964309960603714, + 0.11200179904699326 ], [ - -0.013401327654719353, - -0.2652435004711151, - -0.021488817408680916 + 0.47461840510368347, + -0.022217681631445885, + 0.23181389272212982 ] ], [ [ - -0.29909512400627136, - 0.32880789041519165, - -0.4252844750881195 + 0.27409666776657104, + 0.18343980610370636, + -0.005225253291428089 ], [ - -0.026526324450969696, - -0.40084484219551086, - -0.3725295960903168 + 0.16232147812843323, + 0.5799760222434998, + 0.27901557087898254 ], [ - -0.17025350034236908, - -0.24740883708000183, - 0.07582216709852219 + -0.21531707048416138, + 0.07970071583986282, + 0.8787646293640137 ] ] ] @@ -16631,159 +17576,159 @@ export const testData = { [ [ [ - 0.33499839901924133, - 0.23510107398033142, - 0.2562863826751709 + -0.48178449273109436, + 0.32926392555236816, + -0.3285866677761078 ], [ - -0.3632935583591461, - 0.05853582173585892, - -0.23695941269397736 + 0.5264294147491455, + -0.1760045886039734, + 0.036700669676065445 ], [ - -0.1145162284374237, - -0.23367537558078766, - 0.06292246282100677 + -0.07904969900846481, + 0.2851441204547882, + 0.38437163829803467 ] ], [ [ - 0.2696138620376587, - 0.7088768482208252, - -0.1808793544769287 + -0.1296009123325348, + -0.2551492750644684, + 0.9022114276885986 ], [ - 0.13318367302417755, - 1.0680162906646729, - -0.21250930428504944 + -0.8898090720176697, + 0.12122566252946854, + 0.5932097434997559 ], [ - 0.21136917173862457, - -0.19593563675880432, - -0.11864905059337616 + 0.10692428052425385, + -0.529249370098114, + -0.5071446299552917 ] ], [ [ - -0.15023523569107056, - -0.28680452704429626, - 0.1450766623020172 + -0.28801897168159485, + -0.17852434515953064, + -0.2552545666694641 ], [ - -0.5318515300750732, - -0.17013579607009888, - -0.012467258609831333 + -0.13078252971172333, + -0.30658066272735596, + 0.12897521257400513 ], [ - -0.2873624861240387, - -0.0709749385714531, - 0.14913572371006012 + -0.24208368360996246, + -0.13765157759189606, + -0.2857514023780823 ] ] ], [ [ [ - -0.19635766744613647, - -0.18530386686325073, - -0.08615187555551529 + 0.3810115158557892, + -0.18917249143123627, + -0.02831784449517727 ], [ - -0.5366209745407104, - -0.6775302886962891, - -0.14540544152259827 + -0.5640672445297241, + -0.8773369789123535, + 0.01873210072517395 ], [ - -0.37005215883255005, - 0.06338219344615936, - 0.011487733572721481 + -0.38767924904823303, + 0.045399442315101624, + 0.18848949670791626 ] ], [ [ - 0.4580877721309662, - 0.2233516424894333, - -0.05585471913218498 + 0.040571633726358414, + 0.01593371294438839, + -0.24737092852592468 ], [ - -0.23609213531017303, - 0.4398602545261383, - -0.4935249388217926 + -0.20651893317699432, + 0.14015652239322662, + -0.2224198579788208 ], [ - -0.09782442450523376, - -0.26882562041282654, - 0.3644440770149231 + -0.5507435202598572, + -0.09074224531650543, + -0.6494090557098389 ] ], [ [ - 0.1518576592206955, - 0.08904975652694702, - -0.1985054910182953 + -0.4638271629810333, + -0.21157491207122803, + -0.21089521050453186 ], [ - 0.0716124176979065, - 0.41787996888160706, - 0.12985070049762726 + 0.015379182994365692, + 0.5860069394111633, + 0.3198734223842621 ], [ - -0.1962018609046936, - -0.11045592278242111, - -0.48472288250923157 + -0.453792542219162, + -0.18119028210639954, + 0.019968409091234207 ] ] ], [ [ [ - -0.24873878061771393, - -0.31377995014190674, - -0.2690615952014923 + 0.5788699984550476, + -0.20849919319152832, + 0.6697774529457092 ], [ - -0.3689185082912445, - -0.3231930732727051, - -0.6150315999984741 + 0.0391685776412487, + -0.27752864360809326, + 0.48812031745910645 ], [ - -0.03929625824093819, - -0.3124725818634033, - -0.12363695353269577 + 0.27291446924209595, + 0.5477061867713928, + 0.0609532967209816 ] ], [ [ - 0.18888165056705475, - 0.5758501887321472, - 0.1884964108467102 + 0.30921193957328796, + 0.11291491240262985, + -0.8780627250671387 ], [ - 0.01739897020161152, - -0.3179147243499756, - -0.10364465415477753 + 0.28316259384155273, + 0.3493956923484802, + -0.5359333753585815 ], [ - 0.15794339776039124, - 0.8808969855308533, - 0.030330616980791092 + 0.4598090946674347, + 0.3901137113571167, + 0.10830800980329514 ] ], [ [ - -0.20559145510196686, - 0.04685036838054657, - -0.2779650092124939 + 0.12046888470649719, + 0.037027567625045776, + 0.33895567059516907 ], [ - 0.1727457195520401, - 0.07486840337514877, - -0.016269924119114876 + -0.27672937512397766, + -0.49539312720298767, + 0.21685229241847992 ], [ - -0.019662391394376755, - -0.17464134097099304, - -0.4267726540565491 + 0.42636412382125854, + -0.33751899003982544, + 0.4266938269138336 ] ] ] @@ -16794,212 +17739,212 @@ export const testData = { [ [ [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ], [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ] ], [ [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ], [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ] ], [ [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ], [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ] ], [ [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ], [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ] ] ], [ [ [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ], [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ] ], [ [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ], [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ] ], [ [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ], [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ] ], [ [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ], [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ] ] ] @@ -17008,212 +17953,212 @@ export const testData = { [ [ [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ], [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ] ], [ [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ], [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ] ], [ [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ], [ - 0.5768356323242188, - 0.5853123664855957, - 0.5768356323242188, - 0.5853123664855957 + -0.061492592096328735, + -0.051276564598083496, + -0.061492592096328735, + -0.051276564598083496 ], [ - -0.04626283049583435, - 0.4031027555465698, - -0.04626283049583435, - 0.4031027555465698 + 0.21987804770469666, + -0.24943462014198303, + 0.21987804770469666, + -0.24943462014198303 ] ], [ [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ], [ - 0.08360949158668518, - 0.18423616886138916, - 0.08360949158668518, - 0.18423616886138916 + 0.4029808044433594, + 0.23534893989562988, + 0.4029808044433594, + 0.23534893989562988 ], [ - 0.27887335419654846, - 0.1798156201839447, - 0.27887335419654846, - 0.1798156201839447 + 0.18495962023735046, + 0.28987762331962585, + 0.18495962023735046, + 0.28987762331962585 ] ] ], [ [ [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ], [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ] ], [ [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ], [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ] ], [ [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ], [ - -0.0865088403224945, - -0.29929062724113464, - -0.0865088403224945, - -0.29929062724113464 + 0.25518298149108887, + 0.1420270800590515, + 0.25518298149108887, + 0.1420270800590515 ], [ - -0.6066739559173584, - 0.2414107322692871, - -0.6066739559173584, - 0.2414107322692871 + -0.4912158250808716, + 0.3648372292518616, + -0.4912158250808716, + 0.3648372292518616 ] ], [ [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ], [ - 0.24323001503944397, - 0.2944449782371521, - 0.24323001503944397, - 0.2944449782371521 + 0.06586998701095581, + 0.22539076209068298, + 0.06586998701095581, + 0.22539076209068298 ], [ - -0.21722540259361267, - -0.2618562877178192, - -0.21722540259361267, - -0.2618562877178192 + -0.2972434163093567, + -0.014537990093231201, + -0.2972434163093567, + -0.014537990093231201 ] ] ] @@ -17224,44 +18169,44 @@ export const testData = { [ [ [ - 2.6286404132843018, - -2.0866897106170654 + 2.0645761489868164, + 1.082654595375061 ], [ - 1.3156142234802246, - 2.8917975425720215 + 9.614883422851562, + -0.7942436933517456 ] ], [ [ - -7.076124668121338, - -1.9047226905822754 + -2.149080514907837, + 4.818809986114502 ], [ - -2.5816783905029297, - 5.9409565925598145 + -4.0391926765441895, + -3.070486307144165 ] ] ], [ [ [ - 1.2151155471801758, - -3.202683687210083 + -2.5816783905029297, + 5.9409565925598145 ], [ - -0.35901355743408203, - -3.502537488937378 + -3.1585464477539062, + 3.6483538150787354 ] ], [ [ - -0.4747035503387451, - 1.8682055473327637 + 7.604015350341797, + 1.6200573444366455 ], [ - 0.875652551651001, - 7.885148048400879 + 1.0454699993133545, + 0.24501657485961914 ] ] ] @@ -17270,44 +18215,44 @@ export const testData = { [ [ [ - 2.6286404132843018, - -2.0866897106170654 + 2.0645761489868164, + 1.082654595375061 ], [ - 1.3156142234802246, - 2.8917975425720215 + 9.614883422851562, + -0.7942436933517456 ] ], [ [ - -7.076124668121338, - -1.9047226905822754 + -2.149080514907837, + 4.818809986114502 ], [ - -2.5816783905029297, - 5.9409565925598145 + -4.0391926765441895, + -3.070486307144165 ] ] ], [ [ [ - 1.2151155471801758, - -3.202683687210083 + -2.5816783905029297, + 5.9409565925598145 ], [ - -0.35901355743408203, - -3.502537488937378 + -3.1585464477539062, + 3.6483538150787354 ] ], [ [ - -0.4747035503387451, - 1.8682055473327637 + 7.604015350341797, + 1.6200573444366455 ], [ - 0.875652551651001, - 7.885148048400879 + 1.0454699993133545, + 0.24501657485961914 ] ] ] @@ -17316,53 +18261,53 @@ export const testData = { [ [ [ - 2.6286404132843018, - -2.0866897106170654 + 2.0645761489868164, + 1.082654595375061 ], [ - 1.3156142234802246, - 2.8917975425720215 + 9.614883422851562, + -0.7942436933517456 ] ], [ [ - -7.076124668121338, - -1.9047226905822754 + -2.149080514907837, + 4.818809986114502 ], [ - -2.5816783905029297, - 5.9409565925598145 + -4.0391926765441895, + -3.070486307144165 ] ] ], [ [ [ - 1.2151155471801758, - -3.202683687210083 + -2.5816783905029297, + 5.9409565925598145 ], [ - -0.35901355743408203, - -3.502537488937378 + -3.1585464477539062, + 3.6483538150787354 ] ], [ [ - -0.4747035503387451, - 1.8682055473327637 + 7.604015350341797, + 1.6200573444366455 ], [ - 0.875652551651001, - 7.885148048400879 + 1.0454699993133545, + 0.24501657485961914 ] ] ] ] ], "bias": [ - 0.03989130258560181, - -0.02893012762069702, - -0.06666991114616394 + -0.15848389267921448, + -0.21591666340827942, + 0.21718040108680725 ], "expected_grad_bias": [ 54.0, @@ -17386,374 +18331,374 @@ export const testData = { [ [ [ - -2.0308878421783447, - 0.6461803913116455, - 1.217452883720398, - 0.03121299482882023, - -0.5765647292137146 + -0.17826782166957855, + -0.2625838816165924, + 0.7513576745986938, + 0.18278615176677704, + -0.9977543950080872 ], [ - -1.4563747644424438, - 1.5021625757217407, - 1.0934816598892212, - -0.6195639967918396, - 1.8281400203704834 + 0.45807182788848877, + 0.7924372553825378, + -0.9643475413322449, + 0.46591266989707947, + 1.3539252281188965 ], [ - 0.4877544343471527, - 0.1366790533065796, - -0.013499530963599682, - -0.6400911808013916, - -1.3593297004699707 + -1.459295630455017, + 0.37469375133514404, + 0.7460726499557495, + 0.26590028405189514, + -1.0854178667068481 ], [ - 1.311326026916504, - 0.8920031785964966, - 1.8720558881759644, - 0.24501417577266693, - 0.7017510533332825 + -1.5084643363952637, + -0.4339471161365509, + 0.9574882388114929, + 1.254128336906433, + -1.0384563207626343 ], [ - 0.43805480003356934, - -1.3179324865341187, - -2.430510997772217, - -1.3101704120635986, - -1.439155101776123 + 0.5251074433326721, + -0.8383287787437439, + 1.7227904796600342, + -1.1731188297271729, + 0.7272883057594299 ] ], [ [ - -1.2797472476959229, - -0.19622953236103058, - 0.19903564453125, - 0.8379256725311279, - 0.27458760142326355 + -1.7194626331329346, + 2.383774995803833, + -1.1649107933044434, + -0.20503655076026917, + -0.5375787019729614 ], [ - 0.02786351554095745, - -0.3553343415260315, - -1.2540193796157837, - -1.2696188688278198, - 0.6492337584495544 + 1.2967820167541504, + -1.6138769388198853, + -0.8155969977378845, + -0.1509992778301239, + -0.5020706653594971 ], [ - 0.2340298593044281, - -1.1880178451538086, - 0.7492989897727966, - 0.9463486075401306, - -1.4556224346160889 + 0.8036778569221497, + -1.1333380937576294, + -0.7435185313224792, + -0.7013434171676636, + -0.42178988456726074 ], [ - -1.865479826927185, - -2.1207547187805176, - -0.6719433665275574, - -0.7559810280799866, - 0.37926021218299866 + -1.5332636833190918, + -1.9342981576919556, + 0.3510490953922272, + -0.6404718160629272, + 0.019135747104883194 ], [ - 1.0466166734695435, - -1.5519970655441284, - 0.3812021315097809, - 0.350207656621933, - -0.2644238770008087 + -0.7149955034255981, + -0.7025302648544312, + 0.7700265645980835, + 0.9396787285804749, + 1.0826958417892456 ] ], [ [ - -1.0631657838821411, - -0.7474985122680664, - 0.5845747590065002, - 1.3839225769042969, - -1.3397178649902344 + -0.6519155502319336, + 0.2863307297229767, + 0.10145679116249084, + 0.09791278839111328, + -0.8082833886146545 ], [ - 0.6717097163200378, - 0.4279913902282715, - 1.0040385723114014, - 1.708235263824463, - -0.2667044997215271 + 1.441809892654419, + -0.6460452675819397, + 0.04811352491378784, + 1.382570505142212, + -0.6665758490562439 ], [ - 0.927609920501709, - -0.5422874093055725, - -1.4597265720367432, - 0.8100371360778809, - 1.5311497449874878 + 0.7876792550086975, + -0.15957334637641907, + -0.10303135216236115, + 0.27407389879226685, + 1.1576530933380127 ], [ - 0.44362834095954895, - -2.4579336643218994, - 0.6496618390083313, - 0.8869423866271973, - -0.07573819905519485 + -0.21968594193458557, + 0.4215473532676697, + -0.32665783166885376, + 2.3412764072418213, + -0.5351880192756653 ], [ - 0.21659345924854279, - 1.0110455751419067, - -0.7884382605552673, - 1.1371253728866577, - -1.7366209030151367 + 1.0548261404037476, + -0.4031357765197754, + 0.6454427242279053, + -0.6314883828163147, + -1.2809436321258545 ] ], [ [ - 0.9614791870117188, - 0.7572482824325562, - 0.17160733044147491, - 0.36760959029197693, - 0.609169602394104 + 0.009232764132320881, + 1.2330046892166138, + 0.6238497495651245, + 1.5213422775268555, + -0.4976206421852112 ], [ - 0.5307507514953613, - 1.0079243183135986, - 1.6095112562179565, - 1.6016820669174194, - 1.1434932947158813 + 0.7535606026649475, + -0.38888975977897644, + 2.5921998023986816, + 0.08543383330106735, + -2.0308878421783447 ], [ - -0.8632990717887878, - -1.0004771947860718, - 0.19994869828224182, - -0.754463255405426, - -0.3379971385002136 + 0.6461803913116455, + 1.217452883720398, + 0.03121299482882023, + 1.082465648651123, + -1.8998514413833618 ], [ - 0.41659975051879883, - 0.22890278697013855, - 0.2294260412454605, - 0.4791496992111206, - 0.007589681074023247 + -2.7074427604675293, + -0.7867730259895325, + -0.6195639967918396, + 1.8281400203704834, + 0.4877544343471527 ], [ - 0.38356420397758484, - 0.7159355282783508, - 0.3418067395687103, - -0.6778577566146851, - 0.17783714830875397 + 0.1366790533065796, + -0.7571792006492615, + -1.0642281770706177, + 1.9611531496047974, + -0.4390997588634491 ] ], [ [ - 1.4312905073165894, - -3.104058265686035, - 1.1158103942871094, - 0.28317660093307495, - -1.5755101442337036 + 0.8920031785964966, + 1.8720558881759644, + 0.24501417577266693, + 0.7017510533332825, + 0.9099079370498657 ], [ - -1.1856271028518677, - 0.3281179666519165, - -0.03522142022848129, - 1.5343668460845947, - 1.1684390306472778 + -0.7323962450027466, + -0.6663155555725098, + -0.3277064561843872, + -1.439155101776123, + -1.2797472476959229 ], [ - -0.5797900557518005, - 0.7235100865364075, - -0.48095330595970154, - 0.13058727979660034, - 0.8354679346084595 + -0.19622953236103058, + 0.19903564453125, + -0.5971476435661316, + -1.0348221063613892, + 0.42101818323135376 ], [ - 1.6123450994491577, - 0.3398834466934204, - -0.18680495023727417, - -0.4996188282966614, - 1.1609336137771606 + -0.548947811126709, + -1.2540193796157837, + -1.2696188688278198, + 0.6492337584495544, + 0.2340298593044281 ], [ - 0.7856671810150146, - 0.8128212690353394, - 0.04477962106466293, - -1.7439521551132202, - -1.7851803302764893 + -0.1553155928850174, + -0.4344737231731415, + -1.0962450504302979, + -1.122981309890747, + -1.865479826927185 ] ] ], [ [ [ - -0.24107103049755096, - 0.42683982849121094, - 0.11223956197500229, - 0.7528783082962036, - -0.8849666118621826 + -2.1207547187805176, + -0.6719433665275574, + -0.7559810280799866, + -1.0449823141098022, + -0.27992430329322815 ], [ - 0.8982152342796326, - -1.6744109392166138, - -0.7241051197052002, - 0.8363932371139526, - 1.5363035202026367 + 1.2101659774780273, + -0.9885204434394836, + 0.350207656621933, + -0.2644238770008087, + -1.0631657838821411 ], [ - -0.7425072193145752, - 0.8354768753051758, - -1.2516489028930664, - 0.26434803009033203, - 1.2949540615081787 + -0.7474985122680664, + 0.3266002833843231, + -0.49929699301719666, + -1.4715039730072021, + 0.5023646950721741 ], [ - 1.175123691558838, - -0.7680397629737854, - 0.178359717130661, - -1.5190868377685547, - -0.20686893165111542 + 0.4279913902282715, + 1.0040385723114014, + 1.708235263824463, + -0.2667044997215271, + -0.5910199284553528 ], [ - 1.5211719274520874, - -1.2341058254241943, - -0.7871248126029968, - -1.4083248376846313, - -1.2565326690673828 + 2.3618080615997314, + 1.2076122760772705, + -0.5487976670265198, + 1.5311497449874878, + 0.44362834095954895 ] ], [ [ - -1.2300301790237427, - -0.29269593954086304, - 0.21912771463394165, - -0.45708730816841125, - -0.651996910572052 + -2.4579336643218994, + 0.6496618390083313, + 0.02449978142976761, + 0.25982725620269775, + 0.7348682284355164 ], [ - -0.32107922434806824, - -0.3210636079311371, - 2.49674916267395, - 1.3230384588241577, - -0.061925552785396576 + -0.006029692944139242, + -0.7884382605552673, + 1.1371253728866577, + -1.7366209030151367, + 0.9614791870117188 ], [ - 0.9091914892196655, - -0.6015433669090271, - 0.8525826930999756, - -0.6866192817687988, - -0.21939978003501892 + -0.48808231949806213, + -0.6568363904953003, + -0.4720822274684906, + 0.35971710085868835, + 0.5307507514953613 ], [ - 0.21570608019828796, - 2.041553020477295, - -0.4606938660144806, - 1.8315014839172363, - -0.7265217900276184 + 1.0079243183135986, + 1.6095112562179565, + 1.6016820669174194, + 0.020138248801231384, + 0.573236346244812 ], [ - -0.44100794196128845, - -1.1563644409179688, - -0.845207929611206, - 2.3356547355651855, - 0.0955897644162178 + 0.37203314900398254, + 0.22609540820121765, + -0.754463255405426, + -0.3379971385002136, + 0.41659975051879883 ] ], [ [ - 1.1224497556686401, - -1.0052590370178223, - 1.2696419954299927, - 1.212203025817871, - -0.3618496060371399 + 0.22890278697013855, + 0.1943359375, + 1.0423648357391357, + -1.1257092952728271, + -0.04083564877510071 ], [ - 0.5468137264251709, - 0.9894823431968689, - 0.7208108901977539, - -0.4930783212184906, - -0.6638585925102234 + 0.7159355282783508, + 0.3418067395687103, + -0.6778577566146851, + 0.17783714830875397, + -0.16209769248962402 ], [ - -2.0399112701416016, - -0.6206883192062378, - -0.9584940075874329, - 0.7993512749671936, - -0.23935280740261078 + -0.026765741407871246, + -0.33800795674324036, + 0.6160297393798828, + -1.5755101442337036, + -1.1856271028518677 ], [ - -0.07818234711885452, - 0.6661496162414551, - 1.0709624290466309, - 1.3384746313095093, - 0.27829068899154663 + 0.3281179666519165, + -0.03522142022848129, + 0.18906556069850922, + 1.0375696420669556, + 0.7793638706207275 ], [ - -1.328766107559204, - 0.09645214676856995, - -1.5012465715408325, - -1.362809658050537, - 1.5265393257141113 + -0.6498270630836487, + -0.48095330595970154, + 0.13058727979660034, + 0.8354679346084595, + 1.6123450994491577 ] ], [ [ - -0.5563327670097351, - 2.0752601623535156, - -0.8403553366661072, - 0.9517558813095093, - 1.3194047212600708 + -0.4939593970775604, + 0.30456098914146423, + 2.1306238174438477, + 0.026654772460460663, + 0.7856671810150146 ], [ - -0.8734123110771179, - 0.6210753917694092, - 2.9574992656707764, - 0.13751773536205292, - -0.15331187844276428 + 0.8128212690353394, + 0.04477962106466293, + -1.7439521551132202, + -1.3104760646820068, + -1.4218922853469849 ], [ - 1.2169883251190186, - 1.7785981893539429, - -1.6149650812149048, - -0.5684998035430908, - 2.5527584552764893 + -0.3201002776622772, + 0.011662798002362251, + 0.7528783082962036, + -0.8849666118621826, + 0.8982152342796326 ], [ - -0.04084712266921997, - 0.3193606436252594, - -0.6905565857887268, - 0.3500501811504364, - -0.32124459743499756 + -1.6744109392166138, + -1.1447242498397827, + 0.22346419095993042, + -0.9369489550590515, + -0.17544429004192352 ], [ - -0.7468457221984863, - 1.2974729537963867, - -0.8983440399169922, - -0.38374435901641846, - 0.6814237833023071 + 0.8354768753051758, + -1.2516489028930664, + 0.26434803009033203, + 1.2949540615081787, + -0.5443984270095825 ] ], [ [ - 2.0168917179107666, - 0.481290727853775, - 0.313506156206131, - 0.41611549258232117, - 1.0470067262649536 + 2.050001859664917, + 0.06459449976682663, + 1.448185920715332, + -0.20686893165111542, + 1.5211719274520874 ], [ - -1.400732398033142, - -0.47914406657218933, - 2.1447153091430664, - -0.34384623169898987, - 0.41149622201919556 + -1.2341058254241943, + -0.7871248126029968, + -0.7268313765525818, + -0.26047298312187195, + 2.041553020477295 ], [ - 0.41322529315948486, - -2.1648738384246826, - 0.9794597625732422, - 0.38047143816947937, - -1.9277540445327759 + -0.4606938660144806, + -0.6203854084014893, + 1.3424702882766724, + -1.7992236614227295, + -1.2398992776870728 ], [ - 0.9197121858596802, - -1.6067678928375244, - -1.425918698310852, - 0.783023476600647, - 0.0861901044845581 + -1.1074808835983276, + -0.6043308973312378, + 0.0955897644162178, + 1.1224497556686401, + -0.06249626725912094 ], [ - -0.37659966945648193, - 0.9756653904914856, - -0.8411983847618103, - -0.9621247053146362, - -0.5808306932449341 + -0.4906177818775177, + -1.3847423791885376, + 0.8051268458366394, + 1.1163915395736694, + 0.4140532910823822 ] ] ] @@ -17764,44 +18709,44 @@ export const testData = { [ [ [ - -0.11476090550422668, - -0.24131369590759277 + -0.1400585174560547, + -0.1189696192741394 ], [ - -0.10875487327575684, - 0.07968631386756897 + -0.1396593451499939, + 0.06799721717834473 ] ], [ [ - 0.20207053422927856, - -0.2464660108089447 + 0.11712342500686646, + 0.16814139485359192 ], [ - -0.0899374783039093, - 0.15728631615638733 + -0.14146676659584045, + -0.05842772126197815 ] ] ], [ [ [ - -0.1351938247680664, - 0.16879567503929138 + 0.23335561156272888, + -0.12842318415641785 ], [ - 0.010089278221130371, - -0.2350514531135559 + -0.0903659462928772, + -0.048071324825286865 ] ], [ [ - 0.042271971702575684, - -0.149849534034729 + -0.22137033939361572, + -0.1847814917564392 ], [ - 0.04858878254890442, - -0.22400259971618652 + 0.22272253036499023, + 0.046148449182510376 ] ] ] @@ -17810,44 +18755,44 @@ export const testData = { [ [ [ - 0.23491546511650085, - -0.10666635632514954 + 0.046710461378097534, + 0.09910747408866882 ], [ - 0.15988940000534058, - -0.15729418396949768 + 0.15203699469566345, + 0.1679282784461975 ] ], [ [ - -0.20952555537223816, - 0.09835821390151978 + 0.17905914783477783, + 0.10090303421020508 ], [ - 0.15029987692832947, - -0.002248615026473999 + 0.18846681714057922, + 0.16334408521652222 ] ] ], [ [ [ - -0.21142640709877014, - -0.06857553124427795 + -0.04180261492729187, + 0.02251899242401123 ], [ - -0.17324388027191162, - 0.07081684470176697 + -0.13095378875732422, + -0.18811622262001038 ] ], [ [ - 0.04048082232475281, - 0.1737305223941803 + 0.23712044954299927, + -0.18616604804992676 ], [ - 0.24955525994300842, - -0.11556816101074219 + -0.15629222989082336, + -0.2414878010749817 ] ] ] @@ -17858,106 +18803,106 @@ export const testData = { [ [ [ - -0.4757484495639801, - -0.8812041282653809, - 0.3463735580444336 + -0.5016605257987976, + 0.0729646384716034, + -0.601827085018158 ], [ - -0.7419395446777344, - 0.4907858073711395, - 0.01124744862318039 + 0.7186769247055054, + -0.40328311920166016, + 0.09108078479766846 ], [ - 0.5282792448997498, - 0.37058907747268677, - -0.13969454169273376 + -0.49653488397598267, + 0.4543629586696625, + 0.03304469585418701 ] ], [ [ - 0.9295258522033691, - 0.3352668285369873, - -1.4362306594848633 + -0.6014649868011475, + 0.01556580513715744, + -0.08095501363277435 ], [ - 0.40583908557891846, - 0.1808263659477234, - 0.11902815103530884 + 0.5609210729598999, + 0.2705661654472351, + 0.8075739145278931 ], [ - 0.17801764607429504, - -0.36842218041419983, - -0.5066997408866882 + 0.33128559589385986, + 0.4595896899700165, + -0.4482420086860657 ] ], [ [ - -0.13931676745414734, - -0.9522701501846313, - 1.475050449371338 + -0.6991593837738037, + 0.45764970779418945, + 0.3065469264984131 ], [ - -0.9424186944961548, - -1.2914557456970215, - -0.5469567775726318 + 0.19239531457424164, + -0.004418909549713135, + -0.39568382501602173 ], [ - 0.5914638042449951, - 0.26857104897499084, - -0.7077885270118713 + -0.489966481924057, + 0.31915783882141113, + 0.3014536499977112 ] ] ], [ [ [ - -0.15289494395256042, - 0.13514970242977142, - 0.2045574188232422 + -0.026227392256259918, + 1.1108590364456177, + 0.4146382510662079 ], [ - -0.8474478125572205, - 0.5180610418319702, - 0.26316726207733154 + -0.1955452859401703, + 0.4704682230949402, + -0.646715521812439 ], [ - -0.2188991904258728, - 0.6530547142028809, - -0.0868012011051178 + 0.5727429389953613, + -0.8670409917831421, + 0.29973188042640686 ] ], [ [ - -0.24735553562641144, - 0.16227149963378906, - -0.24669215083122253 + -0.39649078249931335, + 0.8576757907867432, + -0.5326414108276367 ], [ - 0.4316696226596832, - -0.3470993936061859, - -1.2586170434951782 + -0.09169283509254456, + 0.03638267517089844, + -0.2939724922180176 ], [ - -0.2081446349620819, - 0.44266369938850403, - 0.47282782196998596 + -0.3522647023200989, + 0.5533568859100342, + -0.08248010277748108 ] ], [ [ - -0.1232089102268219, - 0.05044287443161011, - -0.08964276313781738 + -0.0021897554397583008, + 1.2117888927459717, + 0.4429609775543213 ], [ - 1.141706943511963, - -1.2464135885238647, - -0.00848311185836792 + -0.62223219871521, + -0.34632712602615356, + -1.2911615371704102 ], [ - 1.535451889038086, - 0.05266711115837097, - -0.016254477202892303 + -0.40977323055267334, + -0.46257489919662476, + -0.6323492527008057 ] ] ] @@ -17968,374 +18913,374 @@ export const testData = { [ [ [ - 0.12015455961227417, - 0.12015455961227417, - -0.22782549262046814, - -0.3479800522327423, - -0.3479800522327423 + -0.09334805607795715, + -0.09334805607795715, + -0.11321020126342773, + -0.01986214518547058, + -0.01986214518547058 ], [ - 0.12015455961227417, - 0.12015455961227417, - -0.22782549262046814, - -0.3479800522327423, - -0.3479800522327423 + -0.09334805607795715, + -0.09334805607795715, + -0.11321020126342773, + -0.01986214518547058, + -0.01986214518547058 ], [ - 0.1712890863418579, - 0.1712890863418579, - -0.2542988359928131, - -0.425587922334671, - -0.425587922334671 + -0.0809704065322876, + -0.0809704065322876, + 0.13509294390678406, + 0.21606335043907166, + 0.21606335043907166 ], [ - 0.05113452672958374, - 0.05113452672958374, - -0.02647334337234497, - -0.07760787010192871, - -0.07760787010192871 + 0.012377649545669556, + 0.012377649545669556, + 0.2483031451702118, + 0.23592549562454224, + 0.23592549562454224 ], [ - 0.05113452672958374, - 0.05113452672958374, - -0.02647334337234497, - -0.07760787010192871, - -0.07760787010192871 + 0.012377649545669556, + 0.012377649545669556, + 0.2483031451702118, + 0.23592549562454224, + 0.23592549562454224 ] ], [ [ - 0.12015455961227417, - 0.12015455961227417, - -0.22782549262046814, - -0.3479800522327423, - -0.3479800522327423 + -0.09334805607795715, + -0.09334805607795715, + -0.11321020126342773, + -0.01986214518547058, + -0.01986214518547058 ], [ - 0.12015455961227417, - 0.12015455961227417, - -0.22782549262046814, - -0.3479800522327423, - -0.3479800522327423 + -0.09334805607795715, + -0.09334805607795715, + -0.11321020126342773, + -0.01986214518547058, + -0.01986214518547058 ], [ - 0.1712890863418579, - 0.1712890863418579, - -0.2542988359928131, - -0.425587922334671, - -0.425587922334671 + -0.0809704065322876, + -0.0809704065322876, + 0.13509294390678406, + 0.21606335043907166, + 0.21606335043907166 ], [ - 0.05113452672958374, - 0.05113452672958374, - -0.02647334337234497, - -0.07760787010192871, - -0.07760787010192871 + 0.012377649545669556, + 0.012377649545669556, + 0.2483031451702118, + 0.23592549562454224, + 0.23592549562454224 ], [ - 0.05113452672958374, - 0.05113452672958374, - -0.02647334337234497, - -0.07760787010192871, - -0.07760787010192871 + 0.012377649545669556, + 0.012377649545669556, + 0.2483031451702118, + 0.23592549562454224, + 0.23592549562454224 ] ], [ [ - 0.11269953846931458, - 0.11269953846931458, - -0.38338831067085266, - -0.49608784914016724, - -0.49608784914016724 + 0.20283451676368713, + 0.20283451676368713, + 0.45201680064201355, + 0.24918228387832642, + 0.24918228387832642 ], [ - 0.11269953846931458, - 0.11269953846931458, - -0.38338831067085266, - -0.49608784914016724, - -0.49608784914016724 + 0.20283451676368713, + 0.20283451676368713, + 0.45201680064201355, + 0.24918228387832642, + 0.24918228387832642 ], [ - 0.22419646382331848, - 0.22419646382331848, - -0.19446155428886414, - -0.4186580181121826, - -0.4186580181121826 + 0.26221221685409546, + 0.26221221685409546, + 0.8522363901138306, + 0.5900241136550903, + 0.5900241136550903 ], [ - 0.1114969253540039, - 0.1114969253540039, - 0.18892675638198853, - 0.07742983102798462, - 0.07742983102798462 + 0.059377700090408325, + 0.059377700090408325, + 0.40021955966949463, + 0.3408418595790863, + 0.3408418595790863 ], [ - 0.1114969253540039, - 0.1114969253540039, - 0.18892675638198853, - 0.07742983102798462, - 0.07742983102798462 + 0.059377700090408325, + 0.059377700090408325, + 0.40021955966949463, + 0.3408418595790863, + 0.3408418595790863 ] ], [ [ - -0.007455021142959595, - -0.007455021142959595, - -0.15556281805038452, - -0.14810779690742493, - -0.14810779690742493 + 0.2961825728416443, + 0.2961825728416443, + 0.5652270317077637, + 0.269044429063797, + 0.269044429063797 ], [ - -0.007455021142959595, - -0.007455021142959595, - -0.15556281805038452, - -0.14810779690742493, - -0.14810779690742493 + 0.2961825728416443, + 0.2961825728416443, + 0.5652270317077637, + 0.269044429063797, + 0.269044429063797 ], [ - 0.05290737748146057, - 0.05290737748146057, - 0.059837281703948975, - 0.006929904222488403, - 0.006929904222488403 + 0.34318262338638306, + 0.34318262338638306, + 0.7171434164047241, + 0.37396079301834106, + 0.37396079301834106 ], [ - 0.060362398624420166, - 0.060362398624420166, - 0.2154000997543335, - 0.15503770112991333, - 0.15503770112991333 + 0.04700005054473877, + 0.04700005054473877, + 0.15191641449928284, + 0.10491636395454407, + 0.10491636395454407 ], [ - 0.060362398624420166, - 0.060362398624420166, - 0.2154000997543335, - 0.15503770112991333, - 0.15503770112991333 + 0.04700005054473877, + 0.04700005054473877, + 0.15191641449928284, + 0.10491636395454407, + 0.10491636395454407 ] ], [ [ - -0.007455021142959595, - -0.007455021142959595, - -0.15556281805038452, - -0.14810779690742493, - -0.14810779690742493 + 0.2961825728416443, + 0.2961825728416443, + 0.5652270317077637, + 0.269044429063797, + 0.269044429063797 ], [ - -0.007455021142959595, - -0.007455021142959595, - -0.15556281805038452, - -0.14810779690742493, - -0.14810779690742493 + 0.2961825728416443, + 0.2961825728416443, + 0.5652270317077637, + 0.269044429063797, + 0.269044429063797 ], [ - 0.05290737748146057, - 0.05290737748146057, - 0.059837281703948975, - 0.006929904222488403, - 0.006929904222488403 + 0.34318262338638306, + 0.34318262338638306, + 0.7171434164047241, + 0.37396079301834106, + 0.37396079301834106 ], [ - 0.060362398624420166, - 0.060362398624420166, - 0.2154000997543335, - 0.15503770112991333, - 0.15503770112991333 + 0.04700005054473877, + 0.04700005054473877, + 0.15191641449928284, + 0.10491636395454407, + 0.10491636395454407 ], [ - 0.060362398624420166, - 0.060362398624420166, - 0.2154000997543335, - 0.15503770112991333, - 0.15503770112991333 + 0.04700005054473877, + 0.04700005054473877, + 0.15191641449928284, + 0.10491636395454407, + 0.10491636395454407 ] ] ], [ [ [ - -0.34662023186683655, - -0.34662023186683655, - -0.24640008807182312, - 0.10022014379501343, - 0.10022014379501343 + 0.191552996635437, + 0.191552996635437, + 0.0856488049030304, + -0.10590419173240662, + -0.10590419173240662 ], [ - -0.34662023186683655, - -0.34662023186683655, - -0.24640008807182312, - 0.10022014379501343, - 0.10022014379501343 + 0.191552996635437, + 0.191552996635437, + 0.0856488049030304, + -0.10590419173240662, + -0.10590419173240662 ], [ - -0.5097748041152954, - -0.5097748041152954, - -0.5737892985343933, - -0.06401446461677551, - -0.06401446461677551 + -0.029766738414764404, + -0.029766738414764404, + -0.37185847759246826, + -0.34209173917770386, + -0.34209173917770386 ], [ - -0.16315460205078125, - -0.16315460205078125, - -0.3273892104625702, - -0.16423460841178894, - -0.16423460841178894 + -0.22131973505020142, + -0.22131973505020142, + -0.45750728249549866, + -0.23618754744529724, + -0.23618754744529724 ], [ - -0.16315460205078125, - -0.16315460205078125, - -0.3273892104625702, - -0.16423460841178894, - -0.16423460841178894 + -0.22131973505020142, + -0.22131973505020142, + -0.45750728249549866, + -0.23618754744529724, + -0.23618754744529724 ] ], [ [ - -0.34662023186683655, - -0.34662023186683655, - -0.24640008807182312, - 0.10022014379501343, - 0.10022014379501343 + 0.191552996635437, + 0.191552996635437, + 0.0856488049030304, + -0.10590419173240662, + -0.10590419173240662 ], [ - -0.34662023186683655, - -0.34662023186683655, - -0.24640008807182312, - 0.10022014379501343, - 0.10022014379501343 + 0.191552996635437, + 0.191552996635437, + 0.0856488049030304, + -0.10590419173240662, + -0.10590419173240662 ], [ - -0.5097748041152954, - -0.5097748041152954, - -0.5737892985343933, - -0.06401446461677551, - -0.06401446461677551 + -0.029766738414764404, + -0.029766738414764404, + -0.37185847759246826, + -0.34209173917770386, + -0.34209173917770386 ], [ - -0.16315460205078125, - -0.16315460205078125, - -0.3273892104625702, - -0.16423460841178894, - -0.16423460841178894 + -0.22131973505020142, + -0.22131973505020142, + -0.45750728249549866, + -0.23618754744529724, + -0.23618754744529724 ], [ - -0.16315460205078125, - -0.16315460205078125, - -0.3273892104625702, - -0.16423460841178894, - -0.16423460841178894 + -0.22131973505020142, + -0.22131973505020142, + -0.45750728249549866, + -0.23618754744529724, + -0.23618754744529724 ] ], [ [ - -0.26386743783950806, - -0.26386743783950806, - -0.13976630568504333, - 0.12410113215446472, - 0.12410113215446472 + 0.20730310678482056, + 0.20730310678482056, + -0.269548624753952, + -0.4768517315387726, + -0.4768517315387726 ], [ - -0.26386743783950806, - -0.26386743783950806, - -0.13976630568504333, - 0.12410113215446472, - 0.12410113215446472 + 0.20730310678482056, + 0.20730310678482056, + -0.269548624753952, + -0.4768517315387726, + -0.4768517315387726 ], [ - -0.12887796759605408, - -0.12887796759605408, - -0.5085822343826294, - -0.37970423698425293, - -0.37970423698425293 + 0.05241367220878601, + 0.05241367220878601, + -0.8559648990631104, + -0.9083786010742188, + -0.9083786010742188 ], [ - 0.1349894404411316, - 0.1349894404411316, - -0.36881592869758606, - -0.50380539894104, - -0.50380539894104 + -0.15488943457603455, + -0.15488943457603455, + -0.5864163637161255, + -0.43152689933776855, + -0.43152689933776855 ], [ - 0.1349894404411316, - 0.1349894404411316, - -0.36881592869758606, - -0.50380539894104, - -0.50380539894104 + -0.15488943457603455, + -0.15488943457603455, + -0.5864163637161255, + -0.43152689933776855, + -0.43152689933776855 ] ], [ [ - 0.08275279402732849, - 0.08275279402732849, - 0.10663378238677979, - 0.023880988359451294, - 0.023880988359451294 + 0.015750110149383545, + 0.015750110149383545, + -0.3551974296569824, + -0.37094753980636597, + -0.37094753980636597 ], [ - 0.08275279402732849, - 0.08275279402732849, - 0.10663378238677979, - 0.023880988359451294, - 0.023880988359451294 + 0.015750110149383545, + 0.015750110149383545, + -0.3551974296569824, + -0.37094753980636597, + -0.37094753980636597 ], [ - 0.38089683651924133, - 0.38089683651924133, - 0.06520706415176392, - -0.3156897723674774, - -0.3156897723674774 + 0.08218041062355042, + 0.08218041062355042, + -0.48410648107528687, + -0.5662869215011597, + -0.5662869215011597 ], [ - 0.29814404249191284, - 0.29814404249191284, - -0.04142671823501587, - -0.3395707607269287, - -0.3395707607269287 + 0.06643030047416687, + 0.06643030047416687, + -0.12890905141830444, + -0.1953393518924713, + -0.1953393518924713 ], [ - 0.29814404249191284, - 0.29814404249191284, - -0.04142671823501587, - -0.3395707607269287, - -0.3395707607269287 + 0.06643030047416687, + 0.06643030047416687, + -0.12890905141830444, + -0.1953393518924713, + -0.1953393518924713 ] ], [ [ - 0.08275279402732849, - 0.08275279402732849, - 0.10663378238677979, - 0.023880988359451294, - 0.023880988359451294 + 0.015750110149383545, + 0.015750110149383545, + -0.3551974296569824, + -0.37094753980636597, + -0.37094753980636597 ], [ - 0.08275279402732849, - 0.08275279402732849, - 0.10663378238677979, - 0.023880988359451294, - 0.023880988359451294 + 0.015750110149383545, + 0.015750110149383545, + -0.3551974296569824, + -0.37094753980636597, + -0.37094753980636597 ], [ - 0.38089683651924133, - 0.38089683651924133, - 0.06520706415176392, - -0.3156897723674774, - -0.3156897723674774 + 0.08218041062355042, + 0.08218041062355042, + -0.48410648107528687, + -0.5662869215011597, + -0.5662869215011597 ], [ - 0.29814404249191284, - 0.29814404249191284, - -0.04142671823501587, - -0.3395707607269287, - -0.3395707607269287 + 0.06643030047416687, + 0.06643030047416687, + -0.12890905141830444, + -0.1953393518924713, + -0.1953393518924713 ], [ - 0.29814404249191284, - 0.29814404249191284, - -0.04142671823501587, - -0.3395707607269287, - -0.3395707607269287 + 0.06643030047416687, + 0.06643030047416687, + -0.12890905141830444, + -0.1953393518924713, + -0.1953393518924713 ] ] ] @@ -18346,44 +19291,44 @@ export const testData = { [ [ [ - -1.6769251823425293, - 4.594216823577881 + -1.343505859375, + -3.040519952774048 ], [ - -5.610960960388184, - -3.7611963748931885 + -3.0536627769470215, + 4.573274612426758 ] ], [ [ - 1.391018271446228, - 11.542533874511719 + 8.510942459106445, + 0.5911479592323303 ], [ - 1.7240196466445923, - -1.9049088954925537 + -7.559212684631348, + -2.7728934288024902 ] ] ], [ [ [ - -0.6248869299888611, - 6.0362396240234375 + -4.858392715454102, + -5.658546447753906 ], [ - -5.252803325653076, - -1.563323974609375 + 7.419499397277832, + 5.1849284172058105 ] ], [ [ - 7.093540191650391, - 9.448348045349121 + 4.672170639038086, + -1.5785690546035767 ], [ - -7.200158596038818, - -3.4500885009765625 + -4.995093822479248, + 5.125855922698975 ] ] ] @@ -18392,44 +19337,44 @@ export const testData = { [ [ [ - -1.6769251823425293, - 4.594216823577881 + -1.343505859375, + -3.040519952774048 ], [ - -5.610960960388184, - -3.7611963748931885 + -3.0536627769470215, + 4.573274612426758 ] ], [ [ - 1.391018271446228, - 11.542533874511719 + 8.510942459106445, + 0.5911479592323303 ], [ - 1.7240196466445923, - -1.9049088954925537 + -7.559212684631348, + -2.7728934288024902 ] ] ], [ [ [ - -0.6248869299888611, - 6.0362396240234375 + -4.858392715454102, + -5.658546447753906 ], [ - -5.252803325653076, - -1.563323974609375 + 7.419499397277832, + 5.1849284172058105 ] ], [ [ - 7.093540191650391, - 9.448348045349121 + 4.672170639038086, + -1.5785690546035767 ], [ - -7.200158596038818, - -3.4500885009765625 + -4.995093822479248, + 5.125855922698975 ] ] ] @@ -18453,6 +19398,144 @@ export const testData = { [ [ [ + [ + -1.3928337097167969, + -0.4097520112991333, + 0.703314483165741, + 0.9964529871940613 + ], + [ + 0.7671750783920288, + -0.737683117389679, + 0.8915963768959045, + 0.4381142258644104 + ], + [ + -1.9372137784957886, + -1.2051048278808594, + -0.6557903289794922, + 0.08431144803762436 + ], + [ + -0.653298556804657, + 0.5411866903305054, + 0.06401552259922028, + -0.8354001641273499 + ] + ], + [ + [ + 0.2550857663154602, + -0.4017896056175232, + -1.2750170230865479, + -0.7951065897941589 + ], + [ + 1.8864071369171143, + 0.1899632215499878, + 1.6621514558792114, + 1.6152663230895996 + ], + [ + -0.6503500938415527, + 0.6934462189674377, + -0.7531406283378601, + -1.054457426071167 + ], + [ + -0.34221795201301575, + 0.5399923920631409, + 0.43685466051101685, + 0.5002582669258118 + ] + ], + [ + [ + 0.19359846413135529, + -0.40304437279701233, + 1.0216805934906006, + -0.5625430345535278 + ], + [ + -0.5148502588272095, + 0.008906678296625614, + 1.1446433067321777, + -0.07024435698986053 + ], + [ + 1.2778736352920532, + -0.30529654026031494, + 0.05272906273603439, + -0.5502418875694275 + ], + [ + 1.2332603931427002, + 0.5611109733581543, + -1.4120334386825562, + 0.1129438579082489 + ] + ], + [ + [ + -0.8788067102432251, + -0.2609003186225891, + 0.12875856459140778, + -0.5114356875419617 + ], + [ + 2.786404848098755, + 0.48124057054519653, + 0.06012781709432602, + -0.3161824643611908 + ], + [ + -1.073968529701233, + -0.8155962824821472, + -1.6220977306365967, + -2.4403839111328125 + ], + [ + -0.23850013315677643, + 0.45670533180236816, + 0.048488546162843704, + 0.4753035008907318 + ] + ] + ], + [ + [ + [ + -1.501094937324524, + -0.11335238814353943, + -0.47884872555732727, + 1.1839776039123535 + ], + [ + -1.8148568868637085, + -2.413346529006958, + -2.5672242641448975, + -1.2153066396713257 + ], + [ + 1.458335041999817, + 0.4836253225803375, + -1.981804370880127, + -0.590317964553833 + ], + [ + -0.14224699139595032, + 2.219874620437622, + 1.4296598434448242, + 2.5194058418273926 + ] + ], + [ + [ + -1.5602378845214844, + -0.055706802755594254, + -0.3643185794353485, + -0.9861663579940796 + ], [ -0.6010674834251404, -0.1635483205318451, @@ -18460,25 +19543,25 @@ export const testData = { -0.3672035038471222 ], [ - -1.2631161212921143, - 0.8303362727165222, - 0.7788206934928894, - -0.08426624536514282 + -0.5103265047073364, + 0.048219867050647736, + 2.249467372894287, + 0.584500253200531 ], [ 0.27795618772506714, -0.8656967282295227, 0.370025634765625, 0.027097342535853386 - ], - [ - 0.05418866500258446, - 0.5362043380737305, - -0.19528378546237946, - 1.0318245887756348 ] ], [ + [ + 0.830817461013794, + -0.4116531312465668, + 2.1705524921417236, + 0.2617567777633667 + ], [ -1.1645411252975464, 1.4430084228515625, @@ -18486,25 +19569,25 @@ export const testData = { -0.6022811532020569 ], [ - 0.0974288359284401, - -1.0450509786605835, - 0.3688916862010956, - 0.5232675075531006 + 0.8178791999816895, + 0.14809109270572662, + 1.33113694190979, + 0.7360257506370544 ], [ -1.7843447923660278, -1.4876283407211304, 1.1491626501083374, 1.937359094619751 - ], - [ - 0.5046956539154053, - 0.2925446927547455, - 0.2171924114227295, - 0.4019394814968109 ] ], [ + [ + 0.35567042231559753, + 0.7510744333267212, + 0.22924625873565674, + -0.4690351188182831 + ], [ -0.9391453862190247, 1.2694876194000244, @@ -18512,25 +19595,27 @@ export const testData = { 0.6024797558784485 ], [ - 1.209511637687683, - -1.2663702964782715, - 1.7024855613708496, - -0.9683796763420105 + -0.6078834533691406, + -0.8096639513969421, + -0.3527470827102661, + -0.013718712143599987 ], [ 0.33257901668548584, -2.500622034072876, -1.3190810680389404, -0.5720829367637634 - ], - [ - -1.4600306749343872, - 1.5690288543701172, - -0.88787841796875, - -0.6835475564002991 ] - ], + ] + ], + [ [ + [ + 1.5485637187957764, + -0.08855976164340973, + -0.7727481722831726, + -1.0038365125656128 + ], [ 0.12993256747722626, 2.3204126358032227, @@ -18538,27 +19623,25 @@ export const testData = { -1.3236184120178223 ], [ - -0.34333336353302, - 0.7385661005973816, - -0.8320447206497192, - 0.9133552312850952 + -1.239241361618042, + 0.9374039173126221, + 2.1315672397613525, + 0.9022464156150818 ], [ 3.494849681854248, -2.554791212081909, -0.6495603322982788, 1.3511242866516113 - ], - [ - 2.08429217338562, - 0.2650778293609619, - -0.19079573452472687, - -0.364820271730423 ] - ] - ], - [ + ], [ + [ + -0.8003812432289124, + 0.22974559664726257, + 0.8345783352851868, + 1.4143918752670288 + ], [ 0.5880279541015625, -0.649803102016449, @@ -18566,25 +19649,25 @@ export const testData = { 0.1007673516869545 ], [ - 0.4674225151538849, - 0.5173186659812927, - -1.4732903242111206, - -0.10355143249034882 + 0.07260560989379883, + 0.24500113725662231, + -0.9157967567443848, + 1.9000908136367798 ], [ 1.7842795848846436, -2.0273475646972656, -1.8968849182128906, 1.5710992813110352 - ], - [ - -1.054054856300354, - 0.10566096007823944, - -1.3687875270843506, - -0.5567623376846313 ] ], [ + [ + -1.4176050424575806, + -0.0560019314289093, + 1.3802173137664795, + -1.265958309173584 + ], [ -1.1206839084625244, -0.48504650592803955, @@ -18592,25 +19675,25 @@ export const testData = { -0.3676562011241913 ], [ - -1.3724169731140137, - -0.13087055087089539, - -0.4163765013217926, - -0.9129456877708435 + -1.1750401258468628, + 0.24909113347530365, + -0.16031959652900696, + 0.9739231467247009 ], [ 0.7357478141784668, -0.5081192851066589, -0.29886385798454285, 2.1124520301818848 - ], - [ - -0.021738804876804352, - 0.8089306950569153, - 2.7958858013153076, - 0.41675102710723877 ] ], [ + [ + 0.9135115742683411, + -0.7519399523735046, + -0.7679979801177979, + -0.7598804831504822 + ], [ 1.1353410482406616, 1.1538640260696411, @@ -18618,25 +19701,27 @@ export const testData = { -1.7530438899993896 ], [ - -0.17104516923427582, - -0.2808971405029297, - -0.12884187698364258, - 0.9388713836669922 + -0.7495994567871094, + 0.2814400792121887, + 0.22202011942863464, + -0.7438408732414246 ], [ 0.30860263109207153, -1.2615443468093872, 0.2716897130012512, -0.2226782888174057 - ], - [ - -2.0968735218048096, - -1.0447371006011963, - 1.0945836305618286, - 1.0349615812301636 ] - ], + ] + ], + [ [ + [ + -1.5529402494430542, + 0.13943159580230713, + 0.1643831729888916, + 0.29162532091140747 + ], [ 0.16704672574996948, 0.19502827525138855, @@ -18644,27 +19729,25 @@ export const testData = { -0.22532868385314941 ], [ - -0.823324978351593, - 0.5321081876754761, - 1.690338134765625, - 1.8711999654769897 + 0.5098334550857544, + 1.5633010864257812, + -0.7737565040588379, + -0.44698092341423035 ], [ -0.08777227252721786, 0.36624786257743835, 0.8002102971076965, -0.43177542090415955 - ], - [ - 0.7183605432510376, - -0.5048002004623413, - 0.4487703740596771, - -0.43473342061042786 ] - ] - ], - [ + ], [ + [ + 0.3932536244392395, + 0.45422324538230896, + 0.21926040947437286, + 0.45671015977859497 + ], [ -0.5347977876663208, -0.41083934903144836, @@ -18672,25 +19755,25 @@ export const testData = { 0.7992386817932129 ], [ - 0.08938626199960709, - 1.624720811843872, - 1.8527616262435913, - -1.680544137954712 + 0.9056950807571411, + -2.0051839351654053, + -0.19047869741916656, + -2.534075975418091 ], [ -0.21575696766376495, 0.19951215386390686, 1.077291488647461, -0.11855955421924591 - ], - [ - 0.6329800486564636, - 0.6623784899711609, - -0.9556253552436829, - 0.43514177203178406 ] ], [ + [ + 0.2259528934955597, + 0.27357611060142517, + -2.2692863941192627, + 0.5441847443580627 + ], [ -1.8895906209945679, 0.870172917842865, @@ -18698,25 +19781,25 @@ export const testData = { 0.4322058856487274 ], [ - -1.7878626585006714, - 1.9938184022903442, - -0.08736804872751236, - -1.1191902160644531 + -0.682377278804779, + -0.22877585887908936, + 0.0997343435883522, + -0.9669718146324158 ], [ -0.21153147518634796, 0.23635204136371613, -2.0590813159942627, 0.36353930830955505 - ], - [ - -0.17709049582481384, - 0.6511173844337463, - 1.162279486656189, - 1.5198776721954346 ] ], [ + [ + 1.0479241609573364, + 0.32106152176856995, + 0.18448585271835327, + -0.7088321447372437 + ], [ 0.8131258487701416, 0.07307689636945724, @@ -18724,163 +19807,191 @@ export const testData = { 0.22815753519535065 ], [ - 0.40518879890441895, - -0.04436149075627327, - -0.46283742785453796, - 0.1497601568698883 + 0.5933053493499756, + 0.0023419519420713186, + 0.7572504878044128, + 0.6018804311752319 ], [ -0.2617298364639282, 0.09828201681375504, 0.5204787254333496, 0.150835320353508 + ] + ] + ] + ] + ], + "weight": [ + [ + [ + [ + [ + -0.07317566871643066, + -0.05697118490934372, + 0.025281300768256187 + ], + [ + 0.09215686470270157, + 0.11558420211076736, + 0.05240511894226074 ], [ - -0.08319627493619919, - 0.018847988918423653, - 0.5120656490325928, - -0.9795308709144592 + -0.09402935951948166, + 0.12580211460590363, + 0.13140276074409485 ] ], [ [ - -0.08465366065502167, - 0.5634167790412903, - -2.517653226852417, - 1.5532352924346924 + -0.04044036939740181, + 0.004691822454333305, + 0.12318181246519089 ], [ - -0.32487261295318604, - 0.9450231790542603, - -1.232080101966858, - 1.510047435760498 + -0.04785345494747162, + 0.06451239436864853, + 0.022634774446487427 ], [ - 0.6712618470191956, - -0.7744964957237244, - -0.12379023432731628, - 0.7035301327705383 + 0.07585608959197998, + 0.04741308465600014, + 0.13501256704330444 + ] + ], + [ + [ + 0.11532974988222122, + -0.0928543284535408, + 0.08189363032579422 ], [ - -0.36376747488975525, - 0.08706109970808029, - -0.27385643124580383, - 0.052069131284952164 + -0.026923909783363342, + -0.07120232284069061, + 0.02282446250319481 + ], + [ + -0.01852257549762726, + -0.08868129551410675, + -0.12011746317148209 ] ] ], [ [ [ - -0.8765193223953247, - 0.9824013710021973, - -0.32311075925827026, - -0.09268321096897125 - ], - [ - -0.7539657950401306, - 0.5708315372467041, - 0.7370786666870117, - -1.690212607383728 + -0.07584045082330704, + 0.014010561630129814, + 0.08293341845273972 ], [ - -0.34074920415878296, - 0.05697745084762573, - 0.0032076085917651653, - 0.9378344416618347 + 0.0801883116364479, + 0.036289919167757034, + 0.12909185886383057 ], [ - -0.9413528442382812, - 0.4082898497581482, - 1.0719655752182007, - 0.17691805958747864 + -0.11655238270759583, + -0.08565417677164078, + 0.058578088879585266 ] ], [ [ - -0.2889143228530884, - -0.5668610334396362, - 0.20414040982723236, - -0.9038130640983582 + -0.12395086884498596, + 0.12834252417087555, + 0.018763039261102676 ], [ - -0.10176023095846176, - 0.9885962009429932, - 0.9275448322296143, - 0.1871725618839264 + -0.05015324801206589, + 0.12142548710107803, + 0.06344791501760483 ], [ - -1.7383617162704468, - -0.7690361142158508, - -1.114380121231079, - 0.6168888807296753 - ], - [ - 0.4690037965774536, - -0.5066404342651367, - -0.6858885884284973, - -1.308877944946289 + 0.11444719135761261, + 0.1025216206908226, + -0.023683840408921242 ] ], [ [ - 1.9061840772628784, - -1.6183137893676758, - 1.6300877332687378, - -0.2200150340795517 + 0.12353374063968658, + 0.017971260473132133, + 0.013177122920751572 + ], + [ + 0.04728586971759796, + -0.10653594881296158, + -0.08136706799268723 ], [ - -0.034228239208459854, - 0.23624566197395325, - -0.6087417602539062, - 0.9832689762115479 + 0.12876833975315094, + -0.0890536978840828, + 0.07353045046329498 + ] + ] + ] + ], + [ + [ + [ + [ + 0.08224423229694366, + -0.11047881841659546, + -0.015596115961670876 ], [ - -0.6000643372535706, - -0.3363756835460663, - 1.7426948547363281, - 2.327395439147949 + -0.0014560514828190207, + 0.10095883160829544, + -0.03723892569541931 ], [ - -0.4416877329349518, - -0.051642946898937225, - -0.4240947961807251, - 1.8199645280838013 + 0.12291000783443451, + -0.1141892746090889, + 0.05685015022754669 ] ], [ [ - -2.704969644546509, - 0.25391218066215515, - 0.8111586570739746, - -0.5477031469345093 + 0.07430146634578705, + -0.049023281782865524, + -0.044752590358257294 ], [ - -0.7678541541099548, - 0.14641381800174713, - 1.7945916652679443, - -0.8427640199661255 + -0.0866771936416626, + 0.03610346093773842, + 0.04560322314500809 ], [ - 0.1157287210226059, - 2.351787567138672, - 0.02904084324836731, - -0.4715009927749634 + -0.04783155769109726, + 0.11004998534917831, + -0.020851340144872665 + ] + ], + [ + [ + -0.02120385132730007, + 0.10628344863653183, + 0.023843467235565186 ], [ - 1.5835394859313965, - 0.5264506936073303, - -1.3288897275924683, - -0.5552407503128052 - ] - ] - ] - ] - ], - "weight": [ - [ + 0.07284656912088394, + 0.08021114766597748, + -0.08907522261142731 + ], + [ + -0.0017236550338566303, + 0.12018252909183502, + -0.08414741605520248 + ] + ] + ], [ [ + [ + 0.01782277598977089, + 0.10108597576618195, + 0.0150253651663661 + ], [ -0.030513359233736992, 0.049209609627723694, @@ -18890,14 +20001,14 @@ export const testData = { 0.11180425435304642, 0.10690176486968994, -0.03810763359069824 - ], + ] + ], + [ [ -0.0492289662361145, -0.026618685573339462, 0.13539858162403107 - ] - ], - [ + ], [ -0.052236780524253845, 0.04074903205037117, @@ -18907,14 +20018,14 @@ export const testData = { 0.04113350436091423, 0.08245334774255753, 0.044047243893146515 - ], + ] + ], + [ [ -0.006466334220021963, 0.009931002743542194, 0.11784464865922928 - ] - ], - [ + ], [ 0.059138908982276917, -0.03144518658518791, @@ -18924,16 +20035,18 @@ export const testData = { 0.09917846322059631, -0.050664398819208145, 0.08484464883804321 - ], - [ - -0.027349485084414482, - 0.0022585864644497633, - -0.10731968283653259 ] ] - ], + ] + ], + [ [ [ + [ + -0.027349485084414482, + 0.0022585864644497633, + -0.10731968283653259 + ], [ -0.051842495799064636, 0.011228075250983238, @@ -18943,14 +20056,14 @@ export const testData = { -0.028004510328173637, 0.0790708139538765, 0.09564515203237534 - ], + ] + ], + [ [ 0.10023753345012665, -0.04150017723441124, 0.010712042450904846 - ] - ], - [ + ], [ -0.1091998890042305, 0.07049248367547989, @@ -18960,14 +20073,14 @@ export const testData = { 0.11390487849712372, -0.021170107647776604, 0.13014858961105347 - ], + ] + ], + [ [ 0.06742006540298462, 0.1161346584558487, -0.00885622389614582 - ] - ], - [ + ], [ -0.10677414387464523, -0.10672265291213989, @@ -18977,18 +20090,16 @@ export const testData = { 0.022619053721427917, -0.1052321121096611, -0.04445267096161842 - ], - [ - 0.06914974004030228, - 0.12371136248111725, - -0.03412988409399986 ] ] - ] - ], - [ + ], [ [ + [ + 0.06914974004030228, + 0.12371136248111725, + -0.03412988409399986 + ], [ 0.09421706944704056, -0.01031185407191515, @@ -18998,14 +20109,14 @@ export const testData = { -0.016104474663734436, -0.06170425936579704, 0.037245430052280426 - ], + ] + ], + [ [ -0.0007366397767327726, -0.0663040354847908, 0.086556576192379 - ] - ], - [ + ], [ -0.06079341098666191, -0.09216593950986862, @@ -19015,14 +20126,14 @@ export const testData = { -0.008356397971510887, -0.07491207867860794, -0.11108863353729248 - ], + ] + ], + [ [ -0.04077182710170746, -0.1041940450668335, 0.07401486486196518 - ] - ], - [ + ], [ -0.016950387507677078, 0.07009042799472809, @@ -19032,16 +20143,18 @@ export const testData = { 0.010960990563035011, -0.020952291786670685, -0.07018402963876724 - ], - [ - 0.030636340379714966, - -0.11833041161298752, - -0.06631190329790115 ] ] - ], + ] + ], + [ [ [ + [ + 0.030636340379714966, + -0.11833041161298752, + -0.06631190329790115 + ], [ 0.10852135717868805, -0.02641327865421772, @@ -19051,14 +20164,14 @@ export const testData = { 0.08058465272188187, -0.02868703380227089, -0.10953208804130554 - ], + ] + ], + [ [ 0.10928711295127869, 0.011463882401585579, 0.12860336899757385 - ] - ], - [ + ], [ -0.12307491153478622, 0.028042973950505257, @@ -19068,14 +20181,14 @@ export const testData = { -0.01652207039296627, -0.1192781999707222, -0.12385933846235275 - ], + ] + ], + [ [ 0.0068649169988930225, 0.13416090607643127, 0.010427097789943218 - ] - ], - [ + ], [ -0.012607605196535587, 0.12684836983680725, @@ -19085,18 +20198,16 @@ export const testData = { -0.07598394900560379, 0.08653328567743301, 0.09710167348384857 - ], - [ - 0.11799715459346771, - 0.10701807588338852, - 0.12649768590927124 ] ] - ] - ], - [ + ], [ [ + [ + 0.11799715459346771, + 0.10701807588338852, + 0.12649768590927124 + ], [ -0.05047071725130081, 0.019567115232348442, @@ -19106,14 +20217,14 @@ export const testData = { -0.018113935366272926, 0.10758863389492035, -0.10752318054437637 - ], + ] + ], + [ [ 0.07436436414718628, -0.07862627506256104, 0.0007462596404366195 - ] - ], - [ + ], [ -0.016202278435230255, -0.06129545718431473, @@ -19123,14 +20234,14 @@ export const testData = { -0.06893385201692581, 0.12325625866651535, -0.04926367849111557 - ], + ] + ], + [ [ 0.08613324165344238, -0.03241463378071785, -0.10714203119277954 - ] - ], - [ + ], [ 0.10563848167657852, -0.037575751543045044, @@ -19140,172 +20251,6 @@ export const testData = { 0.010202044621109962, -0.0013864414067938924, 0.03840000927448273 - ], - [ - -0.033017437905073166, - -0.039262499660253525, - 0.0744556114077568 - ] - ] - ], - [ - [ - [ - 0.06237300857901573, - 0.1202826276421547, - 0.01501829270273447 - ], - [ - -0.03532655909657478, - -0.028991753235459328, - -0.027731310576200485 - ], - [ - -0.04300585016608238, - -0.04644265025854111, - -0.038341689854860306 - ] - ], - [ - [ - 0.04103976860642433, - 0.05384436249732971, - 0.10357610881328583 - ], - [ - -0.1324263960123062, - 0.10552726686000824, - -0.02741682529449463 - ], - [ - -0.13297802209854126, - 0.08896347135305405, - -0.07715301215648651 - ] - ], - [ - [ - -0.06132258102297783, - 0.04516405239701271, - 0.0222906656563282 - ], - [ - 0.09276392310857773, - -0.0949527695775032, - 0.07392872869968414 - ], - [ - 0.07092973589897156, - 0.08423259854316711, - -0.04529407620429993 - ] - ] - ] - ], - [ - [ - [ - [ - 0.02311135269701481, - 0.040055301040410995, - 0.12830914556980133 - ], - [ - -0.08269394189119339, - -0.12494990229606628, - -0.12307319045066833 - ], - [ - 0.018023155629634857, - -0.10342481732368469, - -0.02519121766090393 - ] - ], - [ - [ - -0.06361400336027145, - 0.024651339277625084, - -0.09643067419528961 - ], - [ - 0.08391905575990677, - -0.13368600606918335, - -0.07455432415008545 - ], - [ - 0.02808072417974472, - -0.13384917378425598, - 0.03354187309741974 - ] - ], - [ - [ - -0.05091074854135513, - -0.06872890144586563, - 0.0975482165813446 - ], - [ - -0.04394025728106499, - 0.03216959536075592, - -0.05254532769322395 - ], - [ - 0.06366001069545746, - 0.12392594665288925, - 0.1306309849023819 - ] - ] - ], - [ - [ - [ - -0.08231638371944427, - -0.1352720409631729, - -0.09515999257564545 - ], - [ - 0.038335442543029785, - 0.054630495607852936, - 0.07147255539894104 - ], - [ - 0.059092968702316284, - 0.13238413631916046, - -0.10319491475820541 - ] - ], - [ - [ - -0.10668620467185974, - -0.042614519596099854, - 0.10562329739332199 - ], - [ - -0.10449402779340744, - 0.10202737897634506, - 0.022643063217401505 - ], - [ - 0.0841764360666275, - 0.13482370972633362, - 0.13245315849781036 - ] - ], - [ - [ - 0.13064035773277283, - -0.033394865691661835, - -0.05806885287165642 - ], - [ - 0.057771969586610794, - 0.11604811251163483, - 0.003388179698958993 - ], - [ - -0.03221295773983002, - -0.02200985699892044, - -0.048572737723588943 ] ] ] @@ -19316,424 +20261,424 @@ export const testData = { [ [ [ - 0.31455111503601074, - 0.08514947444200516, - -0.15354058146476746, - -0.06375192850828171 + -0.5189220309257507, + -0.5165614485740662, + -0.6292287707328796, + -0.05756598338484764 ], [ - 0.5849013328552246, - -0.2777863144874573, - -0.07062370330095291, - 0.24299079179763794 + -0.856631338596344, + -0.3688551187515259, + -0.4376771152019501, + -0.0977354496717453 ], [ - -0.3012371063232422, - 0.1636168658733368, - 0.14740002155303955, - -0.028624363243579865 + -0.5509511232376099, + -0.01779169961810112, + -0.55179363489151, + 0.7810271382331848 ], [ - 0.5005623698234558, - -1.00490140914917, - -0.4954855442047119, - 0.131992906332016 + 0.2855244576931, + 0.06042236462235451, + -0.12005633115768433, + 0.60771244764328 ] ], [ [ - -0.11682949215173721, - -0.44103288650512695, - 0.5741671323776245, - 0.024398483335971832 + -0.22281594574451447, + -0.30689749121665955, + 0.7004629969596863, + 0.8319418430328369 ], [ - -0.774344801902771, - 0.11496435850858688, - 0.17903274297714233, - 0.36282312870025635 + -1.1546739339828491, + -0.6868062615394592, + -0.2238551527261734, + 0.9293049573898315 ], [ - -0.6987835168838501, - -0.37187090516090393, - 0.6472610235214233, - 0.7521082162857056 + -0.6667256951332092, + -0.23265919089317322, + -0.28645816445350647, + -0.6312382817268372 ], [ - 1.5605796575546265, - 0.2675955891609192, - -0.03801131248474121, - 0.6034815907478333 + 0.4375527799129486, + 0.3424995243549347, + 0.49018558859825134, + 0.1981693059206009 ] ], [ [ - -0.42367294430732727, - 0.03318726271390915, - 0.5253119468688965, - 0.3473888635635376 + -0.05317973718047142, + -0.3206823766231537, + 0.8374507427215576, + -0.3056468963623047 ], [ - -0.5904951095581055, - -0.18561586737632751, - 0.2454434335231781, - -0.6931743621826172 + 0.2974139153957367, + 0.9845985770225525, + 0.44274604320526123, + 0.14024977385997772 ], [ - -0.39125943183898926, - -1.108742356300354, - -0.507588267326355, - 0.37696021795272827 + -0.48651963472366333, + 0.879676878452301, + 0.01909274235367775, + -0.15339325368404388 ], [ - 0.5191097855567932, - 0.6672462224960327, - -0.15240344405174255, - 0.13204294443130493 + -0.030385207384824753, + 0.1865607053041458, + 0.22969035804271698, + 0.18484054505825043 ] ], [ [ - 0.0351962074637413, - 0.40326881408691406, - -0.0105043426156044, - 0.13288968801498413 + 0.16490347683429718, + 0.9333891868591309, + 0.11205387115478516, + 0.035932887345552444 ], [ - -0.9662636518478394, - 0.4197092056274414, - 0.7768668532371521, - 0.5667317509651184 + 0.04396235570311546, + -0.31778234243392944, + -0.6915766596794128, + -0.7603960633277893 ], [ - 0.8745118379592896, - -0.4432828426361084, - -0.7016594409942627, - 0.06813762336969376 + 0.48135581612586975, + 0.5444054007530212, + -0.7927911877632141, + -0.41890159249305725 ], [ - 0.628696858882904, - 0.23590031266212463, - 0.35417571663856506, - -0.06674491614103317 + -0.49668002128601074, + -0.559000551700592, + -0.1916334480047226, + 0.07035645842552185 ] ] ], [ [ [ - -0.12724320590496063, - -0.1676921546459198, - -0.6764430999755859, - -0.4281846880912781 + 0.027814757078886032, + -0.36531198024749756, + -0.2956852614879608, + -0.07494735717773438 ], [ - 0.14261625707149506, - -0.189521923661232, - -0.5238783359527588, - -0.11030559241771698 + 0.317421019077301, + 0.20873019099235535, + -0.17261816561222076, + 0.18707580864429474 ], [ - -0.08100511133670807, - 0.5715047121047974, - 0.03456680476665497, - 0.0896516889333725 + -0.5448725819587708, + 0.4587745666503906, + 0.2725429832935333, + 0.6743288636207581 ], [ - 0.04384508728981018, - 0.2983396053314209, - 0.44286680221557617, - 0.33616024255752563 + -0.19684088230133057, + -0.13441979885101318, + -0.68226557970047, + 0.0015642233192920685 ] ], [ [ - 0.0530446320772171, - -0.274275541305542, - -0.7193563580513, - -0.2518726587295532 + -0.18683089315891266, + -0.7692659497261047, + -0.39447149634361267, + 0.13065055012702942 ], [ - 0.35049742460250854, - 0.9664632678031921, - -0.10006172209978104, - -0.31052252650260925 + 0.48978617787361145, + 0.38429391384124756, + 0.47841736674308777, + -0.3207741677761078 ], [ - -0.006888136267662048, - -0.15175409615039825, - 0.33437609672546387, - -0.7952547669410706 + -0.3932279944419861, + 0.12875378131866455, + -0.8934746980667114, + 0.4101417660713196 ], [ - -0.8238822221755981, - -0.5533866286277771, - -0.32959437370300293, - -0.821625292301178 + 0.5834230780601501, + 0.4180571138858795, + -0.631263792514801, + -0.5178388953208923 ] ], [ [ - -0.8099207878112793, - -0.16976004838943481, - 0.34372830390930176, - 0.3888295292854309 + -0.03619886562228203, + -0.20496532320976257, + 0.5740773677825928, + -0.47996267676353455 ], [ - -0.3730044364929199, - 0.6971028447151184, - 0.4578671455383301, - -0.4588431119918823 + -0.12516352534294128, + 0.14540526270866394, + 0.6903879046440125, + -0.2156420648097992 ], [ - 0.11398746073246002, - 1.0882223844528198, - -0.17739616334438324, - 0.4957335591316223 + 0.1515147089958191, + -0.5476300716400146, + -0.7382059693336487, + -0.31151825189590454 ], [ - 0.08251698315143585, - -0.796347439289093, - 0.35041654109954834, - 0.03478327393531799 + 0.13428078591823578, + -0.0961957573890686, + -0.005456414073705673, + 0.004339788109064102 ] ], [ [ - -0.7430188059806824, - 0.027915969491004944, - 0.6628812551498413, - 0.2345527857542038 + 0.11125026643276215, + -0.3502165377140045, + 0.3796243667602539, + -0.07001438736915588 ], [ - -1.0526297092437744, - -0.45693933963775635, - -0.5519452095031738, - -0.37496161460876465 + -0.44981685280799866, + -0.028404127806425095, + -0.19824430346488953, + 0.248864084482193 ], [ - -0.1880352944135666, - -0.4893310070037842, - -0.38091444969177246, - 0.00243164598941803 + -0.23346014320850372, + -0.5089297294616699, + -0.25922563672065735, + 0.11221137642860413 ], [ - -0.5911522507667542, - -0.4146895408630371, - -0.36692339181900024, - -0.22563600540161133 + 0.43701913952827454, + 0.23463225364685059, + 0.13308370113372803, + 0.27311310172080994 ] ] ], [ [ [ - -0.1505451649427414, - 0.18801279366016388, - 0.22355595231056213, - 0.43067818880081177 + 0.71690434217453, + -0.37317198514938354, + -0.25998103618621826, + -0.3843086361885071 ], [ - 0.05739826709032059, - -0.27782684564590454, - 0.32386404275894165, - -0.40201282501220703 + 0.07634495943784714, + 0.3695131242275238, + 0.22529920935630798, + 0.4135698974132538 ], [ - 0.0747055634856224, - 0.013080373406410217, - 0.3785865306854248, - -0.5415412783622742 + -0.4950774908065796, + 0.509172260761261, + 0.032416440546512604, + -0.7605869770050049 ], [ - -0.10402481257915497, - 0.5471309423446655, - 0.09130645543336868, - 0.08788447082042694 + 0.2789137661457062, + -0.24722981452941895, + 0.33938825130462646, + 0.8772264719009399 ] ], [ [ - -0.7555528879165649, - 0.4644201993942261, - -0.12831014394760132, - 0.6371702551841736 + 0.5783311128616333, + -0.032182641327381134, + -0.4945024847984314, + 0.10007165372371674 ], [ - -0.4957234263420105, - 0.6983954906463623, - 0.4560081362724304, - -0.25263774394989014 + -0.029323793947696686, + 0.2238347828388214, + 1.7685524225234985, + 0.19979894161224365 ], [ - -0.059423789381980896, - 0.35423970222473145, - -0.13772667944431305, - 0.2738529443740845 + -0.7016185522079468, + 0.08255937695503235, + 0.07554244250059128, + -0.13586947321891785 ], [ - -0.06502597033977509, - -0.15657509863376617, - 0.3571682870388031, - 0.09371341019868851 + 0.1221686378121376, + -0.34831491112709045, + -0.5361258387565613, + 0.36475053429603577 ] ], [ [ - 0.5735805630683899, - -0.9974273443222046, - 0.6931644678115845, - 0.23308917880058289 + -0.18205034732818604, + 0.009124837815761566, + 0.48837193846702576, + 0.18220144510269165 ], [ - -0.6186490058898926, - 1.0131170749664307, - 0.24364443123340607, - -0.21681837737560272 + 0.2875525653362274, + -0.7277586460113525, + 0.383545458316803, + 0.7922366857528687 ], [ - 0.08148512244224548, - 0.7624080181121826, - 0.6038268804550171, - 0.22795037925243378 + 0.35036027431488037, + 0.4647741913795471, + -0.02845963090658188, + 0.3766854405403137 ], [ - -0.34718501567840576, - 0.3617039918899536, - 0.07529257237911224, - 0.5715086460113525 + 0.625316858291626, + -0.13582804799079895, + 0.09993312507867813, + 0.10810399800539017 ] ], [ [ - -0.3552524447441101, - 0.6428000330924988, - -0.014569178223609924, - -0.2555174231529236 + 0.0920933410525322, + -0.2327292561531067, + 0.1246594563126564, + -0.24508613348007202 ], [ - 0.0480840727686882, - 0.47359269857406616, - -0.4183531403541565, - -0.15669973194599152 + 0.0638505071401596, + -0.1594996154308319, + -0.43965858221054077, + -0.12859344482421875 ], [ - 0.31845390796661377, - 0.2326236367225647, - -0.42830348014831543, - 0.2483210265636444 + -0.48574507236480713, + 0.12709787487983704, + 0.10260476917028427, + 0.16429319977760315 ], [ - 0.33505934476852417, - 0.1318371742963791, - 0.30133748054504395, - 0.40604573488235474 + 0.05439956486225128, + -0.029498502612113953, + -0.11129797250032425, + -0.26847541332244873 ] ] ], [ [ [ - -0.10241574048995972, - 0.24514983594417572, - -0.7703133225440979, - -0.20298685133457184 + -0.2452285885810852, + -0.06107306852936745, + 0.8597950339317322, + 0.394406795501709 ], [ - 0.12950509786605835, - -0.0905580073595047, - -0.2170005887746811, - 0.3739772439002991 + -0.17274555563926697, + -0.03637805953621864, + -0.8504515290260315, + 0.4729595482349396 ], [ - -0.1046983003616333, - -0.05653303861618042, - 0.18341003358364105, - 0.6786373853683472 + 0.2524721920490265, + -0.4057195782661438, + -0.11825022101402283, + 0.04109963774681091 ], [ - -0.07671500742435455, - -0.2652748227119446, - 0.2162427455186844, - -0.629124641418457 + 0.9326950311660767, + -0.5181980133056641, + 0.3552418053150177, + 1.070439100265503 ] ], [ [ - 0.7663935422897339, - -0.6792891025543213, - 0.5431439876556396, - -0.024241341277956963 + -0.7024675607681274, + 0.5648580193519592, + 0.5240363478660583, + -0.7053726315498352 ], [ - -0.6712461709976196, - -0.766162633895874, - -0.4784229099750519, - 0.4438798725605011 + -0.35612714290618896, + -0.6093287467956543, + 1.1249797344207764, + -0.8079068660736084 ], [ - -0.4010832607746124, - 0.14694184064865112, - -0.109443798661232, - -0.2974053621292114 + -0.27538979053497314, + 0.832629382610321, + 0.5831271409988403, + 0.6093882918357849 ], [ - -0.14182105660438538, - 0.0485818013548851, - -0.3780379295349121, - 0.2742367386817932 + 0.2426019012928009, + 0.2856079041957855, + -0.05524546280503273, + 0.310916930437088 ] ], [ [ - -0.1508481353521347, - -0.6024109125137329, - 0.4804859757423401, - 0.2117317169904709 + 0.26993316411972046, + 0.2278856486082077, + -0.07653680443763733, + -0.021051857620477676 ], [ - -0.4901675283908844, - -0.5975161790847778, - 1.059933066368103, - 0.9510890245437622 + 0.7272006869316101, + 0.4395790696144104, + 0.01439421996474266, + -1.0826799869537354 ], [ - 0.12868791818618774, - -0.5460107326507568, - 0.37731510400772095, - 0.3430858552455902 + 0.10812952369451523, + 0.4959411323070526, + -0.31829285621643066, + -0.49640241265296936 ], [ - 0.10134606063365936, - 0.15810571610927582, - 0.1015453189611435, - -0.47414088249206543 + -0.3244398832321167, + -0.5352140665054321, + -0.4826482832431793, + -0.6389537453651428 ] ], [ [ - -0.5066900849342346, - 0.5150911808013916, - 0.4745583236217499, - -0.7174737453460693 + -0.2555220425128937, + -0.0470096580684185, + 0.11474063992500305, + 0.7965570092201233 ], [ - 0.07770748436450958, - 0.8527685403823853, - 0.05662144720554352, - -0.23491783440113068 + -0.046865809708833694, + -0.4719932973384857, + -0.34037473797798157, + 0.059014324098825455 ], [ - 0.2234104871749878, - 0.8177720904350281, - -1.0931587219238281, - -0.031021563336253166 + 0.267282098531723, + 0.42551925778388977, + -0.2612544596195221, + -0.09305000305175781 ], [ - 0.6408951282501221, - -0.44277966022491455, - -0.7188045382499695, - -0.18751439452171326 + 0.14654460549354553, + -0.01344921812415123, + 0.03611213341355324, + -0.15932729840278625 ] ] ] @@ -19744,424 +20689,424 @@ export const testData = { [ [ [ - 0.11937001347541809, - -0.17028185725212097, - -0.17028185725212097, - -0.2494322657585144 + 0.10447724163532257, + 0.2759958505630493, + 0.2759958505630493, + 0.27689602971076965 ], [ - -0.16501948237419128, - -0.040856726467609406, - -0.040856726467609406, - -0.022803347557783127 + 0.3304583430290222, + 0.8043910264968872, + 0.8043910264968872, + 0.748386025428772 ], [ - -0.16501948237419128, - -0.040856726467609406, - -0.040856726467609406, - -0.022803347557783127 + 0.3304583430290222, + 0.8043910264968872, + 0.8043910264968872, + 0.748386025428772 ], [ - -0.10317385941743851, - 0.24273720383644104, - 0.24273720383644104, - 0.211464062333107 + 0.49931013584136963, + 0.8851284980773926, + 0.8851284980773926, + 0.8720530867576599 ] ], [ [ - 0.23872655630111694, - -0.0793268159031868, - -0.0793268159031868, - -0.31080520153045654 + 0.2669637203216553, + 0.47796863317489624, + 0.47796863317489624, + 0.33882027864456177 ], [ - -0.15844789147377014, - -0.23631811141967773, - -0.23631811141967773, - -0.37387970089912415 + 0.5041998624801636, + 0.8133538961410522, + 0.8133538961410522, + 0.6375466585159302 ], [ - -0.15844789147377014, - -0.23631811141967773, - -0.23631811141967773, - -0.37387970089912415 + 0.5041998624801636, + 0.8133538961410522, + 0.8133538961410522, + 0.6375466585159302 ], [ - -0.17743602395057678, - 0.009504087269306183, - 0.009504087269306183, - -0.13519541919231415 + 0.5654966235160828, + 0.6807993054389954, + 0.6807993054389954, + 0.6420475840568542 ] ], [ [ - 0.23872655630111694, - -0.0793268159031868, - -0.0793268159031868, - -0.31080520153045654 + 0.2669637203216553, + 0.47796863317489624, + 0.47796863317489624, + 0.33882027864456177 ], [ - -0.15844789147377014, - -0.23631811141967773, - -0.23631811141967773, - -0.37387970089912415 + 0.5041998624801636, + 0.8133538961410522, + 0.8133538961410522, + 0.6375466585159302 ], [ - -0.15844789147377014, - -0.23631811141967773, - -0.23631811141967773, - -0.37387970089912415 + 0.5041998624801636, + 0.8133538961410522, + 0.8133538961410522, + 0.6375466585159302 ], [ - -0.17743602395057678, - 0.009504087269306183, - 0.009504087269306183, - -0.13519541919231415 + 0.5654966235160828, + 0.6807993054389954, + 0.6807993054389954, + 0.6420475840568542 ] ], [ [ - -0.004772186279296875, - -0.18217048048973083, - -0.18217048048973083, - -0.2542453706264496 + 0.1181013435125351, + 0.3042549192905426, + 0.3042549192905426, + 0.2648759186267853 ], [ - -0.2590583562850952, - -0.4182286560535431, - -0.4182286560535431, - -0.4463523328304291 + 0.3148439824581146, + 0.41089382767677307, + 0.41089382767677307, + 0.3637365400791168 ], [ - -0.2590583562850952, - -0.4182286560535431, - -0.4182286560535431, - -0.4463523328304291 + 0.3148439824581146, + 0.41089382767677307, + 0.41089382767677307, + 0.3637365400791168 ], [ - -0.17544502019882202, - -0.20959782600402832, - -0.20959782600402832, - -0.30856314301490784 + 0.21775929629802704, + 0.12964285910129547, + 0.12964285910129547, + 0.21047258377075195 ] ] ], [ [ [ - -0.032347261905670166, - -0.15482750535011292, - -0.15482750535011292, - -0.12919452786445618 + 0.18058183789253235, + 0.3834855556488037, + 0.3834855556488037, + 0.6673980951309204 ], [ - 0.4717216491699219, - 0.49012768268585205, - 0.49012768268585205, - 0.2319510579109192 + 0.537636935710907, + 0.7813745141029358, + 0.7813745141029358, + 0.9144545793533325 ], [ - 0.4717216491699219, - 0.49012768268585205, - 0.49012768268585205, - 0.2319510579109192 + 0.537636935710907, + 0.7813745141029358, + 0.7813745141029358, + 0.9144545793533325 ], [ - 0.5639673471450806, - 0.6972559690475464, - 0.6972559690475464, - 0.26348334550857544 + 0.5520140528678894, + 0.5436312556266785, + 0.5436312556266785, + 0.4455137848854065 ] ], [ [ - -0.20366701483726501, - -0.3893524706363678, - -0.3893524706363678, - -0.19097280502319336 + 0.2939951717853546, + 0.4372510015964508, + 0.4372510015964508, + 0.49767136573791504 ], [ - 0.7182782888412476, - 0.7658469676971436, - 0.7658469676971436, - 0.4932699501514435 + 0.7392789721488953, + 1.0817437171936035, + 1.0817437171936035, + 0.7633848190307617 ], [ - 0.7182782888412476, - 0.7658469676971436, - 0.7658469676971436, - 0.4932699501514435 + 0.7392789721488953, + 1.0817437171936035, + 1.0817437171936035, + 0.7633848190307617 ], [ - 0.909779965877533, - 1.1880854368209839, - 1.1880854368209839, - 0.6205307841300964 + 0.6086863875389099, + 0.568009078502655, + 0.568009078502655, + 0.13552002608776093 ] ], [ [ - -0.20366701483726501, - -0.3893524706363678, - -0.3893524706363678, - -0.19097280502319336 + 0.2939951717853546, + 0.4372510015964508, + 0.4372510015964508, + 0.49767136573791504 ], [ - 0.7182782888412476, - 0.7658469676971436, - 0.7658469676971436, - 0.4932699501514435 + 0.7392789721488953, + 1.0817437171936035, + 1.0817437171936035, + 0.7633848190307617 ], [ - 0.7182782888412476, - 0.7658469676971436, - 0.7658469676971436, - 0.4932699501514435 + 0.7392789721488953, + 1.0817437171936035, + 1.0817437171936035, + 0.7633848190307617 ], [ - 0.909779965877533, - 1.1880854368209839, - 1.1880854368209839, - 0.6205307841300964 + 0.6086863875389099, + 0.568009078502655, + 0.568009078502655, + 0.13552002608776093 ] ], [ [ - -0.34812459349632263, - -0.49819377064704895, - -0.49819377064704895, - -0.1905551254749298 + 0.10174182057380676, + 0.13050755858421326, + 0.13050755858421326, + 0.182585209608078 ], [ - 0.39433231949806213, - 0.3382018506526947, - 0.3382018506526947, - 0.38440853357315063 + 0.5305261611938477, + 0.7380304336547852, + 0.7380304336547852, + 0.4065806269645691 ], [ - 0.39433231949806213, - 0.3382018506526947, - 0.3382018506526947, - 0.38440853357315063 + 0.5305261611938477, + 0.7380304336547852, + 0.7380304336547852, + 0.4065806269645691 ], [ - 0.6273276805877686, - 0.7802046537399292, - 0.7802046537399292, - 0.47475478053092957 + 0.45701250433921814, + 0.37933337688446045, + 0.37933337688446045, + -0.008228868246078491 ] ] ], [ [ [ - -0.1978110373020172, - -0.5583994388580322, - -0.5583994388580322, - -0.36540114879608154 + -0.025542324408888817, + -0.17474104464054108, + -0.17474104464054108, + -0.21195659041404724 ], [ - -0.33952441811561584, - -0.7981580495834351, - -0.7981580495834351, - -0.811761200428009 + 0.03435610979795456, + -0.12244029343128204, + -0.12244029343128204, + -0.3096188008785248 ], [ - -0.33952441811561584, - -0.7981580495834351, - -0.7981580495834351, - -0.811761200428009 + 0.03435610979795456, + -0.12244029343128204, + -0.12244029343128204, + -0.3096188008785248 ], [ - -0.25532710552215576, - -0.7077865600585938, - -0.7077865600585938, - -0.8285654187202454 + -0.032347261905670166, + -0.15482750535011292, + -0.15482750535011292, + -0.12919452786445618 ] ], [ [ - -0.25234299898147583, - -0.5859032869338989, - -0.5859032869338989, - -0.4138944745063782 + 0.19978223741054535, + -0.06369980424642563, + -0.06369980424642563, + -0.055818624794483185 ], [ - -0.2787504196166992, - -0.5052691698074341, - -0.5052691698074341, - -0.5705044269561768 + 0.18761692941188812, + -0.030813774093985558, + -0.030813774093985558, + -0.11953065544366837 ], [ - -0.2787504196166992, - -0.5052691698074341, - -0.5052691698074341, - -0.5705044269561768 + 0.18761692941188812, + -0.030813774093985558, + -0.030813774093985558, + -0.11953065544366837 ], [ - -0.14297613501548767, - -0.40449437499046326, - -0.40449437499046326, - -0.5221775770187378 + -0.20366701483726501, + -0.3893524706363678, + -0.3893524706363678, + -0.19097280502319336 ] ], [ [ - -0.25234299898147583, - -0.5859032869338989, - -0.5859032869338989, - -0.4138944745063782 + 0.19978223741054535, + -0.06369980424642563, + -0.06369980424642563, + -0.055818624794483185 ], [ - -0.2787504196166992, - -0.5052691698074341, - -0.5052691698074341, - -0.5705044269561768 + 0.18761692941188812, + -0.030813774093985558, + -0.030813774093985558, + -0.11953065544366837 ], [ - -0.2787504196166992, - -0.5052691698074341, - -0.5052691698074341, - -0.5705044269561768 + 0.18761692941188812, + -0.030813774093985558, + -0.030813774093985558, + -0.11953065544366837 ], [ - -0.14297613501548767, - -0.40449437499046326, - -0.40449437499046326, - -0.5221775770187378 + -0.20366701483726501, + -0.3893524706363678, + -0.3893524706363678, + -0.19097280502319336 ] ], [ [ - -0.16643691062927246, - -0.3480529189109802, - -0.3480529189109802, - -0.3042113780975342 + 0.2710735499858856, + 0.20295241475105286, + 0.20295241475105286, + 0.27079930901527405 ], [ - -0.10318074375391006, - -0.15331032872200012, - -0.15331032872200012, - -0.254325270652771 + 0.1559443175792694, + 0.1467614471912384, + 0.1467614471912384, + 0.17059043049812317 ], [ - -0.10318074375391006, - -0.15331032872200012, - -0.15331032872200012, - -0.254325270652771 + 0.1559443175792694, + 0.1467614471912384, + 0.1467614471912384, + 0.17059043049812317 ], [ - 0.06485657393932343, - 0.058379679918289185, - 0.058379679918289185, - -0.0677238404750824 + -0.34812459349632263, + -0.49819377064704895, + -0.49819377064704895, + -0.1905551254749298 ] ] ], [ [ [ - -0.0900675356388092, - 0.0779576450586319, - 0.0779576450586319, - 0.3974590003490448 + 0.16911828517913818, + 0.33074456453323364, + 0.33074456453323364, + 0.10321924090385437 ], [ - 0.18694667518138885, - 0.2687353491783142, - 0.2687353491783142, - 0.6209511756896973 + 0.15183815360069275, + 0.08283436298370361, + 0.08283436298370361, + -0.03318226337432861 ], [ - 0.18694667518138885, - 0.2687353491783142, - 0.2687353491783142, - 0.6209511756896973 + 0.15183815360069275, + 0.08283436298370361, + 0.08283436298370361, + -0.03318226337432861 ], [ - 0.2762960195541382, - 0.22902704775333405, - 0.22902704775333405, - 0.49565309286117554 + -0.194735586643219, + -0.4434100389480591, + -0.4434100389480591, + -0.2986520230770111 ] ], [ [ - 0.1626506894826889, - 0.37221455574035645, - 0.37221455574035645, - 0.471862256526947 + 0.19907379150390625, + 0.3374386429786682, + 0.3374386429786682, + -0.02413615584373474 ], [ - 0.5406043529510498, - 0.5700650215148926, - 0.5700650215148926, - 0.663710355758667 + 0.18061795830726624, + 0.05656883120536804, + 0.05656883120536804, + -0.2146604061126709 ], [ - 0.5406043529510498, - 0.5700650215148926, - 0.5700650215148926, - 0.663710355758667 + 0.18061795830726624, + 0.05656883120536804, + 0.05656883120536804, + -0.2146604061126709 ], [ - 0.548866868019104, - 0.48504796624183655, - 0.48504796624183655, - 0.5624213218688965 + -0.07470852136611938, + -0.34530121088027954, + -0.34530121088027954, + -0.3103943169116974 ] ], [ [ - 0.1626506894826889, - 0.37221455574035645, - 0.37221455574035645, - 0.471862256526947 + 0.19907379150390625, + 0.3374386429786682, + 0.3374386429786682, + -0.02413615584373474 ], [ - 0.5406043529510498, - 0.5700650215148926, - 0.5700650215148926, - 0.663710355758667 + 0.18061795830726624, + 0.05656883120536804, + 0.05656883120536804, + -0.2146604061126709 ], [ - 0.5406043529510498, - 0.5700650215148926, - 0.5700650215148926, - 0.663710355758667 + 0.18061795830726624, + 0.05656883120536804, + 0.05656883120536804, + -0.2146604061126709 ], [ - 0.548866868019104, - 0.48504796624183655, - 0.48504796624183655, - 0.5624213218688965 + -0.07470852136611938, + -0.34530121088027954, + -0.34530121088027954, + -0.3103943169116974 ] ], [ [ - 0.1689358353614807, - 0.41490018367767334, - 0.41490018367767334, - 0.4976133704185486 + -0.27180415391921997, + -0.14891774952411652, + -0.14891774952411652, + -0.27959930896759033 ], [ - 0.44486090540885925, - 0.6522586345672607, - 0.6522586345672607, - 0.7450566291809082 + -0.3019259572029114, + -0.3711758255958557, + -0.3711758255958557, + -0.44573020935058594 ], [ - 0.44486090540885925, - 0.6522586345672607, - 0.6522586345672607, - 0.7450566291809082 + -0.3019259572029114, + -0.3711758255958557, + -0.3711758255958557, + -0.44573020935058594 ], [ - 0.418190598487854, - 0.4521670937538147, - 0.4521670937538147, - 0.5486364364624023 + -0.13937608897686005, + -0.2628017067909241, + -0.2628017067909241, + -0.2183668613433838 ] ] ] @@ -20172,106 +21117,106 @@ export const testData = { [ [ [ - -3.5263595581054688, - -3.030369520187378, - 0.8043696880340576 + 0.1067051887512207, + 0.20825695991516113, + 0.3233646750450134 ], [ - -2.895697832107544, - -1.649491310119629, - 3.0863945484161377 + 1.075575828552246, + 0.9549298286437988, + 0.8322933912277222 ], [ - -3.784050226211548, - -2.1708388328552246, - -0.1397075653076172 + 2.7843332290649414, + 3.024883270263672, + 1.9580979347229004 ] ], [ [ - -3.3701252937316895, - -1.9332741498947144, - -1.379983901977539 + -1.088132619857788, + -4.254583358764648, + -4.973104953765869 ], [ - -0.5808892250061035, - 1.2413580417633057, - 0.6115028858184814 + 0.14743173122406006, + -2.7659130096435547, + -3.4836788177490234 ], [ - -1.771789789199829, - 1.7410807609558105, - -1.4635964632034302 + 2.8671376705169678, + 0.8264245986938477, + -1.714296817779541 ] ], [ [ - -3.274324893951416, - -1.413101315498352, - -2.4460387229919434 + 2.8881595134735107, + -1.7971699237823486, + -5.078564167022705 ], [ - -0.8801982402801514, - 0.3345968723297119, - -1.8272972106933594 + 4.171820163726807, + 0.5749964714050293, + -3.3589401245117188 ], [ - -2.295225143432617, - 0.24299001693725586, - -3.8926587104797363 + 5.7922539710998535, + 4.064516067504883, + -0.2995426654815674 ] ] ], [ [ [ - -4.893064022064209, - -3.5297491550445557, - -5.885024547576904 + -3.8329830169677734, + -4.827998638153076, + -0.7829046249389648 ], [ - -5.674193859100342, - -3.415929079055786, - -2.598536968231201 + -2.6662209033966064, + 0.8226261138916016, + 6.516355037689209 ], [ - -6.66256856918335, - -2.3843705654144287, - -0.9642940759658813 + -1.1823781728744507, + 1.8469009399414062, + 5.310114860534668 ] ], [ [ - -1.4495625495910645, - 1.1278483867645264, - -0.48337650299072266 + -3.78059720993042, + -4.655887126922607, + 0.5805654525756836 ], [ - -1.568361759185791, - 1.4692656993865967, - 2.312347888946533 + -6.100958824157715, + -3.0644690990448, + 3.488039016723633 ], [ - -3.522430658340454, - 1.7604587078094482, - 3.373271942138672 + -5.953107833862305, + -2.9071502685546875, + 1.7705130577087402 ] ], [ [ - 0.945197582244873, - 1.9542927742004395, - 3.182798147201538 + 5.147970199584961, + 4.8943281173706055, + 8.273162841796875 ], [ - 3.1435790061950684, - 5.16965389251709, - 7.798410892486572 + -0.6796786785125732, + 0.45905232429504395, + 5.0116963386535645 ], [ - 1.423252820968628, - 5.795356750488281, - 8.605817794799805 + -2.6251235008239746, + -0.29294729232788086, + 3.885946750640869 ] ] ] @@ -20280,106 +21225,106 @@ export const testData = { [ [ [ - -3.5263595581054688, - -3.030369520187378, - 0.8043696880340576 + 0.1067051887512207, + 0.20825695991516113, + 0.3233646750450134 ], [ - -2.895697832107544, - -1.649491310119629, - 3.0863945484161377 + 1.075575828552246, + 0.9549298286437988, + 0.8322933912277222 ], [ - -3.784050226211548, - -2.1708388328552246, - -0.1397075653076172 + 2.7843332290649414, + 3.024883270263672, + 1.9580979347229004 ] ], [ [ - -3.3701252937316895, - -1.9332741498947144, - -1.379983901977539 + -1.088132619857788, + -4.254583358764648, + -4.973104953765869 ], [ - -0.5808892250061035, - 1.2413580417633057, - 0.6115028858184814 + 0.14743173122406006, + -2.7659130096435547, + -3.4836788177490234 ], [ - -1.771789789199829, - 1.7410807609558105, - -1.4635964632034302 + 2.8671376705169678, + 0.8264245986938477, + -1.714296817779541 ] ], [ [ - -3.274324893951416, - -1.413101315498352, - -2.4460387229919434 + 2.8881595134735107, + -1.7971699237823486, + -5.078564167022705 ], [ - -0.8801982402801514, - 0.3345968723297119, - -1.8272972106933594 + 4.171820163726807, + 0.5749964714050293, + -3.3589401245117188 ], [ - -2.295225143432617, - 0.24299001693725586, - -3.8926587104797363 + 5.7922539710998535, + 4.064516067504883, + -0.2995426654815674 ] ] ], [ [ [ - -4.893064022064209, - -3.5297491550445557, - -5.885024547576904 + -3.8329830169677734, + -4.827998638153076, + -0.7829046249389648 ], [ - -5.674193859100342, - -3.415929079055786, - -2.598536968231201 + -2.6662209033966064, + 0.8226261138916016, + 6.516355037689209 ], [ - -6.66256856918335, - -2.3843705654144287, - -0.9642940759658813 + -1.1823781728744507, + 1.8469009399414062, + 5.310114860534668 ] ], [ [ - -1.4495625495910645, - 1.1278483867645264, - -0.48337650299072266 + -3.78059720993042, + -4.655887126922607, + 0.5805654525756836 ], [ - -1.568361759185791, - 1.4692656993865967, - 2.312347888946533 + -6.100958824157715, + -3.0644690990448, + 3.488039016723633 ], [ - -3.522430658340454, - 1.7604587078094482, - 3.373271942138672 + -5.953107833862305, + -2.9071502685546875, + 1.7705130577087402 ] ], [ [ - 0.945197582244873, - 1.9542927742004395, - 3.182798147201538 + 5.147970199584961, + 4.8943281173706055, + 8.273162841796875 ], [ - 3.1435790061950684, - 5.16965389251709, - 7.798410892486572 + -0.6796786785125732, + 0.45905232429504395, + 5.0116963386535645 ], [ - 1.423252820968628, - 5.795356750488281, - 8.605817794799805 + -2.6251235008239746, + -0.29294729232788086, + 3.885946750640869 ] ] ] @@ -20388,106 +21333,106 @@ export const testData = { [ [ [ - 2.19404935836792, - 1.3994925022125244, - 4.993061065673828 + 0.4483606815338135, + 1.7787113189697266, + 5.192532539367676 ], [ - 4.617806434631348, - 4.7987380027771, - 8.019613265991211 + -1.4723293781280518, + 4.892696380615234, + 2.2916412353515625 ], [ - 5.39102029800415, - 4.112349510192871, - 5.7219624519348145 + -2.3301377296447754, + 4.890291213989258, + 1.6198128461837769 ] ], [ [ - -0.6837949752807617, - 2.2884609699249268, - 5.620293617248535 + 1.441436767578125, + -0.48497796058654785, + 1.6295900344848633 ], [ - 1.1893994808197021, - 5.189212799072266, - 8.51211929321289 + -1.1605052947998047, + 1.7250769138336182, + -2.4838342666625977 ], [ - 4.001502990722656, - 4.988478660583496, - 6.615469932556152 + -1.411887288093567, + 3.0889787673950195, + -0.87584388256073 ] ], [ [ - -4.521514892578125, - -0.5493941307067871, - 2.121269702911377 + -1.3780968189239502, + -1.879303216934204, + 0.6745200157165527 ], [ - -2.988053798675537, - 1.5764827728271484, - 4.8712005615234375 + -4.27053689956665, + -1.3108704090118408, + -1.585677146911621 ], [ - -0.9661457538604736, - 1.3847923278808594, - 3.518392562866211 + -3.8346633911132812, + -0.26355016231536865, + -1.8428313732147217 ] ] ], [ [ [ - -0.08539199829101562, - 2.0604448318481445, - 4.888823986053467 + -4.0036540031433105, + -5.653046607971191, + -3.195122241973877 ], [ - -1.1874403953552246, - 1.6464009284973145, - 5.388817310333252 + -3.8981828689575195, + -5.734371185302734, + -2.761385202407837 ], [ - -2.236534595489502, - 1.8138175010681152, - 6.296984672546387 + -1.9460368156433105, + -5.074745178222656, + -3.0354936122894287 ] ], [ [ - 1.9444174766540527, - 2.2282862663269043, - 8.413761138916016 + 0.344696044921875, + -1.1834907531738281, + -1.1799216270446777 ], [ - 1.623469591140747, - 2.040102005004883, - 7.556074142456055 + 0.8071980476379395, + -0.7569489479064941, + 0.02341151237487793 ], [ - 2.2142739295959473, - 4.395120620727539, - 7.946873664855957 + 1.2058725357055664, + -0.941962718963623, + -0.04741215705871582 ] ], [ [ - 1.8882660865783691, - 3.0171961784362793, - 7.231435775756836 + -0.6712508201599121, + -1.8187532424926758, + -2.691244125366211 ], [ - 1.0284156799316406, - 2.113191604614258, - 4.716576099395752 + -1.2874345779418945, + -2.0391221046447754, + -2.2225937843322754 ], [ - 1.4019911289215088, - 4.158297538757324, - 5.673982620239258 + -2.137885570526123, + -3.181636333465576, + -1.6979775428771973 ] ] ] @@ -20496,116 +21441,116 @@ export const testData = { [ [ [ - 2.19404935836792, - 1.3994925022125244, - 4.993061065673828 + 0.4483606815338135, + 1.7787113189697266, + 5.192532539367676 ], [ - 4.617806434631348, - 4.7987380027771, - 8.019613265991211 + -1.4723293781280518, + 4.892696380615234, + 2.2916412353515625 ], [ - 5.39102029800415, - 4.112349510192871, - 5.7219624519348145 + -2.3301377296447754, + 4.890291213989258, + 1.6198128461837769 ] ], [ [ - -0.6837949752807617, - 2.2884609699249268, - 5.620293617248535 + 1.441436767578125, + -0.48497796058654785, + 1.6295900344848633 ], [ - 1.1893994808197021, - 5.189212799072266, - 8.51211929321289 + -1.1605052947998047, + 1.7250769138336182, + -2.4838342666625977 ], [ - 4.001502990722656, - 4.988478660583496, - 6.615469932556152 + -1.411887288093567, + 3.0889787673950195, + -0.87584388256073 ] ], [ [ - -4.521514892578125, - -0.5493941307067871, - 2.121269702911377 + -1.3780968189239502, + -1.879303216934204, + 0.6745200157165527 ], [ - -2.988053798675537, - 1.5764827728271484, - 4.8712005615234375 + -4.27053689956665, + -1.3108704090118408, + -1.585677146911621 ], [ - -0.9661457538604736, - 1.3847923278808594, - 3.518392562866211 + -3.8346633911132812, + -0.26355016231536865, + -1.8428313732147217 ] ] ], [ [ [ - -0.08539199829101562, - 2.0604448318481445, - 4.888823986053467 + -4.0036540031433105, + -5.653046607971191, + -3.195122241973877 ], [ - -1.1874403953552246, - 1.6464009284973145, - 5.388817310333252 + -3.8981828689575195, + -5.734371185302734, + -2.761385202407837 ], [ - -2.236534595489502, - 1.8138175010681152, - 6.296984672546387 + -1.9460368156433105, + -5.074745178222656, + -3.0354936122894287 ] ], [ [ - 1.9444174766540527, - 2.2282862663269043, - 8.413761138916016 + 0.344696044921875, + -1.1834907531738281, + -1.1799216270446777 ], [ - 1.623469591140747, - 2.040102005004883, - 7.556074142456055 + 0.8071980476379395, + -0.7569489479064941, + 0.02341151237487793 ], [ - 2.2142739295959473, - 4.395120620727539, - 7.946873664855957 + 1.2058725357055664, + -0.941962718963623, + -0.04741215705871582 ] ], [ [ - 1.8882660865783691, - 3.0171961784362793, - 7.231435775756836 + -0.6712508201599121, + -1.8187532424926758, + -2.691244125366211 ], [ - 1.0284156799316406, - 2.113191604614258, - 4.716576099395752 + -1.2874345779418945, + -2.0391221046447754, + -2.2225937843322754 ], [ - 1.4019911289215088, - 4.158297538757324, - 5.673982620239258 + -2.137885570526123, + -3.181636333465576, + -1.6979775428771973 ] ] ] ] ], "bias": [ - 0.06534195691347122, - -0.13534505665302277, - 0.11579547822475433, - -0.004997386131435633 + -0.033017437905073166, + -0.039262499660253525, + 0.0744556114077568, + 0.06237300857901573 ], "expected_grad_bias": [ 64.0, From 89ae786d6087e34d58fa667a6b8cec37b47d54c4 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 00:24:57 +0800 Subject: [PATCH 097/128] feat: no_grad mode --- src/functions/base.ts | 4 +- src/functions/mixin.ts | 23 +++--- src/functions/ops.ts | 72 ++++++++++-------- src/grad_mode.ts | 42 +++++++++++ src/index.ts | 1 + src/tensor.ts | 6 +- test/grad_mode.test.js | 164 +++++++++++++++++++++++++++++++++++++++++ test/index.html | 1 + 8 files changed, 268 insertions(+), 45 deletions(-) create mode 100644 src/grad_mode.ts create mode 100644 test/grad_mode.test.js diff --git a/src/functions/base.ts b/src/functions/base.ts index d5d40191..f166f606 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -1,9 +1,11 @@ import { _unbroadcast } from '../broadcasting'; import { zeros_like } from '../creation'; +import { is_grad_enabled } from '../grad_mode'; import { Tensor } from '../tensor'; import { eventBus, getNextId, events } from '../util'; -function resultRequiresGrad(...args: (Tensor | number | number[] | boolean)[]): boolean { +export function resultRequiresGrad(...args: (Tensor | number | number[] | boolean)[]): boolean { + if (!is_grad_enabled()) return false; for (const arg of args) { if (arg instanceof Tensor && arg.requires_grad) { return true; diff --git a/src/functions/mixin.ts b/src/functions/mixin.ts index 59da22a8..cf8b64fe 100644 --- a/src/functions/mixin.ts +++ b/src/functions/mixin.ts @@ -4,7 +4,7 @@ import { _get_original_index, _pad_shape } from '../broadcasting'; -import { TorchFunction, BinaryFunction, UnaryFunction, nullOp } from './base'; +import { TorchFunction, BinaryFunction, UnaryFunction, nullOp, resultRequiresGrad } from './base'; import { registerOperation } from './registry'; import { _get_reduction_shape, _get_strides, _ravel_index, _unravel_index } from './util'; @@ -46,7 +46,7 @@ export function BinaryFunctionMixin( broadcast_shape, output_size ) as number[], - { requires_grad: a.requires_grad || b.requires_grad }, + { requires_grad: resultRequiresGrad(a, b) }, { operation: operation, shape: broadcast_shape } ); }; @@ -54,12 +54,13 @@ export function BinaryFunctionMixin( const result = { [opName]: class extends BinaryFunction { protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { + const rg = resultRequiresGrad(a, b); + if (rg) { this.saved_tensors = [a, b]; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - return forward_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); + return forward_tensor(a, b, rg ? this : null); } protected _backward(dz: Tensor): void { @@ -93,7 +94,7 @@ export function UnaryFunctionMixin( return new Tensor( kernel(a.data, output_size) as number[], - { requires_grad: a.requires_grad }, + { requires_grad: resultRequiresGrad(a) }, { operation: operation, shape: a.shape } ); }; @@ -101,11 +102,12 @@ export function UnaryFunctionMixin( const result = { [opName]: class extends UnaryFunction { protected _forward(a: Tensor): Tensor { - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return forward_tensor(a, a.requires_grad ? this : null); + return forward_tensor(a, rg ? this : null); } protected _backward(dz: Tensor): void { @@ -143,7 +145,8 @@ export function ReductionFunctionMixin( this.dim = dim; this.keepdim = keepdim; - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); @@ -193,8 +196,8 @@ export function ReductionFunctionMixin( return new Tensor( res_data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape: out_shape } + { requires_grad: rg }, + { operation: rg ? this : null, shape: out_shape } ); } diff --git a/src/functions/ops.ts b/src/functions/ops.ts index c68247d5..464bc281 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -5,7 +5,7 @@ import { _pad_shape, _unbroadcast } from '../broadcasting'; -import { TorchFunction, BinaryFunction, nullOp } from './base'; +import { TorchFunction, BinaryFunction, nullOp, resultRequiresGrad } from './base'; import * as functional from './functional'; import { registerOperation } from './registry'; import { ones } from '../creation'; @@ -135,7 +135,7 @@ function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = } return new Tensor( data, - { requires_grad: a.requires_grad }, + { requires_grad: resultRequiresGrad(a) }, { operation: operation, shape: a.shape } ); } @@ -143,13 +143,14 @@ function _powint_tensor(a: Tensor, n: number, operation: TorchFunction | null = class PowInt extends TorchFunction { private n: number; protected _forward(a: Tensor, n: number): Tensor { - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; this.n = n; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _powint_tensor(a, n, a.requires_grad ? this : null); + return _powint_tensor(a, n, rg ? this : null); } protected _backward(dz: Tensor): void { const [a] = this.saved_tensors; @@ -251,7 +252,8 @@ class Reshape extends TorchFunction { throw new Error('Shape mismatch: ' + a.shape + ' and ' + shape); } - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; } if (a.grad_fn) { @@ -262,8 +264,8 @@ class Reshape extends TorchFunction { return new Tensor( a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } + { requires_grad: rg }, + { operation: rg ? this : null, shape } ); } protected _backward(dz: Tensor) { @@ -278,7 +280,8 @@ registerOperation('reshape', Reshape); class Squeeze extends TorchFunction { protected _forward(a: Tensor, dim?: number) { - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; } if (a.grad_fn) { @@ -305,8 +308,8 @@ class Squeeze extends TorchFunction { return new Tensor( a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } + { requires_grad: rg }, + { operation: rg ? this : null, shape } ); } @@ -323,7 +326,8 @@ registerOperation('squeeze', Squeeze); class Unsqueeze extends TorchFunction { protected _forward(a: Tensor, dim: number) { - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; } if (a.grad_fn) { @@ -341,8 +345,8 @@ class Unsqueeze extends TorchFunction { return new Tensor( a.data, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape } + { requires_grad: rg }, + { operation: rg ? this : null, shape } ); } protected _backward(dz: Tensor) { @@ -357,7 +361,8 @@ registerOperation('unsqueeze', Unsqueeze); class Expand extends TorchFunction { protected _forward(a: Tensor, expanded_shape: number[]): Tensor { - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; } if (a.grad_fn) { @@ -380,8 +385,8 @@ class Expand extends TorchFunction { return new Tensor( outData, - { requires_grad: a.requires_grad }, - { operation: a.requires_grad ? this : null, shape: target_shape } + { requires_grad: rg }, + { operation: rg ? this : null, shape: target_shape } ); } @@ -519,7 +524,7 @@ function _transpose_tensor( return new Tensor( data, - { requires_grad: a.requires_grad }, + { requires_grad: resultRequiresGrad(a) }, { operation: operation, shape: output_shape } ); } @@ -527,13 +532,14 @@ class Transpose extends TorchFunction { private dim0: number; private dim1: number; protected _forward(a: Tensor, dim0: number, dim1: number): Tensor { - if (a.requires_grad) { + const rg = resultRequiresGrad(a); + if (rg) { this.saved_tensors = [a]; this.dim0 = dim0; this.dim1 = dim1; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); - return _transpose_tensor(a, dim0, dim1, this); + return _transpose_tensor(a, dim0, dim1, rg ? this : null); } protected _backward(dz: Tensor): void { const [a] = this.saved_tensors; @@ -606,7 +612,7 @@ function _matmul_tensor(a: Tensor, b: Tensor, operation: TorchFunction | null = return [new Tensor( data, - { requires_grad: a.requires_grad || b.requires_grad }, + { requires_grad: resultRequiresGrad(a, b) }, { operation: operation, shape: shape_after_removing_extra_dims } ), shape_after_removing_extra_dims]; } @@ -615,12 +621,13 @@ class Matmul extends BinaryFunction { private shape: number[]; protected _forward(a: Tensor, b: Tensor): Tensor { - if (a.requires_grad || b.requires_grad) { + const rg = resultRequiresGrad(a, b); + if (rg) { this.saved_tensors = [a, b]; } this.next_functions.push(a.grad_fn ? a.grad_fn : nullOp); this.next_functions.push(b.grad_fn ? b.grad_fn : nullOp); - const result = _matmul_tensor(a, b, a.requires_grad || b.requires_grad ? this : null); + const result = _matmul_tensor(a, b, rg ? this : null); this.shape = result[1]; return result[0]; } @@ -943,7 +950,8 @@ class Conv1dOp extends TorchFunction { dilation: number | number[] = 1, groups: number = 1 ): Tensor { - if (input.requires_grad || weight.requires_grad || bias?.requires_grad) { + const rg = resultRequiresGrad(input, weight, ...(bias ? [bias] : [])); + if (rg) { this.saved_tensors = [input, weight]; if (bias) this.saved_tensors.push(bias); } @@ -957,8 +965,8 @@ class Conv1dOp extends TorchFunction { this.groups = groups; const res = _convNd_forward(input, weight, bias, stride, padding, dilation, groups, 1); - res.requires_grad = input.requires_grad || weight.requires_grad || (bias?.requires_grad ?? false); - res.grad_fn = res.requires_grad ? this : null; + res.requires_grad = rg; + res.grad_fn = rg ? this : null; return res; } @@ -995,7 +1003,8 @@ class Conv2dOp extends TorchFunction { dilation: number | number[] = 1, groups: number = 1 ): Tensor { - if (input.requires_grad || weight.requires_grad || bias?.requires_grad) { + const rg = resultRequiresGrad(input, weight, ...(bias ? [bias] : [])); + if (rg) { this.saved_tensors = [input, weight]; if (bias) this.saved_tensors.push(bias); } @@ -1009,8 +1018,8 @@ class Conv2dOp extends TorchFunction { this.groups = groups; const res = _convNd_forward(input, weight, bias, stride, padding, dilation, groups, 2); - res.requires_grad = input.requires_grad || weight.requires_grad || (bias?.requires_grad ?? false); - res.grad_fn = res.requires_grad ? this : null; + res.requires_grad = rg; + res.grad_fn = rg ? this : null; return res; } @@ -1047,7 +1056,8 @@ class Conv3dOp extends TorchFunction { dilation: number | number[] = 1, groups: number = 1 ): Tensor { - if (input.requires_grad || weight.requires_grad || bias?.requires_grad) { + const rg = resultRequiresGrad(input, weight, ...(bias ? [bias] : [])); + if (rg) { this.saved_tensors = [input, weight]; if (bias) this.saved_tensors.push(bias); } @@ -1061,8 +1071,8 @@ class Conv3dOp extends TorchFunction { this.groups = groups; const res = _convNd_forward(input, weight, bias, stride, padding, dilation, groups, 3); - res.requires_grad = input.requires_grad || weight.requires_grad || (bias?.requires_grad ?? false); - res.grad_fn = res.requires_grad ? this : null; + res.requires_grad = rg; + res.grad_fn = rg ? this : null; return res; } diff --git a/src/grad_mode.ts b/src/grad_mode.ts new file mode 100644 index 00000000..3bf9b729 --- /dev/null +++ b/src/grad_mode.ts @@ -0,0 +1,42 @@ +/** + * Global gradient computation mode. + * + * When disabled, all operations behave as if no input requires grad, + * so no computation graph is built and no tensors are saved for backward. + */ +let _grad_enabled = true; + +export function is_grad_enabled(): boolean { + return _grad_enabled; +} + +/** + * Disable gradient computation. Returns the previous state + * so it can be restored later with `disable_no_grad(prev)`. + */ +export function enable_no_grad(): boolean { + const prev = _grad_enabled; + _grad_enabled = false; + return prev; +} + +/** + * Restore gradient computation to a previous state + * (as returned by `enable_no_grad`). + */ +export function disable_no_grad(prev: boolean): void { + _grad_enabled = prev; +} + +/** + * Execute `fn` with gradient computation disabled. + * The previous grad mode is always restored, even if `fn` throws. + */ +export function no_grad(fn: () => T): T { + const prev = enable_no_grad(); + try { + return fn(); + } finally { + disable_no_grad(prev); + } +} diff --git a/src/index.ts b/src/index.ts index a5815378..5c473a26 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ export * from './tensor'; +export { no_grad, enable_no_grad, disable_no_grad, is_grad_enabled } from './grad_mode'; export { TorchFunction, AccumulateGrad } from './functions/base'; export * from './functions/ops'; diff --git a/src/tensor.ts b/src/tensor.ts index ed3f2c7f..c79d6748 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,4 +1,4 @@ -import { AccumulateGrad, TorchFunction } from './functions/base'; +import { AccumulateGrad, TorchFunction, resultRequiresGrad } from './functions/base'; import { getOperation, getOperationCache } from './functions/registry'; import { getNextId, eventBus, events } from './util'; @@ -120,7 +120,7 @@ export class Tensor { } private _executeUnaryOp(opName: string): Tensor { - const operation = this.requires_grad ? new (getOperation(opName))() : getOperationCache(opName); + const operation = resultRequiresGrad(this) ? new (getOperation(opName))() : getOperationCache(opName); return operation.forward(this); } @@ -128,7 +128,7 @@ export class Tensor { if (typeof other == 'number') { other = new Tensor(other); } - const operation = this.requires_grad || other.requires_grad ? new (getOperation(opName))() : getOperationCache(opName); + const operation = resultRequiresGrad(this, other) ? new (getOperation(opName))() : getOperationCache(opName); return operation.forward(this, other); } diff --git a/test/grad_mode.test.js b/test/grad_mode.test.js new file mode 100644 index 00000000..e6ca5e2d --- /dev/null +++ b/test/grad_mode.test.js @@ -0,0 +1,164 @@ +import { assert } from 'chai'; +import { Tensor, no_grad, enable_no_grad, disable_no_grad, is_grad_enabled } from 'torch'; + +describe('Grad Mode', () => { + afterEach(() => { + // Safety: ensure grad mode is always restored after each test + if (!is_grad_enabled()) disable_no_grad(true); + }); + + describe('is_grad_enabled', () => { + it('should be enabled by default', () => { + assert.isTrue(is_grad_enabled()); + }); + }); + + describe('no_grad', () => { + it('should disable gradient tracking inside callback', () => { + const x = new Tensor([2.0], { requires_grad: true }); + const y = no_grad(() => x.mul(x)); + + assert.strictEqual(y.item(), 4.0); + assert.isFalse(y.requires_grad); + assert.isNull(y.grad_fn); + }); + + it('should re-enable gradient tracking after callback', () => { + no_grad(() => {}); + assert.isTrue(is_grad_enabled()); + }); + + it('should re-enable gradient tracking even if callback throws', () => { + try { + no_grad(() => { throw new Error('boom'); }); + } catch (e) { + // expected + } + assert.isTrue(is_grad_enabled()); + }); + + it('should return the value from the callback', () => { + const result = no_grad(() => 42); + assert.strictEqual(result, 42); + }); + + it('should nest correctly', () => { + assert.isTrue(is_grad_enabled()); + no_grad(() => { + assert.isFalse(is_grad_enabled()); + no_grad(() => { + assert.isFalse(is_grad_enabled()); + }); + // still disabled after inner no_grad returns + assert.isFalse(is_grad_enabled()); + }); + assert.isTrue(is_grad_enabled()); + }); + + it('should not build computation graph for unary ops', () => { + const x = new Tensor([2.0], { requires_grad: true }); + const y = no_grad(() => x.exp()); + + assert.isFalse(y.requires_grad); + assert.isNull(y.grad_fn); + }); + + it('should not build computation graph for chained ops', () => { + const x = new Tensor([3.0], { requires_grad: true }); + const y = no_grad(() => x.mul(x).add(x)); + + assert.closeTo(y.item(), 12.0, 1e-6); + assert.isFalse(y.requires_grad); + assert.isNull(y.grad_fn); + }); + + it('should not accumulate gradients for operations inside no_grad', () => { + const x = new Tensor([2.0], { requires_grad: true }); + + // Normal forward + backward + const y = x.mul(x); + y.backward(); + assert.strictEqual(x.grad.item(), 4.0); + + // Operations inside no_grad should not affect grad + x.grad = null; + const z = no_grad(() => x.mul(new Tensor(100.0))); + // z has no graph, so backward would be a no-op + assert.isFalse(z.requires_grad); + }); + }); + + describe('enable_no_grad / disable_no_grad', () => { + it('enable_no_grad should disable grad and return previous state', () => { + assert.isTrue(is_grad_enabled()); + const prev = enable_no_grad(); + assert.isTrue(prev); // was enabled + assert.isFalse(is_grad_enabled()); + disable_no_grad(prev); + assert.isTrue(is_grad_enabled()); + }); + + it('should work for pyodide-style usage pattern', () => { + // Simulate: python side calls enable_no_grad, does work, calls disable_no_grad + const prev = enable_no_grad(); + + const x = new Tensor([5.0], { requires_grad: true }); + const y = x.mul(x); + assert.isFalse(y.requires_grad); + assert.isNull(y.grad_fn); + + disable_no_grad(prev); + assert.isTrue(is_grad_enabled()); + + // After restoring, grad should work again + const a = new Tensor([3.0], { requires_grad: true }); + const b = a.mul(a); + assert.isTrue(b.requires_grad); + assert.isNotNull(b.grad_fn); + }); + + it('should handle nested enable/disable correctly', () => { + const prev1 = enable_no_grad(); + assert.isFalse(is_grad_enabled()); + + const prev2 = enable_no_grad(); + assert.isFalse(is_grad_enabled()); + + disable_no_grad(prev2); // prev2 is false, still disabled + assert.isFalse(is_grad_enabled()); + + disable_no_grad(prev1); // prev1 is true, now enabled + assert.isTrue(is_grad_enabled()); + }); + }); + + describe('interaction with requires_grad', () => { + it('tensors created with requires_grad=true keep the flag, but ops do not track', () => { + const x = new Tensor([2.0], { requires_grad: true }); + // x.requires_grad is an intrinsic property of the tensor, not affected by grad mode + assert.isTrue(x.requires_grad); + + const y = no_grad(() => { + // x still says requires_grad=true, but the operation should not build a graph + return x.mul(x); + }); + + assert.isFalse(y.requires_grad); + }); + + it('backward still works on tensors created before no_grad', () => { + // Build graph normally + const x = new Tensor([3.0], { requires_grad: true }); + const y = x.mul(x); // y = 9, dy/dx = 6 + + // Enter no_grad for some unrelated work + no_grad(() => { + const _ = x.add(new Tensor(100.0)); // no graph built + }); + + // Original graph is intact + y.backward(); + assert.strictEqual(x.grad.item(), 6.0); + }); + }); +}); diff --git a/test/index.html b/test/index.html index 150979e7..dc286ba8 100644 --- a/test/index.html +++ b/test/index.html @@ -32,6 +32,7 @@ import "./custom_operations.test.js" import "./event_listener.test.js" import "./functional.test.js"; + import "./grad_mode.test.js"; import "./loss.test.js"; import "./module.test.js"; import "./nn_functional.test.js"; From cac25dbd9556bf7992a3eec7f5ce2ca187e4c907 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 02:35:09 +0800 Subject: [PATCH 098/128] refactor: remove unused vars --- eslint.config.mjs | 2 +- src/functions/base.ts | 4 ++-- src/functions/mixin.ts | 4 ++-- src/functions/ops.ts | 31 +++++++++++++++---------------- src/nn/functional.ts | 15 --------------- 5 files changed, 20 insertions(+), 36 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index a175a5ee..784224be 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -10,7 +10,7 @@ export default defineConfig(eslint.configs.recommended, tseslint.configs.recomme 'warn', { argsIgnorePattern: '^_', - varsIgnorePattern: '^_', + varsIgnorePattern: '(^_)|(^[A-Z])', caughtErrorsIgnorePattern: '^_', ignoreRestSiblings: true } diff --git a/src/functions/base.ts b/src/functions/base.ts index f166f606..316e6da6 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -58,10 +58,10 @@ abstract class TorchFunction { } class NullOp extends TorchFunction { - protected _forward(...args: (Tensor | number | number[])[]): Tensor { + protected _forward(..._args: (Tensor | number | number[])[]): Tensor { throw new Error('NullOp should not be called'); } - protected _backward(dz: Tensor): void { + protected _backward(_dz: Tensor): void { return; } } diff --git a/src/functions/mixin.ts b/src/functions/mixin.ts index cf8b64fe..ec973e95 100644 --- a/src/functions/mixin.ts +++ b/src/functions/mixin.ts @@ -10,7 +10,7 @@ import { _get_reduction_shape, _get_strides, _ravel_index, _unravel_index } from export function BinaryFunctionMixin( operation: (a: number[], b: number[], a_index: number, b_index: number) => number, - backward_operations: (a, b, aFn, bFn, dz) => void, + backward_operations: (a?: Tensor, b?: Tensor, aFn?: TorchFunction, bFn?: TorchFunction, dz?: Tensor) => void, opName: string | null = null ): typeof BinaryFunction { const kernel = ( @@ -79,7 +79,7 @@ export function BinaryFunctionMixin( export function UnaryFunctionMixin( operation: (a: number[], x: number) => number, - backward_operations: (a, aFn, dz) => void, + backward_operations: (a?: Tensor, aFn?: TorchFunction, dz?: Tensor) => void, opName: string | null = null ): typeof UnaryFunction { const kernel = (a: number[], output_size: number) => { diff --git a/src/functions/ops.ts b/src/functions/ops.ts index 464bc281..c25b6c80 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -24,14 +24,14 @@ function broadcast(tensor: Tensor, result_shape: number[]): Tensor { // debug operations const __Left_index__ = BinaryFunctionMixin( - (a: number[], b: number[], a_index: number, b_index: number) => a_index, - (a, b, aFn, bFn, dz) => { }, + (a: number[], b: number[], a_index: number, _b_index: number) => a_index, + () => { }, "__left_index__" ); const __Right_index__ = BinaryFunctionMixin( - (a: number[], b: number[], a_index: number, b_index: number) => b_index, - (a, b, aFn, bFn, dz) => { }, + (a: number[], b: number[], _a_index: number, b_index: number) => b_index, + () => { }, "__right_index__" ); @@ -39,7 +39,7 @@ const __Right_index__ = BinaryFunctionMixin( const Add = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] + b[b_index], - (a, b, aFn, bFn, dz) => { + (_a, _b, aFn, bFn, dz) => { aFn.backward(dz); bFn.backward(dz); }, @@ -48,7 +48,7 @@ const Add = BinaryFunctionMixin( const Sub = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] - b[b_index], - (a, b, aFn, bFn, dz) => { + (_a, _b, aFn, bFn, dz) => { aFn.backward(dz); bFn.backward(dz.mul(new Tensor(-1))); }, @@ -96,7 +96,7 @@ const Pow = BinaryFunctionMixin( const Fmod = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => a[a_index] % b[b_index], - (a, b, aFn, bFn, dz) => { + (_a, _b, aFn, _bFn, dz) => { aFn.backward(dz); }, "fmod" @@ -207,7 +207,7 @@ const Abs = UnaryFunctionMixin( const Sign = UnaryFunctionMixin( (a: number[], x: number) => Math.sign(a[x]), - (a, aFn, dz) => { + (_a, aFn) => { aFn.backward(0); }, "sign" @@ -272,7 +272,6 @@ class Reshape extends TorchFunction { const [a] = this.saved_tensors; const [aFn] = this.next_functions; - // backward_operations: aFn.backward(dz.reshape(a.shape)); } } @@ -542,7 +541,7 @@ class Transpose extends TorchFunction { return _transpose_tensor(a, dim0, dim1, rg ? this : null); } protected _backward(dz: Tensor): void { - const [a] = this.saved_tensors; + // const [a] = this.saved_tensors; const dim0 = this.dim0; const dim1 = this.dim1; const [aFn] = this.next_functions; @@ -1099,36 +1098,36 @@ registerOperation('conv3d', Conv3dOp); const Lt = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] < b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => { }, + () => { }, "lt" ); const Gt = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] > b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => { }, + () => { }, "gt" ); const Le = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] <= b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => { }, + () => { }, "le" ); const Ge = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] >= b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => { }, + () => { }, "ge" ); const Eq = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] == b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => { }, + () => { }, "eq" ); const Ne = BinaryFunctionMixin( (a: number[], b: number[], a_index: number, b_index: number) => (a[a_index] != b[b_index]) ? 1 : 0, - (a, b, aFn, bFn) => { }, + () => { }, "ne" ); diff --git a/src/nn/functional.ts b/src/nn/functional.ts index 7c20c632..cd21f648 100644 --- a/src/nn/functional.ts +++ b/src/nn/functional.ts @@ -19,21 +19,6 @@ function generate_unary_function(opname: string) { }; } -function generate_binary_function(opname: string) { - return (a: Tensor | number, b: Tensor | number) => { - if (typeof a == 'number') { - a = new Tensor(a); - } - - if (typeof b == 'number') { - b = new Tensor(b); - } - - const operation = new (getOperation(opname))(); - return operation.forward(a, b); - }; -} - export const relu = generate_unary_function('relu'); export const sigmoid = generate_unary_function('sigmoid'); From 4686463786e0c8773606447bfe8a8cef73ef006a Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 02:40:54 +0800 Subject: [PATCH 099/128] fix: TorchFunction backward arb type --- src/functions/base.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/base.ts b/src/functions/base.ts index 316e6da6..da78cb90 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -21,7 +21,7 @@ abstract class TorchFunction { public _retained_tensors: Tensor[] = []; protected abstract _forward(...args: (Tensor | number | number[] | boolean)[]): Tensor; - protected abstract _backward(dz: Tensor): void; + protected abstract _backward(dz: Tensor | number): void; forward(...args: (Tensor | number | number[] | boolean)[]): Tensor { const requires_grad = resultRequiresGrad(...args); @@ -44,7 +44,7 @@ abstract class TorchFunction { return result; } - backward(dz: Tensor): void { + backward(dz: Tensor | number): void { eventBus.dispatchEvent(new CustomEvent(events.OPERATION_BEFORE_BACKWARD, { detail: { operation: this, dz } })); for (const x of this._retained_tensors) { if (!x.grad) { From f2830fa7b72982b44faf3006cf109e038a8cae2d Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 12:29:51 +0800 Subject: [PATCH 100/128] feat: export --- scripts/generate_tests.py | 92 ++++++++++ src/export.ts | 310 ++++++++++++++++++++++++++++++++++ src/functions/base.ts | 1 + src/functions/functional.ts | 8 +- src/functions/registry.ts | 21 ++- src/index.ts | 5 +- src/nn/base.ts | 13 ++ src/nn/functional.ts | 6 +- src/tensor.ts | 8 +- test/export.test.ts | 23 +++ test/generated.test.js | 90 ++++++++++ test/testcases.gen.js | 326 ++++++++++++++++++++++++++++++++++++ 12 files changed, 888 insertions(+), 15 deletions(-) create mode 100644 src/export.ts create mode 100644 test/export.test.ts diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index d7edb08f..6c9fe887 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -312,6 +312,97 @@ def generate_conv_tests(): tests.append(test_data) return tests +def generate_export_tests(): + tests = [] + + def extract_nodes(ep): + nodes = [] + for node in ep.graph.nodes: + nd = { + 'op': node.op, + 'name': node.name, + 'target': str(node.target), + } + nd['args'] = [] + for a in node.args: + if isinstance(a, torch.fx.Node): + nd['args'].append(a.name) + elif isinstance(a, tuple): + nd['args'].append([n.name if isinstance(n, torch.fx.Node) else str(n) for n in a]) + else: + nd['args'].append(str(a)) + if 'val' in node.meta: + v = node.meta['val'] + if isinstance(v, torch.Tensor): + nd['val_shape'] = list(v.shape) + nodes.append(nd) + return nodes + + def extract_specs(ep): + sig = ep.graph_signature + input_specs = [{'kind': s.kind.name, 'name': s.arg.name if hasattr(s.arg, 'name') else str(s.arg)} for s in sig.input_specs] + output_specs = [{'kind': s.kind.name, 'name': s.arg.name if hasattr(s.arg, 'name') else str(s.arg)} for s in sig.output_specs] + return input_specs, output_specs + + # Test 1: Simple Sequential(Linear, ReLU) + torch.manual_seed(42) + model1 = torch.nn.Sequential( + torch.nn.Linear(3, 2), + torch.nn.ReLU() + ) + x1 = torch.randn(2, 3) + ep1 = torch.export.export(model1, (x1,)) + + nodes1 = extract_nodes(ep1) + input_specs1, output_specs1 = extract_specs(ep1) + + tests.append({ + 'test_name': 'linear_relu', + 'model_type': 'LinearReLU', + 'input': x1.detach().numpy().tolist(), + 'weight': model1[0].weight.detach().numpy().tolist(), + 'bias': model1[0].bias.detach().numpy().tolist(), + 'in_features': 3, + 'out_features': 2, + 'expected_nodes': nodes1, + 'expected_input_specs': input_specs1, + 'expected_output_specs': output_specs1, + }) + + # Test 2: Sequential(Linear, ReLU, Linear, Sigmoid) + torch.manual_seed(42) + model2 = torch.nn.Sequential( + torch.nn.Linear(4, 3), + torch.nn.ReLU(), + torch.nn.Linear(3, 2), + torch.nn.Sigmoid() + ) + x2 = torch.randn(2, 4) + ep2 = torch.export.export(model2, (x2,)) + + nodes2 = extract_nodes(ep2) + input_specs2, output_specs2 = extract_specs(ep2) + + tests.append({ + 'test_name': 'two_layer', + 'model_type': 'TwoLayer', + 'input': x2.detach().numpy().tolist(), + 'linear1_weight': model2[0].weight.detach().numpy().tolist(), + 'linear1_bias': model2[0].bias.detach().numpy().tolist(), + 'linear2_weight': model2[2].weight.detach().numpy().tolist(), + 'linear2_bias': model2[2].bias.detach().numpy().tolist(), + 'linear1_in': 4, + 'linear1_out': 3, + 'linear2_in': 3, + 'linear2_out': 2, + 'expected_nodes': nodes2, + 'expected_input_specs': input_specs2, + 'expected_output_specs': output_specs2, + }) + + return tests + + if __name__ == "__main__": suite = { "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, @@ -323,6 +414,7 @@ def generate_conv_tests(): "optimizers": generate_optimizer_tests(), "expand": generate_expand_tests(), "conv": generate_conv_tests(), + "export": generate_export_tests(), } print("export const testData = ", end="") diff --git a/src/export.ts b/src/export.ts new file mode 100644 index 00000000..73c4a910 --- /dev/null +++ b/src/export.ts @@ -0,0 +1,310 @@ +import { Tensor } from './tensor'; +import { TorchFunction } from './functions/base'; +import { Module } from './nn/base'; +import { no_grad } from './grad_mode'; +import { eventBus, events } from './util'; + +/** + * A graph node in the exported program, matching PyTorch's FX node format. + */ +export interface GraphNode { + /** Node type: 'placeholder' for inputs/params, 'call_function' for ops, 'output' for result */ + op: 'placeholder' | 'call_function' | 'output'; + /** Unique name for this node (e.g. "add", "linear_1") */ + name: string; + /** Operation target (e.g. "aten.add.default") */ + target: string; + /** References to input node names */ + args: (string | string[])[]; + /** Output tensor shape, if available */ + val_shape?: number[]; +} + +export interface InputSpec { + kind: 'PARAMETER' | 'USER_INPUT'; + name: string; + target?: string; +} + +export interface OutputSpec { + kind: 'USER_OUTPUT'; + name: string; +} + +export interface GraphSignature { + input_specs: InputSpec[]; + output_specs: OutputSpec[]; +} + +/** + * Maps our internal op names to PyTorch's aten operator names. + * See: https://docs.pytorch.org/docs/2.10/user_guide/torch_compiler/torch.compiler_ir.html + */ +export const _atenMap: Record = { + 'add': 'aten.add.Tensor', + 'sub': 'aten.sub.Tensor', + 'mul': 'aten.mul.Tensor', + 'div': 'aten.div.Tensor', + 'pow': 'aten.pow.Tensor_Tensor', + 'powint': 'aten.pow.Tensor_Scalar', + 'fmod': 'aten.fmod.Tensor', + 'maximum': 'aten.maximum.default', + 'minimum': 'aten.minimum.default', + 'log': 'aten.log.default', + 'sqrt': 'aten.sqrt.default', + 'exp': 'aten.exp.default', + 'square': 'aten.square.default', + 'abs': 'aten.abs.default', + 'sign': 'aten.sign.default', + 'neg': 'aten.neg.default', + 'reciprocal': 'aten.reciprocal.default', + 'nan_to_num': 'aten.nan_to_num.default', + 'reshape': 'aten.reshape.default', + 'squeeze': 'aten.squeeze.dim', + 'unsqueeze': 'aten.unsqueeze.default', + 'expand': 'aten.expand.default', + 'sin': 'aten.sin.default', + 'cos': 'aten.cos.default', + 'tan': 'aten.tan.default', + 'sum': 'aten.sum.default', + 'mean': 'aten.mean.default', + 'min': 'aten.min.default', + 'max': 'aten.max.default', + 'transpose': 'aten.transpose.int', + 'matmul': 'aten.matmul.default', + 'relu': 'aten.relu.default', + 'sigmoid': 'aten.sigmoid.default', + 'lt': 'aten.lt.Tensor', + 'gt': 'aten.gt.Tensor', + 'le': 'aten.le.Tensor', + 'ge': 'aten.ge.Tensor', + 'eq': 'aten.eq.Tensor', + 'ne': 'aten.ne.Tensor', + 'conv1d': 'aten.conv1d.default', + 'conv2d': 'aten.conv2d.default', + 'conv3d': 'aten.conv3d.default', + 'linear': 'aten.linear.default', +}; + +/** + * Maps our internal op names to PyTorch's aten operator names with default value. + */ +function toAtenTarget(opName: string): string { + return _atenMap[opName] || `aten.${opName}.default`; +} + +/** + * Manages unique node name generation with PyTorch-style deduplication. + * E.g. first "add" -> "add", second "add" -> "add_1" + */ +class NameGenerator { + private counts = new Map(); + + generate(baseName: string): string { + const count = this.counts.get(baseName) || 0; + this.counts.set(baseName, count + 1); + return count === 0 ? baseName : `${baseName}_${count}`; + } +} + +/** + * An exported program, matching PyTorch's ExportedProgram structure. + */ +export class ExportedProgram { + constructor( + public graph: GraphNode[], + public graph_signature: GraphSignature, + public parameters: Map + ) { } + + toString(): string { + const lines: string[] = ['ExportedProgram:']; + + // Format forward signature + const inputArgs = this.graph + .filter(n => n.op === 'placeholder') + .map(n => { + const shape = n.val_shape ? JSON.stringify(n.val_shape) : '?'; + return `${n.name}: "${shape}"`; + }) + .join(', '); + lines.push(` class GraphModule(torch.nn.Module):`); + lines.push(` def forward(self, ${inputArgs}):`); + + // Operations + for (const node of this.graph) { + if (node.op === 'call_function') { + const args = node.args.join(', '); + lines.push(` ${node.name} = ${node.target}(${args})`); + } else if (node.op === 'output') { + lines.push(` return (${node.args.join(', ')},)`); + } + } + + lines.push(''); + lines.push('Graph signature:'); + lines.push(' # inputs'); + for (const spec of this.graph_signature.input_specs) { + const target = spec.target ? ` target='${spec.target}'` : ''; + lines.push(` ${spec.name}: ${spec.kind}${target}`); + } + lines.push(' # outputs'); + for (const spec of this.graph_signature.output_specs) { + lines.push(` ${spec.name}: ${spec.kind}`); + } + + return lines.join('\n'); + } +} + +/** + * Export a module's forward pass as an ExportedProgram. + * + * This traces the module's forward() with the given sample inputs + * and captures the computation graph. Similar to PyTorch's torch.export.export(). + * + * Named `export_` to avoid conflict with the JavaScript `export` keyword. + * + * @param module The nn.Module to export + * @param sampleInputs Sample input tensors for tracing + * @returns An ExportedProgram containing the traced graph + */ +export function export_( + module: Module, + sampleInputs: Tensor[] +): ExportedProgram { + const graph: GraphNode[] = []; + const nameGen = new NameGenerator(); + + // Map tensor IDs to their graph node names + const tensorIdToName = new Map(); + + // 1. Create placeholder nodes for parameters + const namedParams = module.named_parameters(); + const paramTensorIds = new Set(); + const inputSpecs: InputSpec[] = []; + + for (const [paramPath, param] of namedParams) { + // Convert "linear.weight" -> "p_linear_weight" (PyTorch convention) + const placeholderName = 'p_' + paramPath.replace(/\./g, '_'); + const nodeName = nameGen.generate(placeholderName); + tensorIdToName.set(param.id, nodeName); + paramTensorIds.add(param.id); + + graph.push({ + op: 'placeholder', + name: nodeName, + target: nodeName, + args: [], + val_shape: param.shape, + }); + + inputSpecs.push({ + kind: 'PARAMETER', + name: nodeName, + target: paramPath, + }); + } + + // 2. Create placeholder nodes for user inputs + for (let i = 0; i < sampleInputs.length; i++) { + const baseName = 'input'; + const nodeName = nameGen.generate(baseName); + tensorIdToName.set(sampleInputs[i].id, nodeName); + + graph.push({ + op: 'placeholder', + name: nodeName, + target: nodeName, + args: [], + val_shape: sampleInputs[i].shape, + }); + + inputSpecs.push({ + kind: 'USER_INPUT', + name: nodeName, + }); + } + + // 3. Trace the forward pass, recording operations + const handler = (e: CustomEvent) => { + const { operation, args, result } = e.detail as { + operation: TorchFunction; + args: (Tensor | number | number[] | boolean)[]; + result: Tensor; + }; + + const opName = operation.opName; + if (!opName) return; // Skip if no opName (shouldn't happen) + + // Build arg references + const nodeArgs: (string | string[])[] = []; + for (const arg of args) { + if (arg instanceof Tensor) { + const name = tensorIdToName.get(arg.id); + if (name) { + nodeArgs.push(name); + } + // If not found, it's an intermediate constant — skip + } + // Numbers and arrays are non-tensor args; we don't include them + // in the graph node args to match PyTorch's behavior for simple cases + } + + // Generate node name from opName + const nodeName = nameGen.generate(opName); + tensorIdToName.set(result.id, nodeName); + + graph.push({ + op: 'call_function', + name: nodeName, + target: toAtenTarget(opName), + args: nodeArgs, + val_shape: result.shape, + }); + }; + + eventBus.addEventListener( + events.OPERATION_AFTER_FORWARD, + handler as EventListener + ); + + let output: Tensor; + try { + output = no_grad(() => module.forward(...sampleInputs)); + } finally { + eventBus.removeEventListener( + events.OPERATION_AFTER_FORWARD, + handler as EventListener + ); + } + + // 4. Add output node + const outputName = tensorIdToName.get(output.id) || 'output'; + graph.push({ + op: 'output', + name: 'output', + target: 'output', + args: [outputName], + }); + + const outputSpecs: OutputSpec[] = [{ + kind: 'USER_OUTPUT', + name: outputName, + }]; + + // 5. Collect parameters + const parameters = new Map(); + for (const [paramPath, param] of namedParams) { + parameters.set(paramPath, { + data: [...param.data], + shape: [...param.shape], + }); + } + + return new ExportedProgram( + graph, + { input_specs: inputSpecs, output_specs: outputSpecs }, + parameters + ); +} diff --git a/src/functions/base.ts b/src/functions/base.ts index da78cb90..eeec3331 100644 --- a/src/functions/base.ts +++ b/src/functions/base.ts @@ -16,6 +16,7 @@ export function resultRequiresGrad(...args: (Tensor | number | number[] | boolea abstract class TorchFunction { public id: number = getNextId(); + public opName: string = ''; public next_functions: TorchFunction[] = []; public saved_tensors: Tensor[] = []; public _retained_tensors: Tensor[] = []; diff --git a/src/functions/functional.ts b/src/functions/functional.ts index 9eb40cab..b7a8f98d 100644 --- a/src/functions/functional.ts +++ b/src/functions/functional.ts @@ -1,9 +1,9 @@ import { Tensor } from '../tensor'; -import { getOperation } from './registry'; +import { createOperation } from './registry'; function generate_function(opname: string) { return (...args: (Tensor | number)[]) => { - const operation = new (getOperation(opname))(); + const operation = createOperation(opname); return operation.forward(...args); }; } @@ -14,7 +14,7 @@ function generate_unary_function(opname: string) { a = new Tensor(a); } - const operation = new (getOperation(opname))(); + const operation = createOperation(opname); return operation.forward(a); }; } @@ -29,7 +29,7 @@ function generate_binary_function(opname: string) { b = new Tensor(b); } - const operation = new (getOperation(opname))(); + const operation = createOperation(opname); return operation.forward(a, b); }; } diff --git a/src/functions/registry.ts b/src/functions/registry.ts index dd93e95a..c4f82271 100644 --- a/src/functions/registry.ts +++ b/src/functions/registry.ts @@ -8,7 +8,7 @@ export function registerOperation(name: string, func: TorchFunctionConstructor) operations.set(name, func); } -export function getOperation(name: string): TorchFunctionConstructor { +function getOperation(name: string): TorchFunctionConstructor { const func = operations.get(name); if (!func) { throw new Error(`Operation '${name}' is not registered.`); @@ -16,11 +16,26 @@ export function getOperation(name: string): TorchFunctionConstructor { return func; } +export function _getAllOperationNames(): Iterable { + return operations.keys(); +} + export function getOperationCache(name: string): TorchFunction { const operation = operations_cache.get(name); if (!operation) { - operations_cache.set(name, new (getOperation(name))()); - return operations_cache.get(name)!; + const op = new (getOperation(name))(); + op.opName = name; + operations_cache.set(name, op); + return op; } return operation; } + +/** + * Create a new operation instance with its opName set. + */ +export function createOperation(name: string): TorchFunction { + const op = new (getOperation(name))(); + op.opName = name; + return op; +} diff --git a/src/index.ts b/src/index.ts index 5c473a26..6ebd9675 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -export * from './tensor'; +export { Tensor, TypedArray, NestedNumberArray } from './tensor'; export { no_grad, enable_no_grad, disable_no_grad, is_grad_enabled } from './grad_mode'; export { TorchFunction, AccumulateGrad } from './functions/base'; @@ -12,3 +12,6 @@ export * as nn from './nn/index'; export * as optim from './optim/index'; export { eventBus, events } from './util'; + +export { export_, ExportedProgram } from './export'; +export type { GraphNode, InputSpec, OutputSpec, GraphSignature } from './export'; diff --git a/src/nn/base.ts b/src/nn/base.ts index 9af70bd5..c4b58c44 100644 --- a/src/nn/base.ts +++ b/src/nn/base.ts @@ -55,6 +55,19 @@ export abstract class Module { } return params; } + + public named_parameters(prefix: string = ''): [string, Parameter][] { + const result: [string, Parameter][] = []; + for (const [name, param] of Object.entries(this._parameters)) { + const fullName = prefix ? `${prefix}.${name}` : name; + result.push([fullName, param]); + } + for (const [name, module] of Object.entries(this._modules)) { + const fullName = prefix ? `${prefix}.${name}` : name; + result.push(...module.named_parameters(fullName)); + } + return result; + } } export class Sequential extends Module { diff --git a/src/nn/functional.ts b/src/nn/functional.ts index cd21f648..b198a394 100644 --- a/src/nn/functional.ts +++ b/src/nn/functional.ts @@ -1,9 +1,9 @@ import { Tensor } from "../tensor"; -import { getOperation } from "../functions/registry"; +import { createOperation } from "../functions/registry"; function generate_function(opname: string) { return (...args: (Tensor | number | number[] | null)[]) => { - const operation = new (getOperation(opname))(); + const operation = createOperation(opname); return operation.forward(...args); }; } @@ -14,7 +14,7 @@ function generate_unary_function(opname: string) { a = new Tensor(a); } - const operation = new (getOperation(opname))(); + const operation = createOperation(opname); return operation.forward(a); }; } diff --git a/src/tensor.ts b/src/tensor.ts index c79d6748..841d1fbb 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -1,5 +1,5 @@ import { AccumulateGrad, TorchFunction, resultRequiresGrad } from './functions/base'; -import { getOperation, getOperationCache } from './functions/registry'; +import { getOperationCache, createOperation } from './functions/registry'; import { getNextId, eventBus, events } from './util'; /* @@ -120,7 +120,7 @@ export class Tensor { } private _executeUnaryOp(opName: string): Tensor { - const operation = resultRequiresGrad(this) ? new (getOperation(opName))() : getOperationCache(opName); + const operation = resultRequiresGrad(this) ? createOperation(opName) : getOperationCache(opName); return operation.forward(this); } @@ -128,12 +128,12 @@ export class Tensor { if (typeof other == 'number') { other = new Tensor(other); } - const operation = resultRequiresGrad(this, other) ? new (getOperation(opName))() : getOperationCache(opName); + const operation = resultRequiresGrad(this, other) ? createOperation(opName) : getOperationCache(opName); return operation.forward(this, other); } private _executeOpRaw(opName: string, ...args: any[]): Tensor { - const operation = new (getOperation(opName))(); + const operation = createOperation(opName); return operation.forward(this, ...args); } diff --git a/test/export.test.ts b/test/export.test.ts new file mode 100644 index 00000000..167aba49 --- /dev/null +++ b/test/export.test.ts @@ -0,0 +1,23 @@ +import { assert } from 'chai'; +import { _atenMap } from '../src/export'; +import { _getAllOperationNames } from '../src/functions/registry'; + +// Import torch to trigger operation registration side effects +import 'torch'; + +describe('Export', () => { + // List from https://docs.pytorch.org/docs/2.10/user_guide/torch_compiler/torch.compiler_ir.html + + const EXCLUDED_OPERATIONS = new Set([ + "__left_index__", + "__right_index__", + ]); + + it('has all supported operations', () => { + for (const opName of _getAllOperationNames()) { + assert.isTrue(opName in _atenMap || EXCLUDED_OPERATIONS.has(opName), + `Missing aten mapping for operation: ${opName}. ` + + `Please add it in export.ts or exclude it in export.test.ts`); + } + }); +}); diff --git a/test/generated.test.js b/test/generated.test.js index fe6f90fe..9f4752e1 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -220,4 +220,94 @@ describe('Automated Tests', () => { }); }); }); + describe('Export', () => { + testData.export?.forEach(test => { + it(`export_${test.test_name}`, () => { + let model; + + if (test.model_type === 'LinearReLU') { + const linear = new torch.nn.Linear(test.in_features, test.out_features); + linear.weight = new Tensor(test.weight, { requires_grad: true }); + linear.bias = new Tensor(test.bias, { requires_grad: true }); + const relu = new torch.nn.ReLU(); + model = new torch.nn.Sequential(linear, relu); + } else if (test.model_type === 'TwoLayer') { + const linear1 = new torch.nn.Linear(test.linear1_in, test.linear1_out); + linear1.weight = new Tensor(test.linear1_weight, { requires_grad: true }); + linear1.bias = new Tensor(test.linear1_bias, { requires_grad: true }); + const relu = new torch.nn.ReLU(); + const linear2 = new torch.nn.Linear(test.linear2_in, test.linear2_out); + linear2.weight = new Tensor(test.linear2_weight, { requires_grad: true }); + linear2.bias = new Tensor(test.linear2_bias, { requires_grad: true }); + const sigmoid = new torch.nn.Sigmoid(); + model = new torch.nn.Sequential(linear1, relu, linear2, sigmoid); + } + + const x = new Tensor(test.input); + const ep = torch.export_(model, [x]); + + // Verify graph structure: must have placeholder, call_function, and output nodes + const placeholders = ep.graph.filter(n => n.op === 'placeholder'); + const callFunctions = ep.graph.filter(n => n.op === 'call_function'); + const outputs = ep.graph.filter(n => n.op === 'output'); + + assert.isAbove(placeholders.length, 0, 'Should have placeholder nodes'); + assert.isAbove(callFunctions.length, 0, 'Should have call_function nodes'); + assert.equal(outputs.length, 1, 'Should have exactly one output node'); + + // Verify all call_function nodes have aten.* targets + for (const node of callFunctions) { + assert.match(node.target, /^aten\./, `Target should start with aten.: ${node.target}`); + } + + // Verify graph signature matches PyTorch's + // Input specs: parameters should be PARAMETER, user inputs should be USER_INPUT + const expectedParamSpecs = test.expected_input_specs.filter(s => s.kind === 'PARAMETER'); + const expectedUserSpecs = test.expected_input_specs.filter(s => s.kind === 'USER_INPUT'); + + const actualParamSpecs = ep.graph_signature.input_specs.filter(s => s.kind === 'PARAMETER'); + const actualUserSpecs = ep.graph_signature.input_specs.filter(s => s.kind === 'USER_INPUT'); + + assert.equal(actualParamSpecs.length, expectedParamSpecs.length, 'Number of parameter specs should match'); + assert.equal(actualUserSpecs.length, expectedUserSpecs.length, 'Number of user input specs should match'); + + // Verify parameter placeholder naming matches PyTorch convention + for (let i = 0; i < expectedParamSpecs.length; i++) { + assert.equal(actualParamSpecs[i].name, expectedParamSpecs[i].name, + `Parameter spec name should match: expected ${expectedParamSpecs[i].name}`); + assert.equal(actualParamSpecs[i].kind, 'PARAMETER'); + } + + // Verify user input naming + for (let i = 0; i < expectedUserSpecs.length; i++) { + assert.equal(actualUserSpecs[i].name, expectedUserSpecs[i].name, + `User input spec name should match: expected ${expectedUserSpecs[i].name}`); + } + + // Verify output spec + assert.equal(ep.graph_signature.output_specs.length, test.expected_output_specs.length); + assert.equal(ep.graph_signature.output_specs[0].kind, 'USER_OUTPUT'); + + // Verify placeholder node shapes match + const expectedPlaceholders = test.expected_nodes.filter(n => n.op === 'placeholder'); + for (let i = 0; i < expectedPlaceholders.length; i++) { + assert.equal(placeholders[i].name, expectedPlaceholders[i].name, + `Placeholder name should match: expected ${expectedPlaceholders[i].name}`); + if (expectedPlaceholders[i].val_shape) { + assert.deepEqual(placeholders[i].val_shape, expectedPlaceholders[i].val_shape, + `Placeholder shape should match for ${expectedPlaceholders[i].name}`); + } + } + + // Verify output node references a valid graph node + const outputArgs = outputs[0].args; + assert.isAbove(outputArgs.length, 0, 'Output should reference at least one node'); + + // All node names should be unique + const allNames = ep.graph.map(n => n.name); + const uniqueNames = new Set(allNames); + assert.equal(allNames.length, uniqueNames.size, 'All node names should be unique'); + }); + }); + }); }); diff --git a/test/testcases.gen.js b/test/testcases.gen.js index ebcfda28..dd07ab6f 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -21559,5 +21559,331 @@ export const testData = { 64.0 ] } + ], + "export": [ + { + "test_name": "linear_relu", + "model_type": "LinearReLU", + "input": [ + [ + -1.1228563785552979, + -0.18632829189300537, + 2.2082014083862305 + ], + [ + -0.637997031211853, + 0.46165722608566284, + 0.2673508822917938 + ] + ], + "weight": [ + [ + 0.4414065182209015, + 0.47920528054237366, + -0.1352572739124298 + ], + [ + 0.5303604602813721, + -0.1264995038509369, + 0.11650390923023224 + ] + ], + "bias": [ + -0.28108587861061096, + 0.3390677869319916 + ], + "in_features": 3, + "out_features": 2, + "expected_nodes": [ + { + "op": "placeholder", + "name": "p_0_weight", + "target": "p_0_weight", + "args": [], + "val_shape": [ + 2, + 3 + ] + }, + { + "op": "placeholder", + "name": "p_0_bias", + "target": "p_0_bias", + "args": [], + "val_shape": [ + 2 + ] + }, + { + "op": "placeholder", + "name": "input", + "target": "input", + "args": [], + "val_shape": [ + 2, + 3 + ] + }, + { + "op": "call_function", + "name": "linear", + "target": "aten.linear.default", + "args": [ + "input", + "p_0_weight", + "p_0_bias" + ], + "val_shape": [ + 2, + 2 + ] + }, + { + "op": "call_function", + "name": "relu", + "target": "aten.relu.default", + "args": [ + "linear" + ], + "val_shape": [ + 2, + 2 + ] + }, + { + "op": "output", + "name": "output", + "target": "output", + "args": [ + [ + "relu" + ] + ] + } + ], + "expected_input_specs": [ + { + "kind": "PARAMETER", + "name": "p_0_weight" + }, + { + "kind": "PARAMETER", + "name": "p_0_bias" + }, + { + "kind": "USER_INPUT", + "name": "input" + } + ], + "expected_output_specs": [ + { + "kind": "USER_OUTPUT", + "name": "relu" + } + ] + }, + { + "test_name": "two_layer", + "model_type": "TwoLayer", + "input": [ + [ + -0.331889808177948, + -0.4784944951534271, + -0.2630537450313568, + -0.17855434119701385 + ], + [ + -1.1858534812927246, + -0.8860282301902771, + -0.7149547338485718, + 0.12802214920520782 + ] + ], + "linear1_weight": [ + [ + 0.3822692632675171, + 0.4150039553642273, + -0.11713624000549316, + 0.45930564403533936 + ], + [ + -0.10955178737640381, + 0.10089534521102905, + -0.24342751502990723, + 0.2936413288116455 + ], + [ + 0.4407714605331421, + -0.3668140769004822, + 0.43459808826446533, + 0.09357964992523193 + ] + ], + "linear1_bias": [ + 0.3694044351577759, + 0.06771528720855713, + 0.24109405279159546 + ], + "linear2_weight": [ + [ + -0.08151666074991226, + 0.44507113099098206, + 0.08533751219511032 + ], + [ + -0.26953014731407166, + 0.14716561138629913, + -0.2660064101219177 + ] + ], + "linear2_bias": [ + -0.06770750880241394, + -0.234495609998703 + ], + "linear1_in": 4, + "linear1_out": 3, + "linear2_in": 3, + "linear2_out": 2, + "expected_nodes": [ + { + "op": "placeholder", + "name": "p_0_weight", + "target": "p_0_weight", + "args": [], + "val_shape": [ + 3, + 4 + ] + }, + { + "op": "placeholder", + "name": "p_0_bias", + "target": "p_0_bias", + "args": [], + "val_shape": [ + 3 + ] + }, + { + "op": "placeholder", + "name": "p_2_weight", + "target": "p_2_weight", + "args": [], + "val_shape": [ + 2, + 3 + ] + }, + { + "op": "placeholder", + "name": "p_2_bias", + "target": "p_2_bias", + "args": [], + "val_shape": [ + 2 + ] + }, + { + "op": "placeholder", + "name": "input", + "target": "input", + "args": [], + "val_shape": [ + 2, + 4 + ] + }, + { + "op": "call_function", + "name": "linear", + "target": "aten.linear.default", + "args": [ + "input", + "p_0_weight", + "p_0_bias" + ], + "val_shape": [ + 2, + 3 + ] + }, + { + "op": "call_function", + "name": "relu", + "target": "aten.relu.default", + "args": [ + "linear" + ], + "val_shape": [ + 2, + 3 + ] + }, + { + "op": "call_function", + "name": "linear_1", + "target": "aten.linear.default", + "args": [ + "relu", + "p_2_weight", + "p_2_bias" + ], + "val_shape": [ + 2, + 2 + ] + }, + { + "op": "call_function", + "name": "sigmoid", + "target": "aten.sigmoid.default", + "args": [ + "linear_1" + ], + "val_shape": [ + 2, + 2 + ] + }, + { + "op": "output", + "name": "output", + "target": "output", + "args": [ + [ + "sigmoid" + ] + ] + } + ], + "expected_input_specs": [ + { + "kind": "PARAMETER", + "name": "p_0_weight" + }, + { + "kind": "PARAMETER", + "name": "p_0_bias" + }, + { + "kind": "PARAMETER", + "name": "p_2_weight" + }, + { + "kind": "PARAMETER", + "name": "p_2_bias" + }, + { + "kind": "USER_INPUT", + "name": "input" + } + ], + "expected_output_specs": [ + { + "kind": "USER_OUTPUT", + "name": "sigmoid" + } + ] + } ] }; From 1be48e5efbdf8caa37aabc689b03df28472bc451 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 12:34:35 +0800 Subject: [PATCH 101/128] refactor: automatic testcase generator --- scripts/.gitignore | 216 + scripts/generate_tests.py | 416 +- scripts/generator/__init__.py | 0 scripts/generator/binary.py | 30 + scripts/generator/broadcasting.py | 41 + scripts/generator/conv.py | 91 + scripts/generator/encoder.py | 39 + scripts/generator/expand.py | 32 + scripts/generator/export.py | 93 + scripts/generator/linear.py | 30 + scripts/generator/matmul.py | 33 + scripts/generator/optimizer.py | 47 + scripts/generator/reduction.py | 41 + scripts/generator/unary.py | 24 + scripts/pyproject.toml | 2 + test/testcases.gen.js | 22789 +++++----------------------- 16 files changed, 4545 insertions(+), 19379 deletions(-) create mode 100644 scripts/.gitignore create mode 100644 scripts/generator/__init__.py create mode 100644 scripts/generator/binary.py create mode 100644 scripts/generator/broadcasting.py create mode 100644 scripts/generator/conv.py create mode 100644 scripts/generator/encoder.py create mode 100644 scripts/generator/expand.py create mode 100644 scripts/generator/export.py create mode 100644 scripts/generator/linear.py create mode 100644 scripts/generator/matmul.py create mode 100644 scripts/generator/optimizer.py create mode 100644 scripts/generator/reduction.py create mode 100644 scripts/generator/unary.py create mode 100644 scripts/pyproject.toml diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 00000000..e15106e3 --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1,216 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# .idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index 6c9fe887..4fe0bd0c 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -1,408 +1,22 @@ import torch -import json -UNARY_OPS = ['log', 'sqrt', 'exp', 'square', 'abs', 'sign', 'neg', 'reciprocal', 'sin', 'cos', 'tan'] -BINARY_OPS = ['add', 'sub', 'mul', 'div', 'pow', 'maximum', 'minimum'] +from generator.encoder import CompactJSONEncoder +from generator.unary import generate_unary_tests +from generator.binary import generate_binary_tests +from generator.broadcasting import generate_broadcasting_tests +from generator.matmul import generate_matmul_tests +from generator.reduction import generate_reduction_tests +from generator.linear import generate_linear_tests +from generator.optimizer import generate_optimizer_tests +from generator.expand import generate_expand_tests +from generator.conv import generate_conv_tests +from generator.export import generate_export_tests + +UNARY_OPS = ["log", "sqrt", "exp", "square", "abs", "sign", "neg", "reciprocal", "sin", "cos", "tan"] +BINARY_OPS = ["add", "sub", "mul", "div", "pow", "maximum", "minimum"] torch.manual_seed(42) -def generate_unary_tests(op_name, num_tests=3): - tests = [] - for i in range(num_tests): - x = torch.randn(3, 3, requires_grad=True) - with torch.no_grad(): - x[0, 0] = 0 - x[0, 1] = 1 - x[0, 2] = -1 - - torch_op = getattr(torch, op_name) - y = torch_op(x) - y.sum().backward() - - tests.append({ - "input": x.detach().numpy().tolist(), - "expected_output": y.detach().numpy().tolist(), - "expected_grad": x.grad.numpy().tolist() - }) - return tests - -def generate_binary_tests(op_name, num_tests=3): - tests = [] - for i in range(num_tests): - x = torch.randn(4, 4, requires_grad=True) - y = torch.randn(4, 4, requires_grad=True) - with torch.no_grad(): - x[0:2, 0] = 0 - x[0:2, 1] = 1 - x[0:2, 2] = -1 - y[0, 0:2] = 0 - y[1, 0:2] = 1 - y[2, 0:2] = -1 - - torch_op = getattr(torch, op_name) - out = torch_op(x, y) - out.sum().backward() - - tests.append({ - "input_x": x.detach().numpy().tolist(), - "input_y": y.detach().numpy().tolist(), - "expected_output": out.detach().numpy().tolist(), - "expected_grad_x": x.grad.numpy().tolist(), - "expected_grad_y": y.grad.numpy().tolist() - }) - return tests - -def generate_broadcasting_tests(): - shape_pairs = [ - ((2, 3), (2, 3)), - ((), (2, 2)), - ((2, 3, 4, 1), (3, 1, 1)), - ((1,), (3, 1, 2)), - ((5, 1, 4, 1), (3, 1, 1)) - ] - - ops = ['add', 'mul'] - tests = [] - - for shape_x, shape_y in shape_pairs: - for op_name in ops: - x = torch.randn(shape_x, requires_grad=True) if shape_x != () else torch.tensor(1.5, requires_grad=True) - y = torch.randn(shape_y, requires_grad=True) if shape_y != () else torch.tensor(-0.5, requires_grad=True) - - torch_op = getattr(torch, op_name) - out = torch_op(x, y) - - out.sum().backward() - - sx_str = "scalar" if shape_x == () else str(shape_x) - sy_str = "scalar" if shape_y == () else str(shape_y) - - tests.append({ - "test_name": f"broadcast_{op_name}_{sx_str}_and_{sy_str}", - "op_name": op_name, - "input_x": x.detach().numpy().tolist(), - "input_y": y.detach().numpy().tolist(), - "expected_output": out.detach().numpy().tolist(), - "expected_grad_x": x.grad.numpy().tolist() if x.grad is not None else 0.0, - "expected_grad_y": y.grad.numpy().tolist() if y.grad is not None else 0.0 - }) - - return tests - -def generate_matmul_tests(): - matmul_cases = [ - ((3,), (3,), "1D_dot_product"), - ((2, 3), (3, 4), "2D_matrix_multiply"), - ((3,), (3, 4), "1D_2D_prepend_remove"), - ((2, 3), (3,), "2D_1D_matrix_vector"), - ((2, 1, 2, 3), (3, 3, 2), "ND_batched_with_broadcast") - ] - - tests = [] - - for shape_x, shape_y, desc in matmul_cases: - x = torch.randn(shape_x, requires_grad=True) - y = torch.randn(shape_y, requires_grad=True) - - out = torch.matmul(x, y) - out.sum().backward() - - tests.append({ - "test_name": f"matmul_{desc}", - "input_x": x.detach().numpy().tolist(), - "input_y": y.detach().numpy().tolist(), - "expected_output": out.detach().numpy().tolist(), - "expected_grad_x": x.grad.numpy().tolist(), - "expected_grad_y": y.grad.numpy().tolist() - }) - - return tests - -def generate_reduction_tests(): - tests = [] - ops = ['sum', 'mean', 'max', 'min'] - dims = [None, 0, 1, -1] - keepdims = [False, True] - - for op in ops: - for dim in dims: - for keepdim in keepdims: - if dim is None and keepdim: - continue - - x = torch.randn(3, 4, 5, requires_grad=True) - torch_op = getattr(torch, op) - - try: - if dim is None: - y = torch_op(x) - else: - out = torch_op(x, dim=dim, keepdim=keepdim) - y = out.values if op in ['max', 'min'] else out - - y.sum().backward() - - tests.append({ - "test_name": f"{op}_dim_{dim}_keepdim_{keepdim}", - "op_name": op, - "dim": dim, - "keepdim": keepdim, - "input": x.detach().numpy().tolist(), - "expected_output": y.detach().numpy().tolist(), - "expected_grad": x.grad.numpy().tolist() - }) - except Exception as e: - pass - return tests - -def generate_linear_tests(): - tests = [] - # Test standard 2D inputs and batched 3D inputs - cases = [ - (10, 5, (3, 10), "2D_input"), - (4, 2, (2, 3, 4), "3D_batched_input") - ] - - for in_features, out_features, input_shape, desc in cases: - layer = torch.nn.Linear(in_features, out_features) - x = torch.randn(*input_shape, requires_grad=True) - - out = layer(x) - out.sum().backward() - - tests.append({ - "test_name": f"linear_{desc}", - "in_features": in_features, - "out_features": out_features, - "input": x.detach().numpy().tolist(), - "weight": layer.weight.detach().numpy().tolist(), - "bias": layer.bias.detach().numpy().tolist(), - "expected_output": out.detach().numpy().tolist(), - "expected_grad_input": x.grad.numpy().tolist(), - "expected_grad_weight": layer.weight.grad.numpy().tolist(), - "expected_grad_bias": layer.bias.grad.numpy().tolist() - }) - return tests - -def generate_optimizer_tests(): - tests = [] - configs = [ - ("SGD_basic", torch.optim.SGD, {"lr": 0.1}), - ("SGD_momentum", torch.optim.SGD, {"lr": 0.1, "momentum": 0.9}), - ("Adam_basic", torch.optim.Adam, {"lr": 0.1}), - ("Adam_custom_betas", torch.optim.Adam, {"lr": 0.1, "betas": (0.95, 0.999)}) - ] - - for test_name, optim_class, kwargs in configs: - # 1. Initialize a generic parameter tensor - w = torch.randn(3, 3, requires_grad=True) - x = torch.randn(3, 3) # Dummy input to calculate a loss - - # Save exact starting state - initial_w = w.detach().clone() - - # 2. Setup Optimizer - optimizer = optim_class([w], **kwargs) - optimizer.zero_grad() - - # 3. Compute loss and gradients - loss = (w * x).sum() - loss.backward() - - # Save exact gradient computed by PyTorch - expected_grad = w.grad.detach().clone() - - # 4. Step the optimizer - optimizer.step() - - tests.append({ - "test_name": test_name, - "optimizer": test_name.split("_")[0], # "SGD" or "Adam" - "kwargs": kwargs, - "initial_weight": initial_w.numpy().tolist(), - "input_x": x.numpy().tolist(), - "expected_grad": expected_grad.numpy().tolist(), - "expected_updated_weight": w.detach().numpy().tolist() - }) - - return tests - -def generate_expand_tests(): - tests = [] - - # Tuples of (initial_shape, expand_shape, description) - cases = [ - ((1,), (3,), "1D_expand"), - ((3,), (2, 3), "prepend_2D"), - ((1, 3), (4, 3), "expand_dim_0"), - ((2, 1, 4), (2, 5, 4), "expand_middle_dim"), - ((1, 3, 1), (2, -1, 4), "preserve_with_negative_one") - ] - - for initial_shape, expand_shape, desc in cases: - x = torch.randn(initial_shape, requires_grad=True) - - out = x.expand(*expand_shape) - out.sum().backward() - - tests.append({ - "test_name": f"expand_{desc}", - "input": x.detach().numpy().tolist(), - "expand_shape": list(expand_shape), - "expected_output": out.detach().numpy().tolist(), - "expected_grad": x.grad.numpy().tolist() - }) - - return tests - -def generate_conv_tests(): - tests = [] - cases = [ - ("Conv1d", torch.nn.Conv1d, [ - (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5), "basic"), - (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 6), "stride_padding"), - (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5), "dilation_no_bias"), - (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 6), "groups"), - ]), - ("Conv2d", torch.nn.Conv2d, [ - (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5, 5), "basic"), - (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 6, 6), "stride_padding"), - (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5, 5), "dilation_no_bias"), - (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 4, 4), "groups"), - ]), - ("Conv3d", torch.nn.Conv3d, [ - (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5, 5, 5), "basic"), - (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 4, 4, 4), "stride_padding"), - (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5, 5, 5), "dilation_no_bias"), - (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 4, 4, 4), "groups"), - ]) - ] - for conv_type, conv_class, conv_cases in cases: - for in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, input_shape, desc in conv_cases: - layer = conv_class(in_channels, out_channels, kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias) - x = torch.randn(*input_shape, requires_grad=True) - - out = layer(x) - out.sum().backward() - - test_data = { - "test_name": f"{conv_type.lower()}_{desc}", - "conv_type": conv_type, - "in_channels": in_channels, - "out_channels": out_channels, - "kernel_size": kernel_size, - "stride": stride, - "padding": padding, - "dilation": dilation, - "groups": groups, - "has_bias": bias, - "input": x.detach().numpy().tolist(), - "weight": layer.weight.detach().numpy().tolist(), - "expected_output": out.detach().numpy().tolist(), - "expected_grad_input": x.grad.numpy().tolist(), - "expected_grad_weight": layer.weight.grad.numpy().tolist() - } - if bias: - test_data["bias"] = layer.bias.detach().numpy().tolist() - test_data["expected_grad_bias"] = layer.bias.grad.numpy().tolist() - else: - test_data["bias"] = None - test_data["expected_grad_bias"] = None - - tests.append(test_data) - return tests - -def generate_export_tests(): - tests = [] - - def extract_nodes(ep): - nodes = [] - for node in ep.graph.nodes: - nd = { - 'op': node.op, - 'name': node.name, - 'target': str(node.target), - } - nd['args'] = [] - for a in node.args: - if isinstance(a, torch.fx.Node): - nd['args'].append(a.name) - elif isinstance(a, tuple): - nd['args'].append([n.name if isinstance(n, torch.fx.Node) else str(n) for n in a]) - else: - nd['args'].append(str(a)) - if 'val' in node.meta: - v = node.meta['val'] - if isinstance(v, torch.Tensor): - nd['val_shape'] = list(v.shape) - nodes.append(nd) - return nodes - - def extract_specs(ep): - sig = ep.graph_signature - input_specs = [{'kind': s.kind.name, 'name': s.arg.name if hasattr(s.arg, 'name') else str(s.arg)} for s in sig.input_specs] - output_specs = [{'kind': s.kind.name, 'name': s.arg.name if hasattr(s.arg, 'name') else str(s.arg)} for s in sig.output_specs] - return input_specs, output_specs - - # Test 1: Simple Sequential(Linear, ReLU) - torch.manual_seed(42) - model1 = torch.nn.Sequential( - torch.nn.Linear(3, 2), - torch.nn.ReLU() - ) - x1 = torch.randn(2, 3) - ep1 = torch.export.export(model1, (x1,)) - - nodes1 = extract_nodes(ep1) - input_specs1, output_specs1 = extract_specs(ep1) - - tests.append({ - 'test_name': 'linear_relu', - 'model_type': 'LinearReLU', - 'input': x1.detach().numpy().tolist(), - 'weight': model1[0].weight.detach().numpy().tolist(), - 'bias': model1[0].bias.detach().numpy().tolist(), - 'in_features': 3, - 'out_features': 2, - 'expected_nodes': nodes1, - 'expected_input_specs': input_specs1, - 'expected_output_specs': output_specs1, - }) - - # Test 2: Sequential(Linear, ReLU, Linear, Sigmoid) - torch.manual_seed(42) - model2 = torch.nn.Sequential( - torch.nn.Linear(4, 3), - torch.nn.ReLU(), - torch.nn.Linear(3, 2), - torch.nn.Sigmoid() - ) - x2 = torch.randn(2, 4) - ep2 = torch.export.export(model2, (x2,)) - - nodes2 = extract_nodes(ep2) - input_specs2, output_specs2 = extract_specs(ep2) - - tests.append({ - 'test_name': 'two_layer', - 'model_type': 'TwoLayer', - 'input': x2.detach().numpy().tolist(), - 'linear1_weight': model2[0].weight.detach().numpy().tolist(), - 'linear1_bias': model2[0].bias.detach().numpy().tolist(), - 'linear2_weight': model2[2].weight.detach().numpy().tolist(), - 'linear2_bias': model2[2].bias.detach().numpy().tolist(), - 'linear1_in': 4, - 'linear1_out': 3, - 'linear2_in': 3, - 'linear2_out': 2, - 'expected_nodes': nodes2, - 'expected_input_specs': input_specs2, - 'expected_output_specs': output_specs2, - }) - - return tests - - if __name__ == "__main__": suite = { "unary": {op: generate_unary_tests(op) for op in UNARY_OPS}, @@ -418,4 +32,4 @@ def extract_specs(ep): } print("export const testData = ", end="") - print(json.dumps(suite, indent=2), end=";\n") + print(CompactJSONEncoder(indent=2).encode(suite), end=";\n") diff --git a/scripts/generator/__init__.py b/scripts/generator/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/generator/binary.py b/scripts/generator/binary.py new file mode 100644 index 00000000..b742ef56 --- /dev/null +++ b/scripts/generator/binary.py @@ -0,0 +1,30 @@ +import torch + + +def generate_binary_tests(op_name, num_tests=3): + tests = [] + for i in range(num_tests): + x = torch.randn(4, 4, requires_grad=True) + y = torch.randn(4, 4, requires_grad=True) + with torch.no_grad(): + x[0:2, 0] = 0 + x[0:2, 1] = 1 + x[0:2, 2] = -1 + y[0, 0:2] = 0 + y[1, 0:2] = 1 + y[2, 0:2] = -1 + + torch_op = getattr(torch, op_name) + out = torch_op(x, y) + out.sum().backward() + + tests.append( + { + "input_x": x.detach().numpy().tolist(), + "input_y": y.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_x": x.grad.numpy().tolist(), + "expected_grad_y": y.grad.numpy().tolist(), + } + ) + return tests diff --git a/scripts/generator/broadcasting.py b/scripts/generator/broadcasting.py new file mode 100644 index 00000000..da21d188 --- /dev/null +++ b/scripts/generator/broadcasting.py @@ -0,0 +1,41 @@ +import torch + + +def generate_broadcasting_tests(): + shape_pairs = [ + ((2, 3), (2, 3)), + ((), (2, 2)), + ((2, 3, 4, 1), (3, 1, 1)), + ((1,), (3, 1, 2)), + ((5, 1, 4, 1), (3, 1, 1)), + ] + + ops = ["add", "mul"] + tests = [] + + for shape_x, shape_y in shape_pairs: + for op_name in ops: + x = torch.randn(shape_x, requires_grad=True) if shape_x != () else torch.tensor(1.5, requires_grad=True) + y = torch.randn(shape_y, requires_grad=True) if shape_y != () else torch.tensor(-0.5, requires_grad=True) + + torch_op = getattr(torch, op_name) + out = torch_op(x, y) + + out.sum().backward() + + sx_str = "scalar" if shape_x == () else str(shape_x) + sy_str = "scalar" if shape_y == () else str(shape_y) + + tests.append( + { + "test_name": f"broadcast_{op_name}_{sx_str}_and_{sy_str}", + "op_name": op_name, + "input_x": x.detach().numpy().tolist(), + "input_y": y.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_x": x.grad.numpy().tolist() if x.grad is not None else 0.0, + "expected_grad_y": y.grad.numpy().tolist() if y.grad is not None else 0.0, + } + ) + + return tests diff --git a/scripts/generator/conv.py b/scripts/generator/conv.py new file mode 100644 index 00000000..4e4951de --- /dev/null +++ b/scripts/generator/conv.py @@ -0,0 +1,91 @@ +import torch + + +def generate_conv_tests(): + tests = [] + cases = [ + ( + "Conv1d", + torch.nn.Conv1d, + [ + (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5), "basic"), + (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 6), "stride_padding"), + (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5), "dilation_no_bias"), + (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 6), "groups"), + ], + ), + ( + "Conv2d", + torch.nn.Conv2d, + [ + (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5, 5), "basic"), + (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 6, 6), "stride_padding"), + (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5, 5), "dilation_no_bias"), + (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 4, 4), "groups"), + ], + ), + ( + "Conv3d", + torch.nn.Conv3d, + [ + (1, 1, 3, 1, 0, 1, 1, True, (1, 1, 5, 5, 5), "basic"), + (2, 3, 2, 2, 1, 1, 1, True, (2, 2, 4, 4, 4), "stride_padding"), + (2, 2, 2, 1, 0, 2, 1, False, (1, 2, 5, 5, 5), "dilation_no_bias"), + (4, 4, 3, 1, 1, 1, 2, True, (1, 4, 4, 4, 4), "groups"), + ], + ), + ] + for conv_type, conv_class, conv_cases in cases: + for ( + in_channels, + out_channels, + kernel_size, + stride, + padding, + dilation, + groups, + bias, + input_shape, + desc, + ) in conv_cases: + layer = conv_class( + in_channels, + out_channels, + kernel_size, + stride=stride, + padding=padding, + dilation=dilation, + groups=groups, + bias=bias, + ) + x = torch.randn(*input_shape, requires_grad=True) + + out = layer(x) + out.sum().backward() + + test_data = { + "test_name": f"{conv_type.lower()}_{desc}", + "conv_type": conv_type, + "in_channels": in_channels, + "out_channels": out_channels, + "kernel_size": kernel_size, + "stride": stride, + "padding": padding, + "dilation": dilation, + "groups": groups, + "has_bias": bias, + "input": x.detach().numpy().tolist(), + "weight": layer.weight.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_input": x.grad.numpy().tolist(), + "expected_grad_weight": layer.weight.grad.numpy().tolist(), + } + if bias: + test_data["bias"] = layer.bias.detach().numpy().tolist() + test_data["expected_grad_bias"] = layer.bias.grad.numpy().tolist() + else: + test_data["bias"] = None + test_data["expected_grad_bias"] = None + + tests.append(test_data) + return tests diff --git a/scripts/generator/encoder.py b/scripts/generator/encoder.py new file mode 100644 index 00000000..482e1ff8 --- /dev/null +++ b/scripts/generator/encoder.py @@ -0,0 +1,39 @@ +import json + + +class CompactJSONEncoder(json.JSONEncoder): + """JSON encoder that puts leaf arrays (arrays of non-list items) on single lines.""" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._indent = kwargs.get("indent", 2) + + def encode(self, o): + return self._encode(o, 0) + + def _encode(self, o, level): + indent_str = " " * (self._indent * level) + next_indent_str = " " * (self._indent * (level + 1)) + + if isinstance(o, dict): + if not o: + return "{}" + items = [] + for k, v in o.items(): + key = json.dumps(k) + val = self._encode(v, level + 1) + items.append(f"{next_indent_str}{key}: {val}") + return "{\n" + ",\n".join(items) + f"\n{indent_str}}}" + + elif isinstance(o, list): + if not o: + return "[]" + # Leaf array: no nested lists inside + if not any(isinstance(item, (list, dict)) for item in o): + return "[" + ", ".join(self._encode(v, level) for v in o) + "]" + # Nested array: pretty print + items = [f"{next_indent_str}{self._encode(v, level + 1)}" for v in o] + return "[\n" + ",\n".join(items) + f"\n{indent_str}]" + + else: + return json.dumps(o) diff --git a/scripts/generator/expand.py b/scripts/generator/expand.py new file mode 100644 index 00000000..459e3b25 --- /dev/null +++ b/scripts/generator/expand.py @@ -0,0 +1,32 @@ +import torch + + +def generate_expand_tests(): + tests = [] + + # Tuples of (initial_shape, expand_shape, description) + cases = [ + ((1,), (3,), "1D_expand"), + ((3,), (2, 3), "prepend_2D"), + ((1, 3), (4, 3), "expand_dim_0"), + ((2, 1, 4), (2, 5, 4), "expand_middle_dim"), + ((1, 3, 1), (2, -1, 4), "preserve_with_negative_one"), + ] + + for initial_shape, expand_shape, desc in cases: + x = torch.randn(initial_shape, requires_grad=True) + + out = x.expand(*expand_shape) + out.sum().backward() + + tests.append( + { + "test_name": f"expand_{desc}", + "input": x.detach().numpy().tolist(), + "expand_shape": list(expand_shape), + "expected_output": out.detach().numpy().tolist(), + "expected_grad": x.grad.numpy().tolist(), + } + ) + + return tests diff --git a/scripts/generator/export.py b/scripts/generator/export.py new file mode 100644 index 00000000..8e32f041 --- /dev/null +++ b/scripts/generator/export.py @@ -0,0 +1,93 @@ +import torch + + +def generate_export_tests(): + tests = [] + + def extract_nodes(ep): + nodes = [] + for node in ep.graph.nodes: + nd = { + "op": node.op, + "name": node.name, + "target": str(node.target), + } + nd["args"] = [] + for a in node.args: + if isinstance(a, torch.fx.Node): + nd["args"].append(a.name) + elif isinstance(a, tuple): + nd["args"].append([n.name if isinstance(n, torch.fx.Node) else str(n) for n in a]) + else: + nd["args"].append(str(a)) + if "val" in node.meta: + v = node.meta["val"] + if isinstance(v, torch.Tensor): + nd["val_shape"] = list(v.shape) + nodes.append(nd) + return nodes + + def extract_specs(ep): + sig = ep.graph_signature + input_specs = [ + {"kind": s.kind.name, "name": s.arg.name if hasattr(s.arg, "name") else str(s.arg)} for s in sig.input_specs + ] + output_specs = [ + {"kind": s.kind.name, "name": s.arg.name if hasattr(s.arg, "name") else str(s.arg)} + for s in sig.output_specs + ] + return input_specs, output_specs + + # Test 1: Simple Sequential(Linear, ReLU) + torch.manual_seed(42) + model1 = torch.nn.Sequential(torch.nn.Linear(3, 2), torch.nn.ReLU()) + x1 = torch.randn(2, 3) + ep1 = torch.export.export(model1, (x1,)) + + nodes1 = extract_nodes(ep1) + input_specs1, output_specs1 = extract_specs(ep1) + + tests.append( + { + "test_name": "linear_relu", + "model_type": "LinearReLU", + "input": x1.detach().numpy().tolist(), + "weight": model1[0].weight.detach().numpy().tolist(), + "bias": model1[0].bias.detach().numpy().tolist(), + "in_features": 3, + "out_features": 2, + "expected_nodes": nodes1, + "expected_input_specs": input_specs1, + "expected_output_specs": output_specs1, + } + ) + + # Test 2: Sequential(Linear, ReLU, Linear, Sigmoid) + torch.manual_seed(42) + model2 = torch.nn.Sequential(torch.nn.Linear(4, 3), torch.nn.ReLU(), torch.nn.Linear(3, 2), torch.nn.Sigmoid()) + x2 = torch.randn(2, 4) + ep2 = torch.export.export(model2, (x2,)) + + nodes2 = extract_nodes(ep2) + input_specs2, output_specs2 = extract_specs(ep2) + + tests.append( + { + "test_name": "two_layer", + "model_type": "TwoLayer", + "input": x2.detach().numpy().tolist(), + "linear1_weight": model2[0].weight.detach().numpy().tolist(), + "linear1_bias": model2[0].bias.detach().numpy().tolist(), + "linear2_weight": model2[2].weight.detach().numpy().tolist(), + "linear2_bias": model2[2].bias.detach().numpy().tolist(), + "linear1_in": 4, + "linear1_out": 3, + "linear2_in": 3, + "linear2_out": 2, + "expected_nodes": nodes2, + "expected_input_specs": input_specs2, + "expected_output_specs": output_specs2, + } + ) + + return tests diff --git a/scripts/generator/linear.py b/scripts/generator/linear.py new file mode 100644 index 00000000..10e494b3 --- /dev/null +++ b/scripts/generator/linear.py @@ -0,0 +1,30 @@ +import torch + + +def generate_linear_tests(): + tests = [] + # Test standard 2D inputs and batched 3D inputs + cases = [(10, 5, (3, 10), "2D_input"), (4, 2, (2, 3, 4), "3D_batched_input")] + + for in_features, out_features, input_shape, desc in cases: + layer = torch.nn.Linear(in_features, out_features) + x = torch.randn(*input_shape, requires_grad=True) + + out = layer(x) + out.sum().backward() + + tests.append( + { + "test_name": f"linear_{desc}", + "in_features": in_features, + "out_features": out_features, + "input": x.detach().numpy().tolist(), + "weight": layer.weight.detach().numpy().tolist(), + "bias": layer.bias.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_input": x.grad.numpy().tolist(), + "expected_grad_weight": layer.weight.grad.numpy().tolist(), + "expected_grad_bias": layer.bias.grad.numpy().tolist(), + } + ) + return tests diff --git a/scripts/generator/matmul.py b/scripts/generator/matmul.py new file mode 100644 index 00000000..d9bfd739 --- /dev/null +++ b/scripts/generator/matmul.py @@ -0,0 +1,33 @@ +import torch + + +def generate_matmul_tests(): + matmul_cases = [ + ((3,), (3,), "1D_dot_product"), + ((2, 3), (3, 4), "2D_matrix_multiply"), + ((3,), (3, 4), "1D_2D_prepend_remove"), + ((2, 3), (3,), "2D_1D_matrix_vector"), + ((2, 1, 2, 3), (3, 3, 2), "ND_batched_with_broadcast"), + ] + + tests = [] + + for shape_x, shape_y, desc in matmul_cases: + x = torch.randn(shape_x, requires_grad=True) + y = torch.randn(shape_y, requires_grad=True) + + out = torch.matmul(x, y) + out.sum().backward() + + tests.append( + { + "test_name": f"matmul_{desc}", + "input_x": x.detach().numpy().tolist(), + "input_y": y.detach().numpy().tolist(), + "expected_output": out.detach().numpy().tolist(), + "expected_grad_x": x.grad.numpy().tolist(), + "expected_grad_y": y.grad.numpy().tolist(), + } + ) + + return tests diff --git a/scripts/generator/optimizer.py b/scripts/generator/optimizer.py new file mode 100644 index 00000000..b030445c --- /dev/null +++ b/scripts/generator/optimizer.py @@ -0,0 +1,47 @@ +import torch + + +def generate_optimizer_tests(): + tests = [] + configs = [ + ("SGD_basic", torch.optim.SGD, {"lr": 0.1}), + ("SGD_momentum", torch.optim.SGD, {"lr": 0.1, "momentum": 0.9}), + ("Adam_basic", torch.optim.Adam, {"lr": 0.1}), + ("Adam_custom_betas", torch.optim.Adam, {"lr": 0.1, "betas": (0.95, 0.999)}), + ] + + for test_name, optim_class, kwargs in configs: + # 1. Initialize a generic parameter tensor + w = torch.randn(3, 3, requires_grad=True) + x = torch.randn(3, 3) # Dummy input to calculate a loss + + # Save exact starting state + initial_w = w.detach().clone() + + # 2. Setup Optimizer + optimizer = optim_class([w], **kwargs) + optimizer.zero_grad() + + # 3. Compute loss and gradients + loss = (w * x).sum() + loss.backward() + + # Save exact gradient computed by PyTorch + expected_grad = w.grad.detach().clone() + + # 4. Step the optimizer + optimizer.step() + + tests.append( + { + "test_name": test_name, + "optimizer": test_name.split("_")[0], # "SGD" or "Adam" + "kwargs": kwargs, + "initial_weight": initial_w.numpy().tolist(), + "input_x": x.numpy().tolist(), + "expected_grad": expected_grad.numpy().tolist(), + "expected_updated_weight": w.detach().numpy().tolist(), + } + ) + + return tests diff --git a/scripts/generator/reduction.py b/scripts/generator/reduction.py new file mode 100644 index 00000000..3ff12ec8 --- /dev/null +++ b/scripts/generator/reduction.py @@ -0,0 +1,41 @@ +import torch + + +def generate_reduction_tests(): + tests = [] + ops = ["sum", "mean", "max", "min"] + dims = [None, 0, 1, -1] + keepdims = [False, True] + + for op in ops: + for dim in dims: + for keepdim in keepdims: + if dim is None and keepdim: + continue + + x = torch.randn(3, 4, 5, requires_grad=True) + torch_op = getattr(torch, op) + + try: + if dim is None: + y = torch_op(x) + else: + out = torch_op(x, dim=dim, keepdim=keepdim) + y = out.values if op in ["max", "min"] else out + + y.sum().backward() + + tests.append( + { + "test_name": f"{op}_dim_{dim}_keepdim_{keepdim}", + "op_name": op, + "dim": dim, + "keepdim": keepdim, + "input": x.detach().numpy().tolist(), + "expected_output": y.detach().numpy().tolist(), + "expected_grad": x.grad.numpy().tolist(), + } + ) + except Exception as e: + pass + return tests diff --git a/scripts/generator/unary.py b/scripts/generator/unary.py new file mode 100644 index 00000000..c43071b6 --- /dev/null +++ b/scripts/generator/unary.py @@ -0,0 +1,24 @@ +import torch + + +def generate_unary_tests(op_name, num_tests=3): + tests = [] + for i in range(num_tests): + x = torch.randn(3, 3, requires_grad=True) + with torch.no_grad(): + x[0, 0] = 0 + x[0, 1] = 1 + x[0, 2] = -1 + + torch_op = getattr(torch, op_name) + y = torch_op(x) + y.sum().backward() + + tests.append( + { + "input": x.detach().numpy().tolist(), + "expected_output": y.detach().numpy().tolist(), + "expected_grad": x.grad.numpy().tolist(), + } + ) + return tests diff --git a/scripts/pyproject.toml b/scripts/pyproject.toml new file mode 100644 index 00000000..55ec8d78 --- /dev/null +++ b/scripts/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +line-length = 120 diff --git a/test/testcases.gen.js b/test/testcases.gen.js index dd07ab6f..a11eab31 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -3,1771 +3,583 @@ export const testData = { "log": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.23033303022384644, - -1.1228563785552979, - -0.18632829189300537 - ], - [ - 2.2082014083862305, - -0.637997031211853, - 0.46165722608566284 - ] + [0.0, 1.0, -1.0], + [0.23033303022384644, -1.1228563785552979, -0.18632829189300537], + [2.2082014083862305, -0.637997031211853, 0.46165722608566284] ], "expected_output": [ - [ - -Infinity, - 0.0, - NaN - ], - [ - -1.468229055404663, - NaN, - NaN - ], - [ - 0.7921783328056335, - NaN, - -0.7729325890541077 - ] + [-Infinity, 0.0, NaN], + [-1.468229055404663, NaN, NaN], + [0.7921783328056335, NaN, -0.7729325890541077] ], "expected_grad": [ - [ - Infinity, - 1.0, - -1.0 - ], - [ - 4.3415398597717285, - -0.8905858397483826, - -5.366871356964111 - ], - [ - 0.45285725593566895, - -1.5674054622650146, - 2.166109323501587 - ] + [Infinity, 1.0, -1.0], + [4.3415398597717285, -0.8905858397483826, -5.366871356964111], + [0.45285725593566895, -1.5674054622650146, 2.166109323501587] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.110290288925171, - -1.6897989511489868, - -0.9889599084854126 - ], - [ - 0.9579718112945557, - 1.322135090827942, - 0.8171897530555725 - ] + [0.0, 1.0, -1.0], + [1.110290288925171, -1.6897989511489868, -0.9889599084854126], + [0.9579718112945557, 1.322135090827942, 0.8171897530555725] ], "expected_output": [ - [ - -Infinity, - 0.0, - NaN - ], - [ - 0.10462149977684021, - NaN, - NaN - ], - [ - -0.04293692484498024, - 0.279247909784317, - -0.2018839567899704 - ] + [-Infinity, 0.0, NaN], + [0.10462149977684021, NaN, NaN], + [-0.04293692484498024, 0.279247909784317, -0.2018839567899704] ], "expected_grad": [ - [ - Infinity, - 1.0, - -1.0 - ], - [ - 0.9006653428077698, - -0.5917863845825195, - -1.011163353919983 - ], - [ - 1.0438719987869263, - 0.7563523650169373, - 1.2237060070037842 - ] + [Infinity, 1.0, -1.0], + [0.9006653428077698, -0.5917863845825195, -1.011163353919983], + [1.0438719987869263, 0.7563523650169373, 1.2237060070037842] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.6863219141960144, - -0.32775864005088806, - 0.7949687242507935 - ], - [ - 0.2815195620059967, - 0.056163541972637177, - 0.5227160453796387 - ] + [0.0, 1.0, -1.0], + [0.6863219141960144, -0.32775864005088806, 0.7949687242507935], + [0.2815195620059967, 0.056163541972637177, 0.5227160453796387] ], "expected_output": [ - [ - -Infinity, - 0.0, - NaN - ], - [ - -0.37640848755836487, - NaN, - -0.22945250570774078 - ], - [ - -1.2675533294677734, - -2.8794875144958496, - -0.6487168669700623 - ] + [-Infinity, 0.0, NaN], + [-0.37640848755836487, NaN, -0.22945250570774078], + [-1.2675533294677734, -2.8794875144958496, -0.6487168669700623] ], "expected_grad": [ - [ - Infinity, - 1.0, - -1.0 - ], - [ - 1.4570422172546387, - -3.051025629043579, - 1.2579110860824585 - ], - [ - 3.5521509647369385, - 17.805145263671875, - 1.913084626197815 - ] + [Infinity, 1.0, -1.0], + [1.4570422172546387, -3.051025629043579, 1.2579110860824585], + [3.5521509647369385, 17.805145263671875, 1.913084626197815] ] } ], "sqrt": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.008498823270201683, - 0.7290605902671814, - 0.13314196467399597 - ], - [ - 0.8639776706695557, - -1.0156747102737427, - -0.8887485265731812 - ] + [0.0, 1.0, -1.0], + [-0.008498823270201683, 0.7290605902671814, 0.13314196467399597], + [0.8639776706695557, -1.0156747102737427, -0.8887485265731812] ], "expected_output": [ - [ - 0.0, - 1.0, - NaN - ], - [ - NaN, - 0.8538504242897034, - 0.36488622426986694 - ], - [ - 0.9295039772987366, - NaN, - NaN - ] + [0.0, 1.0, NaN], + [NaN, 0.8538504242897034, 0.36488622426986694], + [0.9295039772987366, NaN, NaN] ], "expected_grad": [ - [ - Infinity, - 0.5, - NaN - ], - [ - NaN, - 0.5855826735496521, - 1.3702901601791382 - ], - [ - 0.5379213094711304, - NaN, - NaN - ] + [Infinity, 0.5, NaN], + [NaN, 0.5855826735496521, 1.3702901601791382], + [0.5379213094711304, NaN, NaN] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.9912377595901489, - 0.4679030478000641, - -0.20493191480636597 - ], - [ - -0.7409071326255798, - 0.3618396520614624, - 1.9198992252349854 - ] + [0.0, 1.0, -1.0], + [0.9912377595901489, 0.4679030478000641, -0.20493191480636597], + [-0.7409071326255798, 0.3618396520614624, 1.9198992252349854] ], "expected_output": [ - [ - 0.0, - 1.0, - NaN - ], - [ - 0.9956092238426208, - 0.6840344071388245, - NaN - ], - [ - NaN, - 0.6015310883522034, - 1.3856042623519897 - ] + [0.0, 1.0, NaN], + [0.9956092238426208, 0.6840344071388245, NaN], + [NaN, 0.6015310883522034, 1.3856042623519897] ], "expected_grad": [ - [ - Infinity, - 0.5, - NaN - ], - [ - 0.5022050738334656, - 0.7309573888778687, - NaN - ], - [ - NaN, - 0.8312122225761414, - 0.3608534038066864 - ] + [Infinity, 0.5, NaN], + [0.5022050738334656, 0.7309573888778687, NaN], + [NaN, 0.8312122225761414, 0.3608534038066864] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.6890136003494263, - -1.1267184019088745, - -0.2857550382614136 - ], - [ - -1.0935109853744507, - 1.1351022720336914, - 0.7592452168464661 - ] + [0.0, 1.0, -1.0], + [-0.6890136003494263, -1.1267184019088745, -0.2857550382614136], + [-1.0935109853744507, 1.1351022720336914, 0.7592452168464661] ], "expected_output": [ - [ - 0.0, - 1.0, - NaN - ], - [ - NaN, - NaN, - NaN - ], - [ - NaN, - 1.0654118061065674, - 0.8713467717170715 - ] + [0.0, 1.0, NaN], + [NaN, NaN, NaN], + [NaN, 1.0654118061065674, 0.8713467717170715] ], "expected_grad": [ - [ - Infinity, - 0.5, - NaN - ], - [ - NaN, - NaN, - NaN - ], - [ - NaN, - 0.46930208802223206, - 0.5738243460655212 - ] + [Infinity, 0.5, NaN], + [NaN, NaN, NaN], + [NaN, 0.46930208802223206, 0.5738243460655212] ] } ], "exp": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.960340142250061, - -0.5671805739402771, - -0.5706474184989929 - ], - [ - 1.5980384349822998, - 0.11148621141910553, - -0.03919669985771179 - ] + [0.0, 1.0, -1.0], + [0.960340142250061, -0.5671805739402771, -0.5706474184989929], + [1.5980384349822998, 0.11148621141910553, -0.03919669985771179] ], "expected_output": [ - [ - 1.0, - 2.7182817459106445, - 0.3678794503211975 - ], - [ - 2.6125850677490234, - 0.5671221613883972, - 0.5651594400405884 - ], - [ - 4.943326473236084, - 1.1179382801055908, - 0.9615615606307983 - ] + [1.0, 2.7182817459106445, 0.3678794503211975], + [2.6125850677490234, 0.5671221613883972, 0.5651594400405884], + [4.943326473236084, 1.1179382801055908, 0.9615615606307983] ], "expected_grad": [ - [ - 1.0, - 2.7182817459106445, - 0.3678794503211975 - ], - [ - 2.6125850677490234, - 0.5671221613883972, - 0.5651594400405884 - ], - [ - 4.943326473236084, - 1.1179382801055908, - 0.9615615606307983 - ] + [1.0, 2.7182817459106445, 0.3678794503211975], + [2.6125850677490234, 0.5671221613883972, 0.5651594400405884], + [4.943326473236084, 1.1179382801055908, 0.9615615606307983] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -1.6270242929458618, - -1.3951387405395508, - -0.23872417211532593 - ], - [ - -0.5049903988838196, - -2.475163221359253, - -0.931602954864502 - ] + [0.0, 1.0, -1.0], + [-1.6270242929458618, -1.3951387405395508, -0.23872417211532593], + [-0.5049903988838196, -2.475163221359253, -0.931602954864502] ], "expected_output": [ - [ - 1.0, - 2.7182817459106445, - 0.3678794503211975 - ], - [ - 0.19651347398757935, - 0.24779865145683289, - 0.7876321077346802 - ], - [ - 0.603511393070221, - 0.08414925634860992, - 0.39392176270484924 - ] + [1.0, 2.7182817459106445, 0.3678794503211975], + [0.19651347398757935, 0.24779865145683289, 0.7876321077346802], + [0.603511393070221, 0.08414925634860992, 0.39392176270484924] ], "expected_grad": [ - [ - 1.0, - 2.7182817459106445, - 0.3678794503211975 - ], - [ - 0.19651347398757935, - 0.24779865145683289, - 0.7876321077346802 - ], - [ - 0.603511393070221, - 0.08414925634860992, - 0.39392176270484924 - ] + [1.0, 2.7182817459106445, 0.3678794503211975], + [0.19651347398757935, 0.24779865145683289, 0.7876321077346802], + [0.603511393070221, 0.08414925634860992, 0.39392176270484924] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.09089037775993347, - -1.3296922445297241, - -0.542582631111145 - ], - [ - 0.5470984578132629, - 0.6430637240409851, - -0.7904810905456543 - ] + [0.0, 1.0, -1.0], + [-0.09089037775993347, -1.3296922445297241, -0.542582631111145], + [0.5470984578132629, 0.6430637240409851, -0.7904810905456543] ], "expected_output": [ - [ - 1.0, - 2.7182817459106445, - 0.3678794503211975 - ], - [ - 0.9131178259849548, - 0.26455867290496826, - 0.5812451839447021 - ], - [ - 1.7282311916351318, - 1.9023001194000244, - 0.45362651348114014 - ] + [1.0, 2.7182817459106445, 0.3678794503211975], + [0.9131178259849548, 0.26455867290496826, 0.5812451839447021], + [1.7282311916351318, 1.9023001194000244, 0.45362651348114014] ], "expected_grad": [ - [ - 1.0, - 2.7182817459106445, - 0.3678794503211975 - ], - [ - 0.9131178259849548, - 0.26455867290496826, - 0.5812451839447021 - ], - [ - 1.7282311916351318, - 1.9023001194000244, - 0.45362651348114014 - ] + [1.0, 2.7182817459106445, 0.3678794503211975], + [0.9131178259849548, 0.26455867290496826, 0.5812451839447021], + [1.7282311916351318, 1.9023001194000244, 0.45362651348114014] ] } ], "square": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 2.117400646209717, - -1.711801528930664, - 0.16513441503047943 - ], - [ - 1.5818675756454468, - 0.44846096634864807, - 0.033029891550540924 - ] + [0.0, 1.0, -1.0], + [2.117400646209717, -1.711801528930664, 0.16513441503047943], + [1.5818675756454468, 0.44846096634864807, 0.033029891550540924] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.0 - ], - [ - 4.4833855628967285, - 2.930264472961426, - 0.027269374579191208 - ], - [ - 2.502305030822754, - 0.20111723244190216, - 0.0010909737320616841 - ] + [0.0, 1.0, 1.0], + [4.4833855628967285, 2.930264472961426, 0.027269374579191208], + [2.502305030822754, 0.20111723244190216, 0.0010909737320616841] ], "expected_grad": [ - [ - 0.0, - 2.0, - -2.0 - ], - [ - 4.234801292419434, - -3.423603057861328, - 0.33026883006095886 - ], - [ - 3.1637351512908936, - 0.8969219326972961, - 0.06605978310108185 - ] + [0.0, 2.0, -2.0], + [4.234801292419434, -3.423603057861328, 0.33026883006095886], + [3.1637351512908936, 0.8969219326972961, 0.06605978310108185] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.6130759119987488, - 0.7763870358467102, - -0.3029157221317291 - ], - [ - -1.2753024101257324, - -0.47575175762176514, - 2.383944511413574 - ] + [0.0, 1.0, -1.0], + [0.6130759119987488, 0.7763870358467102, -0.3029157221317291], + [-1.2753024101257324, -0.47575175762176514, 2.383944511413574] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.3758620619773865, - 0.602776825428009, - 0.09175793826580048 - ], - [ - 1.6263961791992188, - 0.22633972764015198, - 5.683191299438477 - ] + [0.0, 1.0, 1.0], + [0.3758620619773865, 0.602776825428009, 0.09175793826580048], + [1.6263961791992188, 0.22633972764015198, 5.683191299438477] ], "expected_grad": [ - [ - 0.0, - 2.0, - -2.0 - ], - [ - 1.2261518239974976, - 1.5527740716934204, - -0.6058314442634583 - ], - [ - -2.550604820251465, - -0.9515035152435303, - 4.767889022827148 - ] + [0.0, 2.0, -2.0], + [1.2261518239974976, 1.5527740716934204, -0.6058314442634583], + [-2.550604820251465, -0.9515035152435303, 4.767889022827148] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.39997783303260803, - -1.2039215564727783, - -0.41975241899490356 - ], - [ - -1.1928907632827759, - -0.9350629448890686, - 0.2138027846813202 - ] + [0.0, 1.0, -1.0], + [0.39997783303260803, -1.2039215564727783, -0.41975241899490356], + [-1.1928907632827759, -0.9350629448890686, 0.2138027846813202] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.15998226404190063, - 1.4494271278381348, - 0.17619208991527557 - ], - [ - 1.4229884147644043, - 0.8743427395820618, - 0.04571162909269333 - ] + [0.0, 1.0, 1.0], + [0.15998226404190063, 1.4494271278381348, 0.17619208991527557], + [1.4229884147644043, 0.8743427395820618, 0.04571162909269333] ], "expected_grad": [ - [ - 0.0, - 2.0, - -2.0 - ], - [ - 0.7999556660652161, - -2.4078431129455566, - -0.8395048379898071 - ], - [ - -2.3857815265655518, - -1.8701258897781372, - 0.4276055693626404 - ] + [0.0, 2.0, -2.0], + [0.7999556660652161, -2.4078431129455566, -0.8395048379898071], + [-2.3857815265655518, -1.8701258897781372, 0.4276055693626404] ] } ], "abs": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.33552202582359314, - 0.2469366192817688, - 0.03243076428771019 - ], - [ - 0.40568798780441284, - 1.618118405342102, - 0.39315488934516907 - ] + [0.0, 1.0, -1.0], + [0.33552202582359314, 0.2469366192817688, 0.03243076428771019], + [0.40568798780441284, 1.618118405342102, 0.39315488934516907] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.33552202582359314, - 0.2469366192817688, - 0.03243076428771019 - ], - [ - 0.40568798780441284, - 1.618118405342102, - 0.39315488934516907 - ] + [0.0, 1.0, 1.0], + [0.33552202582359314, 0.2469366192817688, 0.03243076428771019], + [0.40568798780441284, 1.618118405342102, 0.39315488934516907] ], "expected_grad": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0 - ] + [0.0, 1.0, -1.0], + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.42791351675987244, - -0.5006903409957886, - -0.1306709349155426 - ], - [ - 0.9795637726783752, - 0.5959771871566772, - -1.4723340272903442 - ] + [0.0, 1.0, -1.0], + [-0.42791351675987244, -0.5006903409957886, -0.1306709349155426], + [0.9795637726783752, 0.5959771871566772, -1.4723340272903442] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.42791351675987244, - 0.5006903409957886, - 0.1306709349155426 - ], - [ - 0.9795637726783752, - 0.5959771871566772, - 1.4723340272903442 - ] + [0.0, 1.0, 1.0], + [0.42791351675987244, 0.5006903409957886, 0.1306709349155426], + [0.9795637726783752, 0.5959771871566772, 1.4723340272903442] ], "expected_grad": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ], - [ - 1.0, - 1.0, - -1.0 - ] + [0.0, 1.0, -1.0], + [-1.0, -1.0, -1.0], + [1.0, 1.0, -1.0] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.14468061923980713, - 1.2818045616149902, - -1.5952012538909912 - ], - [ - -1.064806342124939, - 0.10553700476884842, - 1.9738837480545044 - ] + [0.0, 1.0, -1.0], + [0.14468061923980713, 1.2818045616149902, -1.5952012538909912], + [-1.064806342124939, 0.10553700476884842, 1.9738837480545044] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.14468061923980713, - 1.2818045616149902, - 1.5952012538909912 - ], - [ - 1.064806342124939, - 0.10553700476884842, - 1.9738837480545044 - ] + [0.0, 1.0, 1.0], + [0.14468061923980713, 1.2818045616149902, 1.5952012538909912], + [1.064806342124939, 0.10553700476884842, 1.9738837480545044] ], "expected_grad": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.0, - 1.0, - -1.0 - ], - [ - -1.0, - 1.0, - 1.0 - ] + [0.0, 1.0, -1.0], + [1.0, 1.0, -1.0], + [-1.0, 1.0, 1.0] ] } ], "sign": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.1562519073486328, - -0.6680524945259094, - 1.2135050296783447 - ], - [ - 0.7923893332481384, - -0.4400617480278015, - 0.4995947778224945 - ] + [0.0, 1.0, -1.0], + [-0.1562519073486328, -0.6680524945259094, 1.2135050296783447], + [0.7923893332481384, -0.4400617480278015, 0.4995947778224945] ], "expected_output": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -1.0, - -1.0, - 1.0 - ], - [ - 1.0, - -1.0, - 1.0 - ] + [0.0, 1.0, -1.0], + [-1.0, -1.0, 1.0], + [1.0, -1.0, 1.0] ], "expected_grad": [ - [ - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0 - ] + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.7485982179641724, - -1.3375409841537476, - 0.6449474096298218 - ], - [ - 0.9652354717254639, - 1.0089688301086426, - -0.033671289682388306 - ] + [0.0, 1.0, -1.0], + [0.7485982179641724, -1.3375409841537476, 0.6449474096298218], + [0.9652354717254639, 1.0089688301086426, -0.033671289682388306] ], "expected_output": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.0, - -1.0, - 1.0 - ], - [ - 1.0, - 1.0, - -1.0 - ] + [0.0, 1.0, -1.0], + [1.0, -1.0, 1.0], + [1.0, 1.0, -1.0] ], "expected_grad": [ - [ - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0 - ] + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -1.7460761070251465, - -0.37421396374702454, - -0.41171613335609436 - ], - [ - -0.8997476696968079, - 0.48207539319992065, - 2.5150909423828125 - ] + [0.0, 1.0, -1.0], + [-1.7460761070251465, -0.37421396374702454, -0.41171613335609436], + [-0.8997476696968079, 0.48207539319992065, 2.5150909423828125] ], "expected_output": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - 1.0, - 1.0 - ] + [0.0, 1.0, -1.0], + [-1.0, -1.0, -1.0], + [-1.0, 1.0, 1.0] ], "expected_grad": [ - [ - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0 - ] + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0], + [0.0, 0.0, 0.0] ] } ], "neg": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.8023788928985596, - 2.924564838409424, - -0.7985216975212097 - ], - [ - -0.5669130086898804, - -0.026701264083385468, - -1.5459672212600708 - ] + [0.0, 1.0, -1.0], + [-0.8023788928985596, 2.924564838409424, -0.7985216975212097], + [-0.5669130086898804, -0.026701264083385468, -1.5459672212600708] ], "expected_output": [ - [ - -0.0, - -1.0, - 1.0 - ], - [ - 0.8023788928985596, - -2.924564838409424, - 0.7985216975212097 - ], - [ - 0.5669130086898804, - 0.026701264083385468, - 1.5459672212600708 - ] + [-0.0, -1.0, 1.0], + [0.8023788928985596, -2.924564838409424, 0.7985216975212097], + [0.5669130086898804, 0.026701264083385468, 1.5459672212600708] ], "expected_grad": [ - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ] + [-1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.1816582977771759, - 0.4279658794403076, - 0.25454989075660706 - ], - [ - 0.06617925316095352, - -1.2704100608825684, - 0.667417049407959 - ] + [0.0, 1.0, -1.0], + [-0.1816582977771759, 0.4279658794403076, 0.25454989075660706], + [0.06617925316095352, -1.2704100608825684, 0.667417049407959] ], "expected_output": [ - [ - -0.0, - -1.0, - 1.0 - ], - [ - 0.1816582977771759, - -0.4279658794403076, - -0.25454989075660706 - ], - [ - -0.06617925316095352, - 1.2704100608825684, - -0.667417049407959 - ] + [-0.0, -1.0, 1.0], + [0.1816582977771759, -0.4279658794403076, -0.25454989075660706], + [-0.06617925316095352, 1.2704100608825684, -0.667417049407959] ], "expected_grad": [ - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ] + [-1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -1.7517130374908447, - -0.1309133768081665, - 1.437826156616211 - ], - [ - -0.154391348361969, - -0.2853364050388336, - -0.1389411836862564 - ] + [0.0, 1.0, -1.0], + [-1.7517130374908447, -0.1309133768081665, 1.437826156616211], + [-0.154391348361969, -0.2853364050388336, -0.1389411836862564] ], "expected_output": [ - [ - -0.0, - -1.0, - 1.0 - ], - [ - 1.7517130374908447, - 0.1309133768081665, - -1.437826156616211 - ], - [ - 0.154391348361969, - 0.2853364050388336, - 0.1389411836862564 - ] + [-0.0, -1.0, 1.0], + [1.7517130374908447, 0.1309133768081665, -1.437826156616211], + [0.154391348361969, 0.2853364050388336, 0.1389411836862564] ], "expected_grad": [ - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0 - ] + [-1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0] ] } ], "reciprocal": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.2561368942260742, - 0.46269556879997253, - -0.315053254365921 - ], - [ - 0.5482434034347534, - 0.03692331537604332, - -0.8128055930137634 - ] + [0.0, 1.0, -1.0], + [1.2561368942260742, 0.46269556879997253, -0.315053254365921], + [0.5482434034347534, 0.03692331537604332, -0.8128055930137634] ], "expected_output": [ - [ - Infinity, - 1.0, - -1.0 - ], - [ - 0.7960915565490723, - 2.161248207092285, - -3.1740665435791016 - ], - [ - 1.8240073919296265, - 27.083158493041992, - -1.2303065061569214 - ] + [Infinity, 1.0, -1.0], + [0.7960915565490723, 2.161248207092285, -3.1740665435791016], + [1.8240073919296265, 27.083158493041992, -1.2303065061569214] ], "expected_grad": [ - [ - -Infinity, - -1.0, - -1.0 - ], - [ - -0.6337617635726929, - -4.670993804931641, - -10.074698448181152 - ], - [ - -3.327003002166748, - -733.4974975585938, - -1.513654112815857 - ] + [-Infinity, -1.0, -1.0], + [-0.6337617635726929, -4.670993804931641, -10.074698448181152], + [-3.327003002166748, -733.4974975585938, -1.513654112815857] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.5963875651359558, - 0.7354843616485596, - 0.0723138153553009 - ], - [ - 1.8586984872817993, - -0.3944927752017975, - 0.7613471746444702 - ] + [0.0, 1.0, -1.0], + [-0.5963875651359558, 0.7354843616485596, 0.0723138153553009], + [1.8586984872817993, -0.3944927752017975, 0.7613471746444702] ], "expected_output": [ - [ - Infinity, - 1.0, - -1.0 - ], - [ - -1.6767619848251343, - 1.3596482276916504, - 13.82861614227295 - ], - [ - 0.5380108952522278, - -2.534900665283203, - 1.313461184501648 - ] + [Infinity, 1.0, -1.0], + [-1.6767619848251343, 1.3596482276916504, 13.82861614227295], + [0.5380108952522278, -2.534900665283203, 1.313461184501648] ], "expected_grad": [ - [ - -Infinity, - -1.0, - -1.0 - ], - [ - -2.811530828475952, - -1.8486433029174805, - -191.23062133789062 - ], - [ - -0.28945571184158325, - -6.425721168518066, - -1.7251802682876587 - ] + [-Infinity, -1.0, -1.0], + [-2.811530828475952, -1.8486433029174805, -191.23062133789062], + [-0.28945571184158325, -6.425721168518066, -1.7251802682876587] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.018282217904925346, - -0.049032170325517654, - 0.17692552506923676 - ], - [ - 0.8319899439811707, - -2.008758783340454, - -0.5569353103637695 - ] + [0.0, 1.0, -1.0], + [0.018282217904925346, -0.049032170325517654, 0.17692552506923676], + [0.8319899439811707, -2.008758783340454, -0.5569353103637695] ], "expected_output": [ - [ - Infinity, - 1.0, - -1.0 - ], - [ - 54.697959899902344, - -20.394773483276367, - 5.652095794677734 - ], - [ - 1.2019375562667847, - -0.49781984090805054, - -1.795540690422058 - ] + [Infinity, 1.0, -1.0], + [54.697959899902344, -20.394773483276367, 5.652095794677734], + [1.2019375562667847, -0.49781984090805054, -1.795540690422058] ], "expected_grad": [ - [ - -Infinity, - -1.0, - -1.0 - ], - [ - -2991.86669921875, - -415.94677734375, - -31.946186065673828 - ], - [ - -1.444653868675232, - -0.24782459437847137, - -3.223966360092163 - ] + [-Infinity, -1.0, -1.0], + [-2991.86669921875, -415.94677734375, -31.946186065673828], + [-1.444653868675232, -0.24782459437847137, -3.223966360092163] ] } ], "sin": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.21935275197029114, - 0.5447354912757874, - -2.056748628616333 - ], - [ - 0.23443682491779327, - -0.34069985151290894, - 1.0171456336975098 - ] + [0.0, 1.0, -1.0], + [0.21935275197029114, 0.5447354912757874, -2.056748628616333], + [0.23443682491779327, -0.34069985151290894, 1.0171456336975098] ], "expected_output": [ - [ - 0.0, - 0.8414709568023682, - -0.8414709568023682 - ], - [ - 0.21759793162345886, - 0.5181918740272522, - -0.8842305541038513 - ], - [ - 0.23229525983333588, - -0.33414679765701294, - 0.8506106734275818 - ] + [0.0, 0.8414709568023682, -0.8414709568023682], + [0.21759793162345886, 0.5181918740272522, -0.8842305541038513], + [0.23229525983333588, -0.33414679765701294, 0.8506106734275818] ], "expected_grad": [ - [ - 1.0, - 0.5403023362159729, - 0.5403023362159729 - ], - [ - 0.9760385155677795, - 0.8552643656730652, - -0.4670506417751312 - ], - [ - 0.9726453423500061, - 0.9425210356712341, - 0.5257960557937622 - ] + [1.0, 0.5403023362159729, 0.5403023362159729], + [0.9760385155677795, 0.8552643656730652, -0.4670506417751312], + [0.9726453423500061, 0.9425210356712341, 0.5257960557937622] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.1056941747665405, - -0.6886897087097168, - 0.1491728127002716 - ], - [ - -1.0009846687316895, - -1.501810908317566, - 0.00793869886547327 - ] + [0.0, 1.0, -1.0], + [1.1056941747665405, -0.6886897087097168, 0.1491728127002716], + [-1.0009846687316895, -1.501810908317566, 0.00793869886547327] ], "expected_output": [ - [ - 0.0, - 0.8414709568023682, - -0.8414709568023682 - ], - [ - 0.8937757611274719, - -0.6355260610580444, - 0.14862018823623657 - ], - [ - -0.8420025706291199, - -0.9976214170455933, - 0.007938615046441555 - ] + [0.0, 0.8414709568023682, -0.8414709568023682], + [0.8937757611274719, -0.6355260610580444, 0.14862018823623657], + [-0.8420025706291199, -0.9976214170455933, 0.007938615046441555] ], "expected_grad": [ - [ - 1.0, - 0.5403023362159729, - 0.5403023362159729 - ], - [ - 0.44851410388946533, - 0.7720794081687927, - 0.9888943433761597 - ], - [ - 0.5394734740257263, - 0.0689307153224945, - 0.9999684691429138 - ] + [1.0, 0.5403023362159729, 0.5403023362159729], + [0.44851410388946533, 0.7720794081687927, 0.9888943433761597], + [0.5394734740257263, 0.0689307153224945, 0.9999684691429138] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.24461546540260315, - 1.4372375011444092, - -0.706683874130249 - ], - [ - 1.3421580791473389, - 0.5234800577163696, - -0.26403290033340454 - ] + [0.0, 1.0, -1.0], + [0.24461546540260315, 1.4372375011444092, -0.706683874130249], + [1.3421580791473389, 0.5234800577163696, -0.26403290033340454] ], "expected_output": [ - [ - 0.0, - 0.8414709568023682, - -0.8414709568023682 - ], - [ - 0.24218325316905975, - 0.9910942912101746, - -0.649315357208252 - ], - [ - 0.9739759564399719, - 0.49989718198776245, - -0.26097580790519714 - ] + [0.0, 0.8414709568023682, -0.8414709568023682], + [0.24218325316905975, 0.9910942912101746, -0.649315357208252], + [0.9739759564399719, 0.49989718198776245, -0.26097580790519714] ], "expected_grad": [ - [ - 1.0, - 0.5403023362159729, - 0.5403023362159729 - ], - [ - 0.9702305197715759, - 0.13316211104393005, - 0.76051926612854 - ], - [ - 0.2266514152288437, - 0.8660847544670105, - 0.9653453230857849 - ] + [1.0, 0.5403023362159729, 0.5403023362159729], + [0.9702305197715759, 0.13316211104393005, 0.76051926612854], + [0.2266514152288437, 0.8660847544670105, 0.9653453230857849] ] } ], "cos": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 1.3824070692062378, - -0.7471941709518433, - -2.5696442127227783 - ], - [ - 0.10177755355834961, - 1.4807320833206177, - 0.29541370272636414 - ] + [0.0, 1.0, -1.0], + [1.3824070692062378, -0.7471941709518433, -2.5696442127227783], + [0.10177755355834961, 1.4807320833206177, 0.29541370272636414] ], "expected_output": [ - [ - 1.0, - 0.5403023362159729, - 0.5403023362159729 - ], - [ - 0.1872768998146057, - 0.733598530292511, - -0.840847909450531 - ], - [ - 0.9948251247406006, - 0.08994252979755402, - 0.9566817879676819 - ] + [1.0, 0.5403023362159729, 0.5403023362159729], + [0.1872768998146057, 0.733598530292511, -0.840847909450531], + [0.9948251247406006, 0.08994252979755402, 0.9566817879676819] ], "expected_grad": [ - [ - -0.0, - -0.8414709568023682, - 0.8414709568023682 - ], - [ - -0.9823071956634521, - 0.6795830726623535, - 0.541271448135376 - ], - [ - -0.10160192847251892, - -0.9959469437599182, - -0.29113566875457764 - ] + [-0.0, -0.8414709568023682, 0.8414709568023682], + [-0.9823071956634521, 0.6795830726623535, 0.541271448135376], + [-0.10160192847251892, -0.9959469437599182, -0.29113566875457764] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.6161983609199524, - 0.0354895144701004, - 1.124637246131897 - ], - [ - -0.18692852556705475, - 0.017339814454317093, - -1.3771003484725952 - ] + [0.0, 1.0, -1.0], + [0.6161983609199524, 0.0354895144701004, 1.124637246131897], + [-0.18692852556705475, 0.017339814454317093, -1.3771003484725952] ], "expected_output": [ - [ - 1.0, - 0.5403023362159729, - 0.5403023362159729 - ], - [ - 0.8160814642906189, - 0.9993703365325928, - 0.4315038025379181 - ], - [ - 0.9825797080993652, - 0.9998496770858765, - 0.19248706102371216 - ] + [1.0, 0.5403023362159729, 0.5403023362159729], + [0.8160814642906189, 0.9993703365325928, 0.4315038025379181], + [0.9825797080993652, 0.9998496770858765, 0.19248706102371216] ], "expected_grad": [ - [ - -0.0, - -0.8414709568023682, - 0.8414709568023682 - ], - [ - -0.5779368877410889, - -0.03548206388950348, - -0.9021111130714417 - ], - [ - 0.18584181368350983, - -0.01733894646167755, - 0.9812995195388794 - ] + [-0.0, -0.8414709568023682, 0.8414709568023682], + [-0.5779368877410889, -0.03548206388950348, -0.9021111130714417], + [0.18584181368350983, -0.01733894646167755, 0.9812995195388794] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.2835264801979065, - -0.34251856803894043, - -1.5208441019058228 - ], - [ - 0.11262339353561401, - 0.061174698173999786, - 0.8015474677085876 - ] + [0.0, 1.0, -1.0], + [0.2835264801979065, -0.34251856803894043, -1.5208441019058228], + [0.11262339353561401, 0.061174698173999786, 0.8015474677085876] ], "expected_output": [ - [ - 1.0, - 0.5403023362159729, - 0.5403023362159729 - ], - [ - 0.9600749015808105, - 0.9419117569923401, - 0.04993145540356636 - ], - [ - 0.9936646819114685, - 0.9981294274330139, - 0.6955958008766174 - ] + [1.0, 0.5403023362159729, 0.5403023362159729], + [0.9600749015808105, 0.9419117569923401, 0.04993145540356636], + [0.9936646819114685, 0.9981294274330139, 0.6955958008766174] ], "expected_grad": [ - [ - -0.0, - -0.8414709568023682, - 0.8414709568023682 - ], - [ - -0.2797430753707886, - 0.3358604311943054, - 0.9987526535987854 - ], - [ - -0.11238545924425125, - -0.06113654747605324, - -0.7184333801269531 - ] + [-0.0, -0.8414709568023682, 0.8414709568023682], + [-0.2797430753707886, 0.3358604311943054, 0.9987526535987854], + [-0.11238545924425125, -0.06113654747605324, -0.7184333801269531] ] } ], "tan": [ { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - -0.8692201972007751, - 0.06136707961559296, - 0.46790215373039246 - ], - [ - 0.43584781885147095, - -0.28228023648262024, - -1.2118933200836182 - ] + [0.0, 1.0, -1.0], + [-0.8692201972007751, 0.06136707961559296, 0.46790215373039246], + [0.43584781885147095, -0.28228023648262024, -1.2118933200836182] ], "expected_output": [ - [ - 0.0, - 1.5574077367782593, - -1.5574077367782593 - ], - [ - -1.1834511756896973, - 0.0614442303776741, - 0.5053295493125916 - ], - [ - 0.46571794152259827, - -0.2900247275829315, - -2.6655936241149902 - ] + [0.0, 1.5574077367782593, -1.5574077367782593], + [-1.1834511756896973, 0.0614442303776741, 0.5053295493125916], + [0.46571794152259827, -0.2900247275829315, -2.6655936241149902] ], "expected_grad": [ - [ - 1.0, - 3.425518751144409, - 3.425518751144409 - ], - [ - 2.4005565643310547, - 1.0037753582000732, - 1.2553579807281494 - ], - [ - 1.216893196105957, - 1.0841143131256104, - 8.105389595031738 - ] + [1.0, 3.425518751144409, 3.425518751144409], + [2.4005565643310547, 1.0037753582000732, 1.2553579807281494], + [1.216893196105957, 1.0841143131256104, 8.105389595031738] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.391975462436676, - 1.06540846824646, - -0.5663558840751648 - ], - [ - 1.2495359182357788, - -0.8697574734687805, - -0.25120875239372253 - ] + [0.0, 1.0, -1.0], + [0.391975462436676, 1.06540846824646, -0.5663558840751648], + [1.2495359182357788, -0.8697574734687805, -0.25120875239372253] ], "expected_output": [ - [ - 0.0, - 1.5574077367782593, - -1.5574077367782593 - ], - [ - 0.41336604952812195, - 1.8072755336761475, - -0.6358392238616943 - ], - [ - 3.004908561706543, - -1.184741735458374, - -0.2566298842430115 - ] + [0.0, 1.5574077367782593, -1.5574077367782593], + [0.41336604952812195, 1.8072755336761475, -0.6358392238616943], + [3.004908561706543, -1.184741735458374, -0.2566298842430115] ], "expected_grad": [ - [ - 1.0, - 3.425518751144409, - 3.425518751144409 - ], - [ - 1.1708714962005615, - 4.266244888305664, - 1.4042915105819702 - ], - [ - 10.029475212097168, - 2.4036130905151367, - 1.0658588409423828 - ] + [1.0, 3.425518751144409, 3.425518751144409], + [1.1708714962005615, 4.266244888305664, 1.4042915105819702], + [10.029475212097168, 2.4036130905151367, 1.0658588409423828] ] }, { "input": [ - [ - 0.0, - 1.0, - -1.0 - ], - [ - 0.2562393546104431, - -0.5835933685302734, - -1.3709070682525635 - ], - [ - 0.23866742849349976, - 1.248494029045105, - 0.05098257213830948 - ] + [0.0, 1.0, -1.0], + [0.2562393546104431, -0.5835933685302734, -1.3709070682525635], + [0.23866742849349976, 1.248494029045105, 0.05098257213830948] ], "expected_output": [ - [ - 0.0, - 1.5574077367782593, - -1.5574077367782593 - ], - [ - 0.2619987726211548, - -0.6603164076805115, - -4.935962200164795 - ], - [ - 0.2433047890663147, - 2.9944915771484375, - 0.05102679133415222 - ] + [0.0, 1.5574077367782593, -1.5574077367782593], + [0.2619987726211548, -0.6603164076805115, -4.935962200164795], + [0.2433047890663147, 2.9944915771484375, 0.05102679133415222] ], "expected_grad": [ - [ - 1.0, - 3.425518751144409, - 3.425518751144409 - ], - [ - 1.06864333152771, - 1.4360177516937256, - 25.363723754882812 - ], - [ - 1.059197187423706, - 9.96697998046875, - 1.0026037693023682 - ] + [1.0, 3.425518751144409, 3.425518751144409], + [1.06864333152771, 1.4360177516937256, 25.363723754882812], + [1.059197187423706, 9.96697998046875, 1.0026037693023682] ] } ] @@ -1776,2786 +588,686 @@ export const testData = { "add": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -1.1133604049682617 - ], - [ - 0.0, - 1.0, - -1.0, - 0.2570752799510956 - ], - [ - 0.6377718448638916, - 0.15978877246379852, - 1.7697970867156982, - 0.6268176436424255 - ], - [ - -0.4976125955581665, - -0.18228091299533844, - -0.21200162172317505, - 0.8162168264389038 - ] + [0.0, 1.0, -1.0, -1.1133604049682617], + [0.0, 1.0, -1.0, 0.2570752799510956], + [0.6377718448638916, 0.15978877246379852, 1.7697970867156982, 0.6268176436424255], + [-0.4976125955581665, -0.18228091299533844, -0.21200162172317505, 0.8162168264389038] ], "input_y": [ - [ - 0.0, - 0.0, - 1.294582724571228, - 0.22267311811447144 - ], - [ - 1.0, - 1.0, - -0.8326117396354675, - -0.8129478096961975 - ], - [ - -1.0, - -1.0, - 0.7637977004051208, - 1.1792222261428833 - ], - [ - 0.08301948755979538, - 0.4220196604728699, - 0.3418477773666382, - -2.701582431793213 - ] + [0.0, 0.0, 1.294582724571228, 0.22267311811447144], + [1.0, 1.0, -0.8326117396354675, -0.8129478096961975], + [-1.0, -1.0, 0.7637977004051208, 1.1792222261428833], + [0.08301948755979538, 0.4220196604728699, 0.3418477773666382, -2.701582431793213] ], "expected_output": [ - [ - 0.0, - 1.0, - 0.294582724571228, - -0.8906872868537903 - ], - [ - 1.0, - 2.0, - -1.8326117992401123, - -0.5558725595474243 - ], - [ - -0.3622281551361084, - -0.8402112126350403, - 2.533594846725464, - 1.806039810180664 - ], - [ - -0.4145931005477905, - 0.23973874747753143, - 0.12984615564346313, - -1.885365605354309 - ] + [0.0, 1.0, 0.294582724571228, -0.8906872868537903], + [1.0, 2.0, -1.8326117992401123, -0.5558725595474243], + [-0.3622281551361084, -0.8402112126350403, 2.533594846725464, 1.806039810180664], + [-0.4145931005477905, 0.23973874747753143, 0.12984615564346313, -1.885365605354309] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.5786357522010803 - ], - [ - 0.0, - 1.0, - -1.0, - 0.3255786597728729 - ], - [ - 0.043896086513996124, - 1.4443233013153076, - 0.23202891647815704, - 0.5064983367919922 - ], - [ - -0.9177634716033936, - 0.42056551575660706, - -0.368858277797699, - -0.7696145176887512 - ] + [0.0, 1.0, -1.0, -0.5786357522010803], + [0.0, 1.0, -1.0, 0.3255786597728729], + [0.043896086513996124, 1.4443233013153076, 0.23202891647815704, 0.5064983367919922], + [-0.9177634716033936, 0.42056551575660706, -0.368858277797699, -0.7696145176887512] ], "input_y": [ - [ - 0.0, - 0.0, - -1.190559983253479, - 0.7756073474884033 - ], - [ - 1.0, - 1.0, - -1.881459355354309, - 0.5850948691368103 - ], - [ - -1.0, - -1.0, - -0.8708454966545105, - -0.6410972476005554 - ], - [ - 0.5373784899711609, - 0.7817491888999939, - 1.0477299690246582, - -0.39480558037757874 - ] + [0.0, 0.0, -1.190559983253479, 0.7756073474884033], + [1.0, 1.0, -1.881459355354309, 0.5850948691368103], + [-1.0, -1.0, -0.8708454966545105, -0.6410972476005554], + [0.5373784899711609, 0.7817491888999939, 1.0477299690246582, -0.39480558037757874] ], "expected_output": [ - [ - 0.0, - 1.0, - -2.1905598640441895, - 0.196971595287323 - ], - [ - 1.0, - 2.0, - -2.8814592361450195, - 0.9106734991073608 - ], - [ - -0.9561039209365845, - 0.4443233013153076, - -0.6388165950775146, - -0.13459891080856323 - ], - [ - -0.38038498163223267, - 1.2023147344589233, - 0.6788716912269592, - -1.1644201278686523 - ] + [0.0, 1.0, -2.1905598640441895, 0.196971595287323], + [1.0, 2.0, -2.8814592361450195, 0.9106734991073608], + [-0.9561039209365845, 0.4443233013153076, -0.6388165950775146, -0.13459891080856323], + [-0.38038498163223267, 1.2023147344589233, 0.6788716912269592, -1.1644201278686523] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.29864323139190674 - ], - [ - 0.0, - 1.0, - -1.0, - 0.881690502166748 - ], - [ - -0.518220841884613, - 0.83954256772995, - 0.05852266773581505, - -1.6682480573654175 - ], - [ - -0.019966987892985344, - -1.2131143808364868, - 1.197104811668396, - -0.7817718386650085 - ] + [0.0, 1.0, -1.0, -0.29864323139190674], + [0.0, 1.0, -1.0, 0.881690502166748], + [-0.518220841884613, 0.83954256772995, 0.05852266773581505, -1.6682480573654175], + [-0.019966987892985344, -1.2131143808364868, 1.197104811668396, -0.7817718386650085] ], "input_y": [ - [ - 0.0, - 0.0, - 0.2794382870197296, - -0.5718191266059875 - ], - [ - 1.0, - 1.0, - -0.37528103590011597, - 1.446703553199768 - ], - [ - -1.0, - -1.0, - 0.12306158244609833, - 0.8757511377334595 - ], - [ - 0.21162617206573486, - 1.2271368503570557, - -0.5722804665565491, - -0.17070035636425018 - ] + [0.0, 0.0, 0.2794382870197296, -0.5718191266059875], + [1.0, 1.0, -0.37528103590011597, 1.446703553199768], + [-1.0, -1.0, 0.12306158244609833, 0.8757511377334595], + [0.21162617206573486, 1.2271368503570557, -0.5722804665565491, -0.17070035636425018] ], "expected_output": [ - [ - 0.0, - 1.0, - -0.7205617427825928, - -0.8704623579978943 - ], - [ - 1.0, - 2.0, - -1.3752810955047607, - 2.3283939361572266 - ], - [ - -1.5182209014892578, - -0.16045743227005005, - 0.18158425390720367, - -0.792496919631958 - ], - [ - 0.19165918231010437, - 0.014022469520568848, - 0.6248243451118469, - -0.9524722099304199 - ] + [0.0, 1.0, -0.7205617427825928, -0.8704623579978943], + [1.0, 2.0, -1.3752810955047607, 2.3283939361572266], + [-1.5182209014892578, -0.16045743227005005, 0.18158425390720367, -0.792496919631958], + [0.19165918231010437, 0.014022469520568848, 0.6248243451118469, -0.9524722099304199] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ] } ], "sub": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 1.541925072669983 - ], - [ - 0.0, - 1.0, - -1.0, - -1.3860632181167603 - ], - [ - -1.2519514560699463, - 3.0250484943389893, - 1.3462589979171753, - 0.8556069731712341 - ], - [ - -1.525596261024475, - 1.2538059949874878, - -0.684340238571167, - -2.121647357940674 - ] + [0.0, 1.0, -1.0, 1.541925072669983], + [0.0, 1.0, -1.0, -1.3860632181167603], + [-1.2519514560699463, 3.0250484943389893, 1.3462589979171753, 0.8556069731712341], + [-1.525596261024475, 1.2538059949874878, -0.684340238571167, -2.121647357940674] ], "input_y": [ - [ - 0.0, - 0.0, - -0.4809381365776062, - -0.9903622269630432 - ], - [ - 1.0, - 1.0, - -1.0486466884613037, - 1.7823078632354736 - ], - [ - -1.0, - -1.0, - 0.9993040561676025, - 1.2751853466033936 - ], - [ - 1.2704023122787476, - -0.07503493875265121, - -2.2949612140655518, - -1.3630598783493042 - ] + [0.0, 0.0, -0.4809381365776062, -0.9903622269630432], + [1.0, 1.0, -1.0486466884613037, 1.7823078632354736], + [-1.0, -1.0, 0.9993040561676025, 1.2751853466033936], + [1.2704023122787476, -0.07503493875265121, -2.2949612140655518, -1.3630598783493042] ], "expected_output": [ - [ - 0.0, - 1.0, - -0.5190618634223938, - 2.532287359237671 - ], - [ - -1.0, - 0.0, - 0.04864668846130371, - -3.1683712005615234 - ], - [ - -0.2519514560699463, - 4.02504825592041, - 0.34695494174957275, - -0.4195783734321594 - ], - [ - -2.7959985733032227, - 1.328840970993042, - 1.6106209754943848, - -0.7585874795913696 - ] + [0.0, 1.0, -0.5190618634223938, 2.532287359237671], + [-1.0, 0.0, 0.04864668846130371, -3.1683712005615234], + [-0.2519514560699463, 4.02504825592041, 0.34695494174957275, -0.4195783734321594], + [-2.7959985733032227, 1.328840970993042, 1.6106209754943848, -0.7585874795913696] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ] + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 0.3547132909297943 - ], - [ - 0.0, - 1.0, - -1.0, - 0.22359032928943634 - ], - [ - 0.34287506341934204, - -1.4590637683868408, - -1.4936561584472656, - -0.22138521075248718 - ], - [ - 0.12097510695457458, - 0.5535293817520142, - -1.9203240871429443, - -0.09706467390060425 - ] + [0.0, 1.0, -1.0, 0.3547132909297943], + [0.0, 1.0, -1.0, 0.22359032928943634], + [0.34287506341934204, -1.4590637683868408, -1.4936561584472656, -0.22138521075248718], + [0.12097510695457458, 0.5535293817520142, -1.9203240871429443, -0.09706467390060425] ], "input_y": [ - [ - 0.0, - 0.0, - -0.8097057938575745, - -1.4298604726791382 - ], - [ - 1.0, - 1.0, - 1.8783389329910278, - 0.18154054880142212 - ], - [ - -1.0, - -1.0, - -1.2370758056640625, - -2.301875114440918 - ], - [ - 0.6071491837501526, - 0.034609485417604446, - -0.5123788118362427, - 0.5574127435684204 - ] + [0.0, 0.0, -0.8097057938575745, -1.4298604726791382], + [1.0, 1.0, 1.8783389329910278, 0.18154054880142212], + [-1.0, -1.0, -1.2370758056640625, -2.301875114440918], + [0.6071491837501526, 0.034609485417604446, -0.5123788118362427, 0.5574127435684204] ], "expected_output": [ - [ - 0.0, - 1.0, - -0.19029420614242554, - 1.7845737934112549 - ], - [ - -1.0, - 0.0, - -2.8783388137817383, - 0.04204978048801422 - ], - [ - 1.3428750038146973, - -0.4590637683868408, - -0.2565803527832031, - 2.0804898738861084 - ], - [ - -0.486174076795578, - 0.5189198851585388, - -1.4079452753067017, - -0.6544774174690247 - ] + [0.0, 1.0, -0.19029420614242554, 1.7845737934112549], + [-1.0, 0.0, -2.8783388137817383, 0.04204978048801422], + [1.3428750038146973, -0.4590637683868408, -0.2565803527832031, 2.0804898738861084], + [-0.486174076795578, 0.5189198851585388, -1.4079452753067017, -0.6544774174690247] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ] + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 2.8543806076049805 - ], - [ - 0.0, - 1.0, - -1.0, - -0.18887265026569366 - ], - [ - 0.0696544423699379, - -1.6034338474273682, - -0.42982181906700134, - 0.5761587619781494 - ], - [ - 0.682919979095459, - -0.035719022154808044, - -0.8881044387817383, - -0.5891188979148865 - ] + [0.0, 1.0, -1.0, 2.8543806076049805], + [0.0, 1.0, -1.0, -0.18887265026569366], + [0.0696544423699379, -1.6034338474273682, -0.42982181906700134, 0.5761587619781494], + [0.682919979095459, -0.035719022154808044, -0.8881044387817383, -0.5891188979148865] ], "input_y": [ - [ - 0.0, - 0.0, - -0.7190185785293579, - -0.38583096861839294 - ], - [ - 1.0, - 1.0, - 0.09291388839483261, - -0.7843634486198425 - ], - [ - -1.0, - -1.0, - -0.7668924331665039, - -0.9494866728782654 - ], - [ - 0.58314448595047, - 0.033020101487636566, - -1.2597709894180298, - -0.7298099398612976 - ] + [0.0, 0.0, -0.7190185785293579, -0.38583096861839294], + [1.0, 1.0, 0.09291388839483261, -0.7843634486198425], + [-1.0, -1.0, -0.7668924331665039, -0.9494866728782654], + [0.58314448595047, 0.033020101487636566, -1.2597709894180298, -0.7298099398612976] ], "expected_output": [ - [ - 0.0, - 1.0, - -0.2809814214706421, - 3.2402114868164062 - ], - [ - -1.0, - 0.0, - -1.0929138660430908, - 0.5954908132553101 - ], - [ - 1.0696544647216797, - -0.6034338474273682, - 0.33707061409950256, - 1.5256454944610596 - ], - [ - 0.09977549314498901, - -0.06873912364244461, - 0.3716665506362915, - 0.14069104194641113 - ] + [0.0, 1.0, -0.2809814214706421, 3.2402114868164062], + [-1.0, 0.0, -1.0929138660430908, 0.5954908132553101], + [1.0696544647216797, -0.6034338474273682, 0.33707061409950256, 1.5256454944610596], + [0.09977549314498901, -0.06873912364244461, 0.3716665506362915, 0.14069104194641113] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ], - [ - -1.0, - -1.0, - -1.0, - -1.0 - ] + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0], + [-1.0, -1.0, -1.0, -1.0] ] } ], "mul": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 1.9025356769561768 - ], - [ - 0.0, - 1.0, - -1.0, - 0.06751081347465515 - ], - [ - 0.7401772737503052, - 1.4161995649337769, - 0.6833979487419128, - -0.13825182616710663 - ], - [ - 0.9863895177841187, - -0.3892551064491272, - 0.6138074398040771, - -0.2786312699317932 - ] + [0.0, 1.0, -1.0, 1.9025356769561768], + [0.0, 1.0, -1.0, 0.06751081347465515], + [0.7401772737503052, 1.4161995649337769, 0.6833979487419128, -0.13825182616710663], + [0.9863895177841187, -0.3892551064491272, 0.6138074398040771, -0.2786312699317932] ], "input_y": [ - [ - 0.0, - 0.0, - 0.19955870509147644, - -1.2461947202682495 - ], - [ - 1.0, - 1.0, - -0.5218439698219299, - 0.8302035331726074 - ], - [ - -1.0, - -1.0, - -1.2894343137741089, - 1.0762810707092285 - ], - [ - -2.2878637313842773, - -0.48340824246406555, - 0.5599985718727112, - -1.0602329969406128 - ] + [0.0, 0.0, 0.19955870509147644, -1.2461947202682495], + [1.0, 1.0, -0.5218439698219299, 0.8302035331726074], + [-1.0, -1.0, -1.2894343137741089, 1.0762810707092285], + [-2.2878637313842773, -0.48340824246406555, 0.5599985718727112, -1.0602329969406128] ], "expected_output": [ - [ - 0.0, - 0.0, - -0.19955870509147644, - -2.3709299564361572 - ], - [ - 0.0, - 1.0, - 0.5218439698219299, - 0.0560477152466774 - ], - [ - -0.7401772737503052, - -1.4161995649337769, - -0.8811967372894287, - -0.14879782497882843 - ], - [ - -2.2567248344421387, - 0.18816912174224854, - 0.3437312841415405, - 0.2954140603542328 - ] + [0.0, 0.0, -0.19955870509147644, -2.3709299564361572], + [0.0, 1.0, 0.5218439698219299, 0.0560477152466774], + [-0.7401772737503052, -1.4161995649337769, -0.8811967372894287, -0.14879782497882843], + [-2.2567248344421387, 0.18816912174224854, 0.3437312841415405, 0.2954140603542328] ], "expected_grad_x": [ - [ - 0.0, - 0.0, - 0.19955870509147644, - -1.2461947202682495 - ], - [ - 1.0, - 1.0, - -0.5218439698219299, - 0.8302035331726074 - ], - [ - -1.0, - -1.0, - -1.2894343137741089, - 1.0762810707092285 - ], - [ - -2.2878637313842773, - -0.48340824246406555, - 0.5599985718727112, - -1.0602329969406128 - ] + [0.0, 0.0, 0.19955870509147644, -1.2461947202682495], + [1.0, 1.0, -0.5218439698219299, 0.8302035331726074], + [-1.0, -1.0, -1.2894343137741089, 1.0762810707092285], + [-2.2878637313842773, -0.48340824246406555, 0.5599985718727112, -1.0602329969406128] ], "expected_grad_y": [ - [ - 0.0, - 1.0, - -1.0, - 1.9025356769561768 - ], - [ - 0.0, - 1.0, - -1.0, - 0.06751081347465515 - ], - [ - 0.7401772737503052, - 1.4161995649337769, - 0.6833979487419128, - -0.13825182616710663 - ], - [ - 0.9863895177841187, - -0.3892551064491272, - 0.6138074398040771, - -0.2786312699317932 - ] + [0.0, 1.0, -1.0, 1.9025356769561768], + [0.0, 1.0, -1.0, 0.06751081347465515], + [0.7401772737503052, 1.4161995649337769, 0.6833979487419128, -0.13825182616710663], + [0.9863895177841187, -0.3892551064491272, 0.6138074398040771, -0.2786312699317932] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.7554785013198853 - ], - [ - 0.0, - 1.0, - -1.0, - -0.008815222419798374 - ], - [ - -1.6514869928359985, - 2.1477253437042236, - -0.6604134440422058, - 0.11352583765983582 - ], - [ - 0.35569247603416443, - 1.2056455612182617, - 1.3690308332443237, - -0.6949581503868103 - ] + [0.0, 1.0, -1.0, -0.7554785013198853], + [0.0, 1.0, -1.0, -0.008815222419798374], + [-1.6514869928359985, 2.1477253437042236, -0.6604134440422058, 0.11352583765983582], + [0.35569247603416443, 1.2056455612182617, 1.3690308332443237, -0.6949581503868103] ], "input_y": [ - [ - 0.0, - 0.0, - -1.2322070598602295, - -0.598077118396759 - ], - [ - 1.0, - 1.0, - -0.23776796460151672, - -0.1013922467827797 - ], - [ - -1.0, - -1.0, - -0.595004141330719, - 0.3926331400871277 - ], - [ - -1.4313503503799438, - -0.039798520505428314, - -0.5003415942192078, - 0.2930373251438141 - ] + [0.0, 0.0, -1.2322070598602295, -0.598077118396759], + [1.0, 1.0, -0.23776796460151672, -0.1013922467827797], + [-1.0, -1.0, -0.595004141330719, 0.3926331400871277], + [-1.4313503503799438, -0.039798520505428314, -0.5003415942192078, 0.2930373251438141] ], "expected_output": [ - [ - 0.0, - 0.0, - 1.2322070598602295, - 0.45183441042900085 - ], - [ - 0.0, - 1.0, - 0.23776796460151672, - 0.0008937952225096524 - ], - [ - 1.6514869928359985, - -2.1477253437042236, - 0.3929487466812134, - 0.044574007391929626 - ], - [ - -0.509120523929596, - -0.04798290878534317, - -0.6849830746650696, - -0.2036486715078354 - ] + [0.0, 0.0, 1.2322070598602295, 0.45183441042900085], + [0.0, 1.0, 0.23776796460151672, 0.0008937952225096524], + [1.6514869928359985, -2.1477253437042236, 0.3929487466812134, 0.044574007391929626], + [-0.509120523929596, -0.04798290878534317, -0.6849830746650696, -0.2036486715078354] ], "expected_grad_x": [ - [ - 0.0, - 0.0, - -1.2322070598602295, - -0.598077118396759 - ], - [ - 1.0, - 1.0, - -0.23776796460151672, - -0.1013922467827797 - ], - [ - -1.0, - -1.0, - -0.595004141330719, - 0.3926331400871277 - ], - [ - -1.4313503503799438, - -0.039798520505428314, - -0.5003415942192078, - 0.2930373251438141 - ] + [0.0, 0.0, -1.2322070598602295, -0.598077118396759], + [1.0, 1.0, -0.23776796460151672, -0.1013922467827797], + [-1.0, -1.0, -0.595004141330719, 0.3926331400871277], + [-1.4313503503799438, -0.039798520505428314, -0.5003415942192078, 0.2930373251438141] ], "expected_grad_y": [ - [ - 0.0, - 1.0, - -1.0, - -0.7554785013198853 - ], - [ - 0.0, - 1.0, - -1.0, - -0.008815222419798374 - ], - [ - -1.6514869928359985, - 2.1477253437042236, - -0.6604134440422058, - 0.11352583765983582 - ], - [ - 0.35569247603416443, - 1.2056455612182617, - 1.3690308332443237, - -0.6949581503868103 - ] + [0.0, 1.0, -1.0, -0.7554785013198853], + [0.0, 1.0, -1.0, -0.008815222419798374], + [-1.6514869928359985, 2.1477253437042236, -0.6604134440422058, 0.11352583765983582], + [0.35569247603416443, 1.2056455612182617, 1.3690308332443237, -0.6949581503868103] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.13413065671920776 - ], - [ - 0.0, - 1.0, - -1.0, - -1.5807840824127197 - ], - [ - -0.15693345665931702, - 1.138344645500183, - -0.2505214214324951, - 1.6704555749893188 - ], - [ - 1.8887592554092407, - -0.7538138628005981, - -1.7142589092254639, - -2.2069785594940186 - ] + [0.0, 1.0, -1.0, -0.13413065671920776], + [0.0, 1.0, -1.0, -1.5807840824127197], + [-0.15693345665931702, 1.138344645500183, -0.2505214214324951, 1.6704555749893188], + [1.8887592554092407, -0.7538138628005981, -1.7142589092254639, -2.2069785594940186] ], "input_y": [ - [ - 0.0, - 0.0, - 0.49674081802368164, - -2.369169235229492 - ], - [ - 1.0, - 1.0, - -0.8810284733772278, - 0.34835284948349 - ], - [ - -1.0, - -1.0, - -0.9705761075019836, - 1.4723693132400513 - ], - [ - -1.3775256872177124, - -1.204437255859375, - -0.48241984844207764, - -0.8164191246032715 - ] + [0.0, 0.0, 0.49674081802368164, -2.369169235229492], + [1.0, 1.0, -0.8810284733772278, 0.34835284948349], + [-1.0, -1.0, -0.9705761075019836, 1.4723693132400513], + [-1.3775256872177124, -1.204437255859375, -0.48241984844207764, -0.8164191246032715] ], "expected_output": [ - [ - 0.0, - 0.0, - -0.49674081802368164, - 0.31777822971343994 - ], - [ - 0.0, - 1.0, - 0.8810284733772278, - -0.5506706237792969 - ], - [ - 0.15693345665931702, - -1.138344645500183, - 0.24315010011196136, - 2.4595274925231934 - ], - [ - -2.6018145084381104, - 0.9079214930534363, - 0.8269925117492676, - 1.8018195629119873 - ] + [0.0, 0.0, -0.49674081802368164, 0.31777822971343994], + [0.0, 1.0, 0.8810284733772278, -0.5506706237792969], + [0.15693345665931702, -1.138344645500183, 0.24315010011196136, 2.4595274925231934], + [-2.6018145084381104, 0.9079214930534363, 0.8269925117492676, 1.8018195629119873] ], "expected_grad_x": [ - [ - 0.0, - 0.0, - 0.49674081802368164, - -2.369169235229492 - ], - [ - 1.0, - 1.0, - -0.8810284733772278, - 0.34835284948349 - ], - [ - -1.0, - -1.0, - -0.9705761075019836, - 1.4723693132400513 - ], - [ - -1.3775256872177124, - -1.204437255859375, - -0.48241984844207764, - -0.8164191246032715 - ] + [0.0, 0.0, 0.49674081802368164, -2.369169235229492], + [1.0, 1.0, -0.8810284733772278, 0.34835284948349], + [-1.0, -1.0, -0.9705761075019836, 1.4723693132400513], + [-1.3775256872177124, -1.204437255859375, -0.48241984844207764, -0.8164191246032715] ], "expected_grad_y": [ - [ - 0.0, - 1.0, - -1.0, - -0.13413065671920776 - ], - [ - 0.0, - 1.0, - -1.0, - -1.5807840824127197 - ], - [ - -0.15693345665931702, - 1.138344645500183, - -0.2505214214324951, - 1.6704555749893188 - ], - [ - 1.8887592554092407, - -0.7538138628005981, - -1.7142589092254639, - -2.2069785594940186 - ] + [0.0, 1.0, -1.0, -0.13413065671920776], + [0.0, 1.0, -1.0, -1.5807840824127197], + [-0.15693345665931702, 1.138344645500183, -0.2505214214324951, 1.6704555749893188], + [1.8887592554092407, -0.7538138628005981, -1.7142589092254639, -2.2069785594940186] ] } ], "div": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.5379461050033569 - ], - [ - 0.0, - 1.0, - -1.0, - -0.3353029191493988 - ], - [ - 0.9199973940849304, - -0.3787555396556854, - -1.5597758293151855, - -0.8009540438652039 - ], - [ - 0.35879161953926086, - 1.286241054534912, - 0.8211396932601929, - 0.9001851081848145 - ] + [0.0, 1.0, -1.0, -0.5379461050033569], + [0.0, 1.0, -1.0, -0.3353029191493988], + [0.9199973940849304, -0.3787555396556854, -1.5597758293151855, -0.8009540438652039], + [0.35879161953926086, 1.286241054534912, 0.8211396932601929, 0.9001851081848145] ], "input_y": [ - [ - 0.0, - 0.0, - 1.875388741493225, - 1.1042989492416382 - ], - [ - 1.0, - 1.0, - 0.23035314679145813, - -0.36578282713890076 - ], - [ - -1.0, - -1.0, - 1.5921050310134888, - -0.41619211435317993 - ], - [ - -0.7509436011314392, - -1.4861301183700562, - -0.03333820775151253, - 1.199822187423706 - ] + [0.0, 0.0, 1.875388741493225, 1.1042989492416382], + [1.0, 1.0, 0.23035314679145813, -0.36578282713890076], + [-1.0, -1.0, 1.5921050310134888, -0.41619211435317993], + [-0.7509436011314392, -1.4861301183700562, -0.03333820775151253, 1.199822187423706] ], "expected_output": [ - [ - NaN, - Infinity, - -0.5332227945327759, - -0.48713812232017517 - ], - [ - 0.0, - 1.0, - -4.341160774230957, - 0.9166721105575562 - ], - [ - -0.9199973940849304, - 0.3787555396556854, - -0.9796940684318542, - 1.9244815111160278 - ], - [ - -0.47778770327568054, - -0.8654969334602356, - -24.63058853149414, - 0.7502654194831848 - ] + [NaN, Infinity, -0.5332227945327759, -0.48713812232017517], + [0.0, 1.0, -4.341160774230957, 0.9166721105575562], + [-0.9199973940849304, 0.3787555396556854, -0.9796940684318542, 1.9244815111160278], + [-0.47778770327568054, -0.8654969334602356, -24.63058853149414, 0.7502654194831848] ], "expected_grad_x": [ - [ - Infinity, - Infinity, - 0.5332227945327759, - 0.9055519104003906 - ], - [ - 1.0, - 1.0, - 4.341160774230957, - -2.7338626384735107 - ], - [ - -1.0, - -1.0, - 0.628099262714386, - -2.4027364253997803 - ], - [ - -1.331657886505127, - -0.6728885769844055, - -29.99561309814453, - 0.833456814289093 - ] + [Infinity, Infinity, 0.5332227945327759, 0.9055519104003906], + [1.0, 1.0, 4.341160774230957, -2.7338626384735107], + [-1.0, -1.0, 0.628099262714386, -2.4027364253997803], + [-1.331657886505127, -0.6728885769844055, -29.99561309814453, 0.833456814289093] ], "expected_grad_y": [ - [ - NaN, - -Infinity, - 0.28432655334472656, - 0.44112884998321533 - ], - [ - -0.0, - -1.0, - 18.84567642211914, - 2.5060555934906006 - ], - [ - -0.9199973940849304, - 0.3787555396556854, - 0.6153451204299927, - 4.624022006988525 - ], - [ - -0.6362497806549072, - -0.5823830366134644, - -738.8096313476562, - -0.6253138184547424 - ] + [NaN, -Infinity, 0.28432655334472656, 0.44112884998321533], + [-0.0, -1.0, 18.84567642211914, 2.5060555934906006], + [-0.9199973940849304, 0.3787555396556854, 0.6153451204299927, 4.624022006988525], + [-0.6362497806549072, -0.5823830366134644, -738.8096313476562, -0.6253138184547424] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 0.32332202792167664 - ], - [ - 0.0, - 1.0, - -1.0, - -0.3372461199760437 - ], - [ - -0.08114803582429886, - 1.2586976289749146, - 0.8691263794898987, - -0.9609367251396179 - ], - [ - 0.3896495997905731, - 0.378065288066864, - -0.13722474873065948, - 1.1604512929916382 - ] + [0.0, 1.0, -1.0, 0.32332202792167664], + [0.0, 1.0, -1.0, -0.3372461199760437], + [-0.08114803582429886, 1.2586976289749146, 0.8691263794898987, -0.9609367251396179], + [0.3896495997905731, 0.378065288066864, -0.13722474873065948, 1.1604512929916382] ], "input_y": [ - [ - 0.0, - 0.0, - -0.22963792085647583, - -0.40709349513053894 - ], - [ - 1.0, - 1.0, - 0.8916962146759033, - 0.7001703381538391 - ], - [ - -1.0, - -1.0, - 0.9187757968902588, - 0.6662830114364624 - ], - [ - 0.22452101111412048, - -0.9745140671730042, - 0.9816727638244629, - 0.5836943984031677 - ] + [0.0, 0.0, -0.22963792085647583, -0.40709349513053894], + [1.0, 1.0, 0.8916962146759033, 0.7001703381538391], + [-1.0, -1.0, 0.9187757968902588, 0.6662830114364624], + [0.22452101111412048, -0.9745140671730042, 0.9816727638244629, 0.5836943984031677] ], "expected_output": [ - [ - NaN, - Infinity, - 4.354681491851807, - -0.7942205667495728 - ], - [ - 0.0, - 1.0, - -1.1214581727981567, - -0.48166295886039734 - ], - [ - 0.08114803582429886, - -1.2586976289749146, - 0.9459613561630249, - -1.4422351121902466 - ], - [ - 1.7354705333709717, - -0.38795262575149536, - -0.13978664577007294, - 1.9881144762039185 - ] + [NaN, Infinity, 4.354681491851807, -0.7942205667495728], + [0.0, 1.0, -1.1214581727981567, -0.48166295886039734], + [0.08114803582429886, -1.2586976289749146, 0.9459613561630249, -1.4422351121902466], + [1.7354705333709717, -0.38795262575149536, -0.13978664577007294, 1.9881144762039185] ], "expected_grad_x": [ - [ - Infinity, - Infinity, - -4.354681491851807, - -2.4564380645751953 - ], - [ - 1.0, - 1.0, - 1.1214581727981567, - 1.4282238483428955 - ], - [ - -1.0, - -1.0, - 1.0884047746658325, - 1.5008636713027954 - ], - [ - 4.453926086425781, - -1.026152491569519, - 1.0186693668365479, - 1.713225245475769 - ] + [Infinity, Infinity, -4.354681491851807, -2.4564380645751953], + [1.0, 1.0, 1.1214581727981567, 1.4282238483428955], + [-1.0, -1.0, 1.0884047746658325, 1.5008636713027954], + [4.453926086425781, -1.026152491569519, 1.0186693668365479, 1.713225245475769] ], "expected_grad_y": [ - [ - NaN, - -Infinity, - 18.9632511138916, - -1.950953722000122 - ], - [ - -0.0, - -1.0, - 1.257668375968933, - 0.6879225373268127 - ], - [ - 0.08114803582429886, - -1.2586976289749146, - -1.0295889377593994, - 2.1645984649658203 - ], - [ - -7.7296576499938965, - -0.39809852838516235, - 0.14239637553691864, - -3.406087875366211 - ] + [NaN, -Infinity, 18.9632511138916, -1.950953722000122], + [-0.0, -1.0, 1.257668375968933, 0.6879225373268127], + [0.08114803582429886, -1.2586976289749146, -1.0295889377593994, 2.1645984649658203], + [-7.7296576499938965, -0.39809852838516235, 0.14239637553691864, -3.406087875366211] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.7911050319671631 - ], - [ - 0.0, - 1.0, - -1.0, - -0.17465536296367645 - ], - [ - 0.34005025029182434, - 1.4557304382324219, - -0.3461014926433563, - -0.2633814215660095 - ], - [ - 1.5014268159866333, - -0.033501043915748596, - 1.1346064805984497, - 0.14365693926811218 - ] + [0.0, 1.0, -1.0, -0.7911050319671631], + [0.0, 1.0, -1.0, -0.17465536296367645], + [0.34005025029182434, 1.4557304382324219, -0.3461014926433563, -0.2633814215660095], + [1.5014268159866333, -0.033501043915748596, 1.1346064805984497, 0.14365693926811218] ], "input_y": [ - [ - 0.0, - 0.0, - 1.3061575889587402, - -0.9275763630867004 - ], - [ - 1.0, - 1.0, - 1.2907683849334717, - 1.5468223094940186 - ], - [ - -1.0, - -1.0, - -0.6493158936500549, - 0.45214036107063293 - ], - [ - 1.2459663152694702, - -0.8647340536117554, - -0.8475469946861267, - -0.02352304570376873 - ] + [0.0, 0.0, 1.3061575889587402, -0.9275763630867004], + [1.0, 1.0, 1.2907683849334717, 1.5468223094940186], + [-1.0, -1.0, -0.6493158936500549, 0.45214036107063293], + [1.2459663152694702, -0.8647340536117554, -0.8475469946861267, -0.02352304570376873] ], "expected_output": [ - [ - NaN, - Infinity, - -0.7656043767929077, - 0.8528732061386108 - ], - [ - 0.0, - 1.0, - -0.7747323513031006, - -0.1129123643040657 - ], - [ - -0.34005025029182434, - -1.4557304382324219, - 0.5330248475074768, - -0.582521378993988 - ], - [ - 1.2050299644470215, - 0.03874144330620766, - -1.338694453239441, - -6.107072353363037 - ] + [NaN, Infinity, -0.7656043767929077, 0.8528732061386108], + [0.0, 1.0, -0.7747323513031006, -0.1129123643040657], + [-0.34005025029182434, -1.4557304382324219, 0.5330248475074768, -0.582521378993988], + [1.2050299644470215, 0.03874144330620766, -1.338694453239441, -6.107072353363037] ], "expected_grad_x": [ - [ - Infinity, - Infinity, - 0.7656043767929077, - -1.0780783891677856 - ], - [ - 1.0, - 1.0, - 0.7747323513031006, - 0.6464866399765015 - ], - [ - -1.0, - -1.0, - -1.5400824546813965, - 2.211702585220337 - ], - [ - 0.8025898933410645, - -1.156424880027771, - -1.1798756122589111, - -42.51150131225586 - ] + [Infinity, Infinity, 0.7656043767929077, -1.0780783891677856], + [1.0, 1.0, 0.7747323513031006, 0.6464866399765015], + [-1.0, -1.0, -1.5400824546813965, 2.211702585220337], + [0.8025898933410645, -1.156424880027771, -1.1798756122589111, -42.51150131225586] ], "expected_grad_y": [ - [ - NaN, - -Infinity, - 0.5861501097679138, - 0.9194641709327698 - ], - [ - -0.0, - -1.0, - 0.6002101898193359, - 0.0729963406920433 - ], - [ - -0.34005025029182434, - -1.4557304382324219, - 0.8209022283554077, - 1.288364052772522 - ], - [ - -0.9671449065208435, - 0.04480157047510147, - -1.5794929265975952, - -259.6208190917969 - ] + [NaN, -Infinity, 0.5861501097679138, 0.9194641709327698], + [-0.0, -1.0, 0.6002101898193359, 0.0729963406920433], + [-0.34005025029182434, -1.4557304382324219, 0.8209022283554077, 1.288364052772522], + [-0.9671449065208435, 0.04480157047510147, -1.5794929265975952, -259.6208190917969] ] } ], "pow": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.35899198055267334 - ], - [ - 0.0, - 1.0, - -1.0, - 0.013965161517262459 - ], - [ - -1.3923954963684082, - 0.540465772151947, - 0.4350730776786804, - -2.2717032432556152 - ], - [ - 0.06991618871688843, - 0.5178828239440918, - -0.3457261919975281, - 1.3411089181900024 - ] + [0.0, 1.0, -1.0, -0.35899198055267334], + [0.0, 1.0, -1.0, 0.013965161517262459], + [-1.3923954963684082, 0.540465772151947, 0.4350730776786804, -2.2717032432556152], + [0.06991618871688843, 0.5178828239440918, -0.3457261919975281, 1.3411089181900024] ], "input_y": [ - [ - 0.0, - 0.0, - -0.5522539615631104, - -0.09342008084058762 - ], - [ - 1.0, - 1.0, - -0.5081791877746582, - 1.1477830410003662 - ], - [ - -1.0, - -1.0, - 0.9821351766586304, - 0.22690092027187347 - ], - [ - 1.563033103942871, - 0.5983186960220337, - -0.5407329201698303, - 0.7841619849205017 - ] + [0.0, 0.0, -0.5522539615631104, -0.09342008084058762], + [1.0, 1.0, -0.5081791877746582, 1.1477830410003662], + [-1.0, -1.0, 0.9821351766586304, 0.22690092027187347], + [1.563033103942871, 0.5983186960220337, -0.5407329201698303, 0.7841619849205017] ], "expected_output": [ - [ - 1.0, - 1.0, - NaN, - NaN - ], - [ - 0.0, - 1.0, - NaN, - 0.007428741082549095 - ], - [ - -0.7181867361068726, - 1.8502559661865234, - 0.44159001111984253, - NaN - ], - [ - 0.01563280075788498, - 0.6745581030845642, - NaN, - 1.2587876319885254 - ] + [1.0, 1.0, NaN, NaN], + [0.0, 1.0, NaN, 0.007428741082549095], + [-0.7181867361068726, 1.8502559661865234, 0.44159001111984253, NaN], + [0.01563280075788498, 0.6745581030845642, NaN, 1.2587876319885254] ], "expected_grad_x": [ - [ - 0.0, - 0.0, - NaN, - NaN - ], - [ - 1.0, - 1.0, - NaN, - 0.6105610132217407 - ], - [ - -0.515792191028595, - -3.4234468936920166, - 0.9968464374542236, - NaN - ], - [ - 0.3494839370250702, - 0.7793282866477966, - NaN, - 0.7360277771949768 - ] + [0.0, 0.0, NaN, NaN], + [1.0, 1.0, NaN, 0.6105610132217407], + [-0.515792191028595, -3.4234468936920166, 0.9968464374542236, NaN], + [0.3494839370250702, 0.7793282866477966, NaN, 0.7360277771949768] ], "expected_grad_y": [ - [ - 0.0, - 0.0, - NaN, - NaN - ], - [ - 0.0, - 0.0, - NaN, - -0.0317295640707016 - ], - [ - NaN, - -1.1385067701339722, - -0.3675094544887543, - NaN - ], - [ - -0.041590411216020584, - -0.4438634514808655, - NaN, - 0.3694501519203186 - ] + [0.0, 0.0, NaN, NaN], + [0.0, 0.0, NaN, -0.0317295640707016], + [NaN, -1.1385067701339722, -0.3675094544887543, NaN], + [-0.041590411216020584, -0.4438634514808655, NaN, 0.3694501519203186] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 0.7011352777481079 - ], - [ - 0.0, - 1.0, - -1.0, - 0.46809425950050354 - ], - [ - 0.1417587399482727, - 1.1084681749343872, - 0.5544233322143555, - 1.5817502737045288 - ], - [ - -0.5585249066352844, - 0.6636945605278015, - -1.7024588584899902, - 1.669644832611084 - ] + [0.0, 1.0, -1.0, 0.7011352777481079], + [0.0, 1.0, -1.0, 0.46809425950050354], + [0.1417587399482727, 1.1084681749343872, 0.5544233322143555, 1.5817502737045288], + [-0.5585249066352844, 0.6636945605278015, -1.7024588584899902, 1.669644832611084] ], "input_y": [ - [ - 0.0, - 0.0, - -1.6634936332702637, - -0.7650561332702637 - ], - [ - 1.0, - 1.0, - -1.1787039041519165, - -2.1400885581970215 - ], - [ - -1.0, - -1.0, - -0.07032525539398193, - 0.27448296546936035 - ], - [ - 0.5569454431533813, - -0.23220781981945038, - -0.05974622070789337, - -1.666461706161499 - ] + [0.0, 0.0, -1.6634936332702637, -0.7650561332702637], + [1.0, 1.0, -1.1787039041519165, -2.1400885581970215], + [-1.0, -1.0, -0.07032525539398193, 0.27448296546936035], + [0.5569454431533813, -0.23220781981945038, -0.05974622070789337, -1.666461706161499] ], "expected_output": [ - [ - 1.0, - 1.0, - NaN, - 1.3121100664138794 - ], - [ - 0.0, - 1.0, - NaN, - 5.075933456420898 - ], - [ - 7.054238796234131, - 0.9021458625793457, - 1.0423519611358643, - 1.1341224908828735 - ], - [ - NaN, - 1.0998674631118774, - NaN, - 0.4256037771701813 - ] + [1.0, 1.0, NaN, 1.3121100664138794], + [0.0, 1.0, NaN, 5.075933456420898], + [7.054238796234131, 0.9021458625793457, 1.0423519611358643, 1.1341224908828735], + [NaN, 1.0998674631118774, NaN, 0.4256037771701813] ], "expected_grad_x": [ - [ - 0.0, - 0.0, - NaN, - -1.4317320585250854 - ], - [ - 1.0, - 1.0, - NaN, - -23.206750869750977 - ], - [ - -49.76228332519531, - -0.8138672113418579, - -0.13221606612205505, - 0.19680559635162354 - ], - [ - NaN, - -0.38481229543685913, - NaN, - -0.4247923791408539 - ] + [0.0, 0.0, NaN, -1.4317320585250854], + [1.0, 1.0, NaN, -23.206750869750977], + [-49.76228332519531, -0.8138672113418579, -0.13221606612205505, 0.19680559635162354], + [NaN, -0.38481229543685913, NaN, -0.4247923791408539] ], "expected_grad_y": [ - [ - 0.0, - 0.0, - NaN, - -0.4658704996109009 - ], - [ - 0.0, - 0.0, - NaN, - -3.8530678749084473 - ], - [ - -13.781363487243652, - 0.09290211647748947, - -0.6148070693016052, - 0.5200314521789551 - ], - [ - NaN, - -0.4508722424507141, - NaN, - 0.21816913783550262 - ] + [0.0, 0.0, NaN, -0.4658704996109009], + [0.0, 0.0, NaN, -3.8530678749084473], + [-13.781363487243652, 0.09290211647748947, -0.6148070693016052, 0.5200314521789551], + [NaN, -0.4508722424507141, NaN, 0.21816913783550262] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -1.5196866989135742 - ], - [ - 0.0, - 1.0, - -1.0, - 0.9274609088897705 - ], - [ - 0.7894347310066223, - 0.7824702858924866, - -0.06465863436460495, - -0.0002302070497535169 - ], - [ - 0.569308340549469, - 0.7476243376731873, - 2.1336774826049805, - 0.5014525055885315 - ] + [0.0, 1.0, -1.0, -1.5196866989135742], + [0.0, 1.0, -1.0, 0.9274609088897705], + [0.7894347310066223, 0.7824702858924866, -0.06465863436460495, -0.0002302070497535169], + [0.569308340549469, 0.7476243376731873, 2.1336774826049805, 0.5014525055885315] ], "input_y": [ - [ - 0.0, - 0.0, - 1.4614392518997192, - 1.0566132068634033 - ], - [ - 1.0, - 1.0, - -0.2809409499168396, - -0.3604622483253479 - ], - [ - -1.0, - -1.0, - -1.7659958600997925, - -2.5379507541656494 - ], - [ - -0.03343662992119789, - -1.7016695737838745, - 0.5863364338874817, - -1.7526601552963257 - ] + [0.0, 0.0, 1.4614392518997192, 1.0566132068634033], + [1.0, 1.0, -0.2809409499168396, -0.3604622483253479], + [-1.0, -1.0, -1.7659958600997925, -2.5379507541656494], + [-0.03343662992119789, -1.7016695737838745, 0.5863364338874817, -1.7526601552963257] ], "expected_output": [ - [ - 1.0, - 1.0, - NaN, - NaN - ], - [ - 0.0, - 1.0, - NaN, - 1.02751624584198 - ], - [ - 1.2667291164398193, - 1.2780038118362427, - NaN, - NaN - ], - [ - 1.0190144777297974, - 1.640397310256958, - 1.5594813823699951, - 3.3527045249938965 - ] + [1.0, 1.0, NaN, NaN], + [0.0, 1.0, NaN, 1.02751624584198], + [1.2667291164398193, 1.2780038118362427, NaN, NaN], + [1.0190144777297974, 1.640397310256958, 1.5594813823699951, 3.3527045249938965] ], "expected_grad_x": [ - [ - 0.0, - 0.0, - NaN, - NaN - ], - [ - 1.0, - 1.0, - NaN, - -0.39934927225112915 - ], - [ - -1.6046028137207031, - -1.6332937479019165, - NaN, - NaN - ], - [ - -0.05984878167510033, - -3.733712673187256, - 0.42854681611061096, - -11.71826171875 - ] + [0.0, 0.0, NaN, NaN], + [1.0, 1.0, NaN, -0.39934927225112915], + [-1.6046028137207031, -1.6332937479019165, NaN, NaN], + [-0.05984878167510033, -3.733712673187256, 0.42854681611061096, -11.71826171875] ], "expected_grad_y": [ - [ - 0.0, - 0.0, - NaN, - NaN - ], - [ - 0.0, - 0.0, - NaN, - -0.07737673819065094 - ], - [ - -0.29950305819511414, - -0.3134934902191162, - NaN, - NaN - ], - [ - -0.5740445852279663, - -0.4771172106266022, - 1.1818482875823975, - -2.314192295074463 - ] + [0.0, 0.0, NaN, NaN], + [0.0, 0.0, NaN, -0.07737673819065094], + [-0.29950305819511414, -0.3134934902191162, NaN, NaN], + [-0.5740445852279663, -0.4771172106266022, 1.1818482875823975, -2.314192295074463] ] } ], "maximum": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 0.2491273283958435 - ], - [ - 0.0, - 1.0, - -1.0, - 0.0604986697435379 - ], - [ - -0.18495284020900726, - -1.0380902290344238, - -0.10130416601896286, - -0.9271824359893799 - ], - [ - 0.734416127204895, - 0.030971217900514603, - -0.5865293741226196, - -0.3154546320438385 - ] + [0.0, 1.0, -1.0, 0.2491273283958435], + [0.0, 1.0, -1.0, 0.0604986697435379], + [-0.18495284020900726, -1.0380902290344238, -0.10130416601896286, -0.9271824359893799], + [0.734416127204895, 0.030971217900514603, -0.5865293741226196, -0.3154546320438385] ], "input_y": [ - [ - 0.0, - 0.0, - 1.2309634685516357, - 1.2286686897277832 - ], - [ - 1.0, - 1.0, - -1.2784851789474487, - -1.269239068031311 - ], - [ - -1.0, - -1.0, - 1.8989076614379883, - -0.04056643322110176 - ], - [ - 0.6467097401618958, - -2.081273078918457, - -0.9303572773933411, - -1.3949681520462036 - ] + [0.0, 0.0, 1.2309634685516357, 1.2286686897277832], + [1.0, 1.0, -1.2784851789474487, -1.269239068031311], + [-1.0, -1.0, 1.8989076614379883, -0.04056643322110176], + [0.6467097401618958, -2.081273078918457, -0.9303572773933411, -1.3949681520462036] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.2309634685516357, - 1.2286686897277832 - ], - [ - 1.0, - 1.0, - -1.0, - 0.0604986697435379 - ], - [ - -0.18495284020900726, - -1.0, - 1.8989076614379883, - -0.04056643322110176 - ], - [ - 0.734416127204895, - 0.030971217900514603, - -0.5865293741226196, - -0.3154546320438385 - ] + [0.0, 1.0, 1.2309634685516357, 1.2286686897277832], + [1.0, 1.0, -1.0, 0.0604986697435379], + [-0.18495284020900726, -1.0, 1.8989076614379883, -0.04056643322110176], + [0.734416127204895, 0.030971217900514603, -0.5865293741226196, -0.3154546320438385] ], "expected_grad_x": [ - [ - 0.5, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.5, - 1.0, - 1.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ] + [0.5, 1.0, 0.0, 0.0], + [0.0, 0.5, 1.0, 1.0], + [1.0, 0.0, 0.0, 0.0], + [1.0, 1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - 0.5, - 0.0, - 1.0, - 1.0 - ], - [ - 1.0, - 0.5, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.5, 0.0, 1.0, 1.0], + [1.0, 0.5, 0.0, 0.0], + [0.0, 1.0, 1.0, 1.0], + [0.0, 0.0, 0.0, 0.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -0.10754015296697617 - ], - [ - 0.0, - 1.0, - -1.0, - 0.3934462368488312 - ], - [ - 0.9626035690307617, - -1.1049346923828125, - -0.7909473180770874, - -0.21609316766262054 - ], - [ - 0.8574033975601196, - 1.145952820777893, - -0.11311652511358261, - 1.409318447113037 - ] + [0.0, 1.0, -1.0, -0.10754015296697617], + [0.0, 1.0, -1.0, 0.3934462368488312], + [0.9626035690307617, -1.1049346923828125, -0.7909473180770874, -0.21609316766262054], + [0.8574033975601196, 1.145952820777893, -0.11311652511358261, 1.409318447113037] ], "input_y": [ - [ - 0.0, - 0.0, - 1.6020095348358154, - -1.0371782779693604 - ], - [ - 1.0, - 1.0, - 0.11150163412094116, - 1.7073947191238403 - ], - [ - -1.0, - -1.0, - -0.06464217603206635, - 3.445625066757202 - ], - [ - 0.36726734042167664, - -0.39192530512809753, - 0.1605725735425949, - 2.2373695373535156 - ] + [0.0, 0.0, 1.6020095348358154, -1.0371782779693604], + [1.0, 1.0, 0.11150163412094116, 1.7073947191238403], + [-1.0, -1.0, -0.06464217603206635, 3.445625066757202], + [0.36726734042167664, -0.39192530512809753, 0.1605725735425949, 2.2373695373535156] ], "expected_output": [ - [ - 0.0, - 1.0, - 1.6020095348358154, - -0.10754015296697617 - ], - [ - 1.0, - 1.0, - 0.11150163412094116, - 1.7073947191238403 - ], - [ - 0.9626035690307617, - -1.0, - -0.06464217603206635, - 3.445625066757202 - ], - [ - 0.8574033975601196, - 1.145952820777893, - 0.1605725735425949, - 2.2373695373535156 - ] + [0.0, 1.0, 1.6020095348358154, -0.10754015296697617], + [1.0, 1.0, 0.11150163412094116, 1.7073947191238403], + [0.9626035690307617, -1.0, -0.06464217603206635, 3.445625066757202], + [0.8574033975601196, 1.145952820777893, 0.1605725735425949, 2.2373695373535156] ], "expected_grad_x": [ - [ - 0.5, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.5, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 0.0, - 0.0 - ] + [0.5, 1.0, 0.0, 1.0], + [0.0, 0.5, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0], + [1.0, 1.0, 0.0, 0.0] ], "expected_grad_y": [ - [ - 0.5, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.5, - 1.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0, - 1.0 - ] + [0.5, 0.0, 1.0, 0.0], + [1.0, 0.5, 1.0, 1.0], + [0.0, 1.0, 1.0, 1.0], + [0.0, 0.0, 1.0, 1.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 0.32681646943092346 - ], - [ - 0.0, - 1.0, - -1.0, - -0.2612513303756714 - ], - [ - -1.3136197328567505, - -0.6061143279075623, - 0.6449755430221558, - -0.24771355092525482 - ], - [ - -0.9767715930938721, - -0.443967342376709, - 0.7373694777488708, - -0.13394701480865479 - ] + [0.0, 1.0, -1.0, 0.32681646943092346], + [0.0, 1.0, -1.0, -0.2612513303756714], + [-1.3136197328567505, -0.6061143279075623, 0.6449755430221558, -0.24771355092525482], + [-0.9767715930938721, -0.443967342376709, 0.7373694777488708, -0.13394701480865479] ], "input_y": [ - [ - 0.0, - 0.0, - 0.25832492113113403, - -2.4340736865997314 - ], - [ - 1.0, - 1.0, - -2.0726318359375, - -2.1240861415863037 - ], - [ - -1.0, - -1.0, - 0.4093967378139496, - -0.5840954780578613 - ], - [ - 1.0092873573303223, - 1.0439283847808838, - 0.29792049527168274, - 0.8381712436676025 - ] + [0.0, 0.0, 0.25832492113113403, -2.4340736865997314], + [1.0, 1.0, -2.0726318359375, -2.1240861415863037], + [-1.0, -1.0, 0.4093967378139496, -0.5840954780578613], + [1.0092873573303223, 1.0439283847808838, 0.29792049527168274, 0.8381712436676025] ], "expected_output": [ - [ - 0.0, - 1.0, - 0.25832492113113403, - 0.32681646943092346 - ], - [ - 1.0, - 1.0, - -1.0, - -0.2612513303756714 - ], - [ - -1.0, - -0.6061143279075623, - 0.6449755430221558, - -0.24771355092525482 - ], - [ - 1.0092873573303223, - 1.0439283847808838, - 0.7373694777488708, - 0.8381712436676025 - ] + [0.0, 1.0, 0.25832492113113403, 0.32681646943092346], + [1.0, 1.0, -1.0, -0.2612513303756714], + [-1.0, -0.6061143279075623, 0.6449755430221558, -0.24771355092525482], + [1.0092873573303223, 1.0439283847808838, 0.7373694777488708, 0.8381712436676025] ], "expected_grad_x": [ - [ - 0.5, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.5, - 1.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0 - ] + [0.5, 1.0, 0.0, 1.0], + [0.0, 0.5, 1.0, 1.0], + [0.0, 1.0, 1.0, 1.0], + [0.0, 0.0, 1.0, 0.0] ], "expected_grad_y": [ - [ - 0.5, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.5, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 0.0, - 1.0 - ] + [0.5, 0.0, 1.0, 0.0], + [1.0, 0.5, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0], + [1.0, 1.0, 0.0, 1.0] ] } ], "minimum": [ { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 1.4483332633972168 - ], - [ - 0.0, - 1.0, - -1.0, - -0.8552408218383789 - ], - [ - -0.25843867659568787, - -0.7501540780067444, - 1.2354754209518433, - 1.0141247510910034 - ], - [ - -0.6535475254058838, - 1.4623208045959473, - 0.1203368678689003, - 0.7514159083366394 - ] + [0.0, 1.0, -1.0, 1.4483332633972168], + [0.0, 1.0, -1.0, -0.8552408218383789], + [-0.25843867659568787, -0.7501540780067444, 1.2354754209518433, 1.0141247510910034], + [-0.6535475254058838, 1.4623208045959473, 0.1203368678689003, 0.7514159083366394] ], "input_y": [ - [ - 0.0, - 0.0, - -0.8768263459205627, - -1.5509816408157349 - ], - [ - 1.0, - 1.0, - -0.20693671703338623, - 0.44715985655784607 - ], - [ - -1.0, - -1.0, - 0.21129246056079865, - 1.4860185384750366 - ], - [ - 2.121837854385376, - 0.4178215563297272, - 0.44609254598617554, - -0.02666892670094967 - ] + [0.0, 0.0, -0.8768263459205627, -1.5509816408157349], + [1.0, 1.0, -0.20693671703338623, 0.44715985655784607], + [-1.0, -1.0, 0.21129246056079865, 1.4860185384750366], + [2.121837854385376, 0.4178215563297272, 0.44609254598617554, -0.02666892670094967] ], "expected_output": [ - [ - 0.0, - 0.0, - -1.0, - -1.5509816408157349 - ], - [ - 0.0, - 1.0, - -1.0, - -0.8552408218383789 - ], - [ - -1.0, - -1.0, - 0.21129246056079865, - 1.0141247510910034 - ], - [ - -0.6535475254058838, - 0.4178215563297272, - 0.1203368678689003, - -0.02666892670094967 - ] + [0.0, 0.0, -1.0, -1.5509816408157349], + [0.0, 1.0, -1.0, -0.8552408218383789], + [-1.0, -1.0, 0.21129246056079865, 1.0141247510910034], + [-0.6535475254058838, 0.4178215563297272, 0.1203368678689003, -0.02666892670094967] ], "expected_grad_x": [ - [ - 0.5, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.5, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 1.0, - 0.0, - 1.0, - 0.0 - ] + [0.5, 0.0, 1.0, 0.0], + [1.0, 0.5, 1.0, 1.0], + [0.0, 0.0, 0.0, 1.0], + [1.0, 0.0, 1.0, 0.0] ], "expected_grad_y": [ - [ - 0.5, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.5, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0 - ] + [0.5, 1.0, 0.0, 1.0], + [0.0, 0.5, 0.0, 0.0], + [1.0, 1.0, 1.0, 0.0], + [0.0, 1.0, 0.0, 1.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - 1.0925219058990479 - ], - [ - 0.0, - 1.0, - -1.0, - -0.24391917884349823 - ], - [ - -0.783242404460907, - -0.26778313517570496, - 1.5684525966644287, - -0.283514142036438 - ], - [ - -1.465786099433899, - -0.06292983889579773, - -2.527074098587036, - 0.47731438279151917 - ] + [0.0, 1.0, -1.0, 1.0925219058990479], + [0.0, 1.0, -1.0, -0.24391917884349823], + [-0.783242404460907, -0.26778313517570496, 1.5684525966644287, -0.283514142036438], + [-1.465786099433899, -0.06292983889579773, -2.527074098587036, 0.47731438279151917] ], "input_y": [ - [ - 0.0, - 0.0, - -0.06058019772171974, - -0.5304896831512451 - ], - [ - 1.0, - 1.0, - 1.6892662048339844, - -0.6297198534011841 - ], - [ - -1.0, - -1.0, - -1.4458993673324585, - -0.31466683745384216 - ], - [ - -1.242173194885254, - -0.3340345025062561, - -1.5728429555892944, - 2.810397148132324 - ] + [0.0, 0.0, -0.06058019772171974, -0.5304896831512451], + [1.0, 1.0, 1.6892662048339844, -0.6297198534011841], + [-1.0, -1.0, -1.4458993673324585, -0.31466683745384216], + [-1.242173194885254, -0.3340345025062561, -1.5728429555892944, 2.810397148132324] ], "expected_output": [ - [ - 0.0, - 0.0, - -1.0, - -0.5304896831512451 - ], - [ - 0.0, - 1.0, - -1.0, - -0.6297198534011841 - ], - [ - -1.0, - -1.0, - -1.4458993673324585, - -0.31466683745384216 - ], - [ - -1.465786099433899, - -0.3340345025062561, - -2.527074098587036, - 0.47731438279151917 - ] + [0.0, 0.0, -1.0, -0.5304896831512451], + [0.0, 1.0, -1.0, -0.6297198534011841], + [-1.0, -1.0, -1.4458993673324585, -0.31466683745384216], + [-1.465786099433899, -0.3340345025062561, -2.527074098587036, 0.47731438279151917] ], "expected_grad_x": [ - [ - 0.5, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.5, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 1.0, - 1.0 - ] + [0.5, 0.0, 1.0, 0.0], + [1.0, 0.5, 1.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - 0.5, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.5, - 0.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0 - ] + [0.5, 1.0, 0.0, 1.0], + [0.0, 0.5, 0.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [0.0, 1.0, 0.0, 0.0] ] }, { "input_x": [ - [ - 0.0, - 1.0, - -1.0, - -2.0370566844940186 - ], - [ - 0.0, - 1.0, - -1.0, - 0.9563636779785156 - ], - [ - -0.8331825137138367, - -0.47921040654182434, - 0.2998451292514801, - 0.721377432346344 - ], - [ - 0.7283791899681091, - -0.34462252259254456, - 0.4790245592594147, - 0.024238986894488335 - ] + [0.0, 1.0, -1.0, -2.0370566844940186], + [0.0, 1.0, -1.0, 0.9563636779785156], + [-0.8331825137138367, -0.47921040654182434, 0.2998451292514801, 0.721377432346344], + [0.7283791899681091, -0.34462252259254456, 0.4790245592594147, 0.024238986894488335] ], "input_y": [ - [ - 0.0, - 0.0, - 0.43399056792259216, - 1.1234275102615356 - ], - [ - 1.0, - 1.0, - 0.2529439628124237, - 0.12658123672008514 - ], - [ - -1.0, - -1.0, - 0.825295627117157, - 2.268347978591919 - ], - [ - -0.06611745059490204, - -1.0740467309951782, - 1.3753548860549927, - -0.3824302554130554 - ] + [0.0, 0.0, 0.43399056792259216, 1.1234275102615356], + [1.0, 1.0, 0.2529439628124237, 0.12658123672008514], + [-1.0, -1.0, 0.825295627117157, 2.268347978591919], + [-0.06611745059490204, -1.0740467309951782, 1.3753548860549927, -0.3824302554130554] ], "expected_output": [ - [ - 0.0, - 0.0, - -1.0, - -2.0370566844940186 - ], - [ - 0.0, - 1.0, - -1.0, - 0.12658123672008514 - ], - [ - -1.0, - -1.0, - 0.2998451292514801, - 0.721377432346344 - ], - [ - -0.06611745059490204, - -1.0740467309951782, - 0.4790245592594147, - -0.3824302554130554 - ] + [0.0, 0.0, -1.0, -2.0370566844940186], + [0.0, 1.0, -1.0, 0.12658123672008514], + [-1.0, -1.0, 0.2998451292514801, 0.721377432346344], + [-0.06611745059490204, -1.0740467309951782, 0.4790245592594147, -0.3824302554130554] ], "expected_grad_x": [ - [ - 0.5, - 0.0, - 1.0, - 1.0 - ], - [ - 1.0, - 0.5, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0 - ] + [0.5, 0.0, 1.0, 1.0], + [1.0, 0.5, 1.0, 0.0], + [0.0, 0.0, 1.0, 1.0], + [0.0, 0.0, 1.0, 0.0] ], "expected_grad_y": [ - [ - 0.5, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.5, - 0.0, - 1.0 - ], - [ - 1.0, - 1.0, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 0.0, - 1.0 - ] + [0.5, 1.0, 0.0, 0.0], + [0.0, 0.5, 0.0, 1.0], + [1.0, 1.0, 0.0, 0.0], + [1.0, 1.0, 0.0, 1.0] ] } ] @@ -4565,128 +1277,48 @@ export const testData = { "test_name": "broadcast_add_(2, 3)_and_(2, 3)", "op_name": "add", "input_x": [ - [ - -0.017705317586660385, - -0.843208909034729, - 0.06224742531776428 - ], - [ - 0.4080433249473572, - -1.2516316175460815, - -1.2717373371124268 - ] + [-0.017705317586660385, -0.843208909034729, 0.06224742531776428], + [0.4080433249473572, -1.2516316175460815, -1.2717373371124268] ], "input_y": [ - [ - 0.8055283427238464, - 1.0920584201812744, - 0.8560135960578918 - ], - [ - 1.5192112922668457, - 0.44675812125205994, - -0.2566242218017578 - ] + [0.8055283427238464, 1.0920584201812744, 0.8560135960578918], + [1.5192112922668457, 0.44675812125205994, -0.2566242218017578] ], "expected_output": [ - [ - 0.7878230214118958, - 0.2488495111465454, - 0.9182610511779785 - ], - [ - 1.9272546768188477, - -0.8048734664916992, - -1.5283615589141846 - ] + [0.7878230214118958, 0.2488495111465454, 0.9182610511779785], + [1.9272546768188477, -0.8048734664916992, -1.5283615589141846] ], "expected_grad_x": [ - [ - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0] ], "expected_grad_y": [ - [ - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0] ] }, { "test_name": "broadcast_mul_(2, 3)_and_(2, 3)", "op_name": "mul", "input_x": [ - [ - 1.7753183841705322, - -0.7927579879760742, - -1.6142888069152832 - ], - [ - 0.31103116273880005, - 1.7946441173553467, - 3.19868803024292 - ] + [1.7753183841705322, -0.7927579879760742, -1.6142888069152832], + [0.31103116273880005, 1.7946441173553467, 3.19868803024292] ], "input_y": [ - [ - 0.2567588686943054, - 0.8679211735725403, - -1.1851390600204468 - ], - [ - 0.7940642833709717, - 0.19724640250205994, - 0.622898280620575 - ] + [0.2567588686943054, 0.8679211735725403, -1.1851390600204468], + [0.7940642833709717, 0.19724640250205994, 0.622898280620575] ], "expected_output": [ - [ - 0.4558287262916565, - -0.6880514621734619, - 1.9131567478179932 - ], - [ - 0.2469787299633026, - 0.35398709774017334, - 1.9924572706222534 - ] + [0.4558287262916565, -0.6880514621734619, 1.9131567478179932], + [0.2469787299633026, 0.35398709774017334, 1.9924572706222534] ], "expected_grad_x": [ - [ - 0.2567588686943054, - 0.8679211735725403, - -1.1851390600204468 - ], - [ - 0.7940642833709717, - 0.19724640250205994, - 0.622898280620575 - ] + [0.2567588686943054, 0.8679211735725403, -1.1851390600204468], + [0.7940642833709717, 0.19724640250205994, 0.622898280620575] ], "expected_grad_y": [ - [ - 1.7753183841705322, - -0.7927579879760742, - -1.6142888069152832 - ], - [ - 0.31103116273880005, - 1.7946441173553467, - 3.19868803024292 - ] + [1.7753183841705322, -0.7927579879760742, -1.6142888069152832], + [0.31103116273880005, 1.7946441173553467, 3.19868803024292] ] }, { @@ -4694,35 +1326,17 @@ export const testData = { "op_name": "add", "input_x": 1.5, "input_y": [ - [ - 1.186416506767273, - 1.3099017143249512 - ], - [ - -2.1073341369628906, - -0.22107578814029694 - ] + [1.186416506767273, 1.3099017143249512], + [-2.1073341369628906, -0.22107578814029694] ], "expected_output": [ - [ - 2.6864166259765625, - 2.809901714324951 - ], - [ - -0.6073341369628906, - 1.2789242267608643 - ] + [2.6864166259765625, 2.809901714324951], + [-0.6073341369628906, 1.2789242267608643] ], "expected_grad_x": 4.0, "expected_grad_y": [ - [ - 1.0, - 1.0 - ], - [ - 1.0, - 1.0 - ] + [1.0, 1.0], + [1.0, 1.0] ] }, { @@ -4730,9007 +1344,2768 @@ export const testData = { "op_name": "mul", "input_x": 1.5, "input_y": [ - [ - 0.9579378366470337, - -1.3392482995986938 - ], - [ - -1.3702017068862915, - -0.32176926732063293 - ] + [0.9579378366470337, -1.3392482995986938], + [-1.3702017068862915, -0.32176926732063293] ], "expected_output": [ - [ - 1.4369068145751953, - -2.0088725090026855 - ], - [ - -2.055302619934082, - -0.4826539158821106 - ] + [1.4369068145751953, -2.0088725090026855], + [-2.055302619934082, -0.4826539158821106] ], "expected_grad_x": -2.0732815265655518, "expected_grad_y": [ + [1.5, 1.5], + [1.5, 1.5] + ] + }, + { + "test_name": "broadcast_add_(2, 3, 4, 1)_and_(3, 1, 1)", + "op_name": "add", + "input_x": [ [ - 1.5, - 1.5 - ], - [ - 1.5, - 1.5 - ] - ] - }, - { - "test_name": "broadcast_add_(2, 3, 4, 1)_and_(3, 1, 1)", - "op_name": "add", - "input_x": [ - [ - [ - [ - -1.9291036128997803 - ], - [ - 0.03497670218348503 - ], - [ - -0.4833625555038452 - ], - [ - -1.2260730266571045 - ] - ], - [ - [ - -1.6395642757415771 - ], - [ - 0.2299439013004303 - ], - [ - -0.44963574409484863 - ], - [ - -0.40768420696258545 - ] - ], - [ - [ - -0.011143443174660206 - ], - [ - 1.8151899576187134 - ], - [ - 0.6066091060638428 - ], - [ - 0.5963938236236572 - ] - ] - ], - [ - [ - [ - 0.5361921191215515 - ], - [ - 1.2350000143051147 - ], - [ - -0.21214154362678528 - ], - [ - 1.387345790863037 - ] - ], - [ - [ - -0.6384463906288147 - ], - [ - 0.737216591835022 - ], - [ - 1.1485421657562256 - ], - [ - 0.725890040397644 - ] - ], - [ - [ - -0.29366371035575867 - ], - [ - -0.6286743879318237 - ], - [ - -0.04226749762892723 - ], - [ - -0.27004849910736084 - ] - ] - ] - ], - "input_y": [ - [ - [ - 0.1034090593457222 - ] - ], - [ - [ - -0.5241618156433105 - ] - ], - [ - [ - -0.8587943315505981 - ] - ] - ], - "expected_output": [ - [ - [ - [ - -1.8256945610046387 - ], - [ - 0.13838575780391693 - ], - [ - -0.3799535036087036 - ], - [ - -1.122663974761963 - ] - ], - [ - [ - -2.1637260913848877 - ], - [ - -0.29421791434288025 - ], - [ - -0.9737975597381592 - ], - [ - -0.931846022605896 - ] - ], - [ - [ - -0.8699377775192261 - ], - [ - 0.9563956260681152 - ], - [ - -0.25218522548675537 - ], - [ - -0.2624005079269409 - ] - ] - ], - [ - [ - [ - 0.6396011710166931 - ], - [ - 1.3384090662002563 - ], - [ - -0.10873248428106308 - ], - [ - 1.4907548427581787 - ] - ], - [ - [ - -1.1626081466674805 - ], - [ - 0.21305477619171143 - ], - [ - 0.624380350112915 - ], - [ - 0.2017282247543335 - ] - ], - [ - [ - -1.1524580717086792 - ], - [ - -1.4874687194824219 - ], - [ - -0.9010618329048157 - ], - [ - -1.128842830657959 - ] - ] - ] - ], - "expected_grad_x": [ - [ - [ - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ] - ], - [ - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ] - ], - [ - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ] - ] - ], - [ - [ - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ] - ], - [ - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ] - ], - [ - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ], - [ - 1.0 - ] - ] - ] - ], - "expected_grad_y": [ - [ - [ - 8.0 - ] - ], - [ - [ - 8.0 - ] - ], - [ - [ - 8.0 - ] - ] - ] - }, - { - "test_name": "broadcast_mul_(2, 3, 4, 1)_and_(3, 1, 1)", - "op_name": "mul", - "input_x": [ - [ - [ - [ - 2.8818862438201904 - ], - [ - -1.1672022342681885 - ], - [ - 1.9413354396820068 - ], - [ - -1.163609266281128 - ] - ], - [ - [ - -1.5966553688049316 - ], - [ - 0.08320564776659012 - ], - [ - -0.9222075343132019 - ], - [ - -0.3711417317390442 - ] - ], - [ - [ - 0.1490848809480667 - ], - [ - -0.2603190541267395 - ], - [ - -0.7125067710876465 - ], - [ - -0.7577925324440002 - ] - ] - ], - [ - [ - [ - -0.6056803464889526 - ], - [ - -0.001647569122724235 - ], - [ - -0.48284876346588135 - ], - [ - -1.0801341533660889 - ] - ], - [ - [ - 0.9042091369628906 - ], - [ - -0.03959815204143524 - ], - [ - 0.3362662196159363 - ], - [ - -0.9519665837287903 - ] - ], - [ - [ - -0.08652620017528534 - ], - [ - 0.832058310508728 - ], - [ - 0.9070028066635132 - ], - [ - 0.03912770003080368 - ] - ] - ] - ], - "input_y": [ - [ - [ - -1.5896711349487305 - ] - ], - [ - [ - -0.040549930185079575 - ] - ], - [ - [ - 1.9009761810302734 - ] - ] - ], - "expected_output": [ - [ - [ - [ - -4.58125114440918 - ], - [ - 1.855467677116394 - ], - [ - -3.0860848426818848 - ], - [ - 1.849756121635437 - ] - ], - [ - [ - 0.0647442638874054 - ], - [ - -0.0033739833161234856 - ], - [ - 0.037395451217889786 - ], - [ - 0.015049771405756474 - ] - ], - [ - [ - 0.2834067940711975 - ], - [ - -0.49486032128334045 - ], - [ - -1.3544584512710571 - ], - [ - -1.4405455589294434 - ] - ] - ], - [ - [ - [ - 0.9628325700759888 - ], - [ - 0.0026190930511802435 - ], - [ - 0.7675707340240479 - ], - [ - 1.7170580625534058 - ] - ], - [ - [ - -0.03666561841964722 - ], - [ - 0.001605702331289649 - ], - [ - -0.013635572046041489 - ], - [ - 0.03860217705368996 - ] - ], - [ - [ - -0.16448424756526947 - ], - [ - 1.5817229747772217 - ], - [ - 1.7241907119750977 - ], - [ - 0.07438082247972488 - ] - ] - ] - ], - "expected_grad_x": [ - [ - [ - [ - -1.5896711349487305 - ], - [ - -1.5896711349487305 - ], - [ - -1.5896711349487305 - ], - [ - -1.5896711349487305 - ] - ], - [ - [ - -0.040549930185079575 - ], - [ - -0.040549930185079575 - ], - [ - -0.040549930185079575 - ], - [ - -0.040549930185079575 - ] - ], - [ - [ - 1.9009761810302734 - ], - [ - 1.9009761810302734 - ], - [ - 1.9009761810302734 - ], - [ - 1.9009761810302734 - ] - ] - ], - [ - [ - [ - -1.5896711349487305 - ], - [ - -1.5896711349487305 - ], - [ - -1.5896711349487305 - ], - [ - -1.5896711349487305 - ] - ], - [ - [ - -0.040549930185079575 - ], - [ - -0.040549930185079575 - ], - [ - -0.040549930185079575 - ], - [ - -0.040549930185079575 - ] - ], - [ - [ - 1.9009761810302734 - ], - [ - 1.9009761810302734 - ], - [ - 1.9009761810302734 - ], - [ - 1.9009761810302734 - ] - ] - ] - ], - "expected_grad_y": [ - [ - [ - 0.3220992088317871 - ] - ], - [ - [ - -2.5578882694244385 - ] - ], - [ - [ - 0.11012923717498779 - ] - ] - ] - }, - { - "test_name": "broadcast_add_(1,)_and_(3, 1, 2)", - "op_name": "add", - "input_x": [ - -0.6620396375656128 - ], - "input_y": [ - [ - [ - 0.2589207887649536, - -1.0626986026763916 - ] - ], - [ - [ - -1.4913355112075806, - 0.16728094220161438 - ] - ], - [ - [ - 0.7527865171432495, - 0.611292839050293 - ] - ] - ], - "expected_output": [ - [ - [ - -0.4031188488006592, - -1.7247382402420044 - ] - ], - [ - [ - -2.1533751487731934, - -0.4947586953639984 - ] - ], - [ - [ - 0.09074687957763672, - -0.050746798515319824 - ] - ] - ], - "expected_grad_x": [ - 6.0 - ], - "expected_grad_y": [ - [ - [ - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "broadcast_mul_(1,)_and_(3, 1, 2)", - "op_name": "mul", - "input_x": [ - -1.7093836069107056 - ], - "input_y": [ - [ - [ - -0.6855810284614563, - -0.10798398405313492 - ] - ], - [ - [ - -0.5913975834846497, - 0.7366381287574768 - ] - ], - [ - [ - 1.6831679344177246, - -0.3644360899925232 - ] - ] - ], - "expected_output": [ - [ - [ - 1.1719210147857666, - 0.1845860481262207 - ] - ], - [ - [ - 1.01092529296875, - -1.2591971158981323 - ] - ], - [ - [ - -2.8771796226501465, - 0.6229611039161682 - ] - ] - ], - "expected_grad_x": [ - 0.6704073548316956 - ], - "expected_grad_y": [ - [ - [ - -1.7093836069107056, - -1.7093836069107056 - ] - ], - [ - [ - -1.7093836069107056, - -1.7093836069107056 - ] - ], - [ - [ - -1.7093836069107056, - -1.7093836069107056 - ] - ] - ] - }, - { - "test_name": "broadcast_add_(5, 1, 4, 1)_and_(3, 1, 1)", - "op_name": "add", - "input_x": [ - [ - [ - [ - 1.6522549390792847 - ], - [ - -0.4681110680103302 - ], - [ - -1.3070950508117676 - ], - [ - -0.2728694975376129 - ] - ] - ], - [ - [ - [ - -1.0562596321105957 - ], - [ - 0.24130821228027344 - ], - [ - 0.18275369703769684 - ], - [ - 0.6246524453163147 - ] - ] - ], - [ - [ - [ - -0.7939775586128235 - ], - [ - -0.674835205078125 - ], - [ - -0.3876877427101135 - ], - [ - 0.44965043663978577 - ] - ] - ], - [ - [ - [ - 0.3726101517677307 - ], - [ - -1.9104946851730347 - ], - [ - 0.26085028052330017 - ], - [ - 1.4177610874176025 - ] - ] - ], - [ - [ - [ - 0.6738032102584839 - ], - [ - 1.4665507078170776 - ], - [ - -1.1077474355697632 - ], - [ - -0.7443782091140747 - ] - ] - ] - ], - "input_y": [ - [ - [ - -0.048239294439554214 - ] - ], - [ - [ - -0.8039766550064087 - ] - ], - [ - [ - -0.3882785737514496 - ] - ] - ], - "expected_output": [ - [ - [ - [ - 1.604015588760376 - ], - [ - -0.5163503885269165 - ], - [ - -1.3553344011306763 - ], - [ - -0.32110878825187683 - ] - ], - [ - [ - 0.848278284072876 - ], - [ - -1.2720876932144165 - ], - [ - -2.1110715866088867 - ], - [ - -1.0768461227416992 - ] - ], - [ - [ - 1.2639763355255127 - ], - [ - -0.8563896417617798 - ], - [ - -1.6953736543655396 - ], - [ - -0.6611480712890625 - ] - ] - ], - [ - [ - [ - -1.1044989824295044 - ], - [ - 0.19306892156600952 - ], - [ - 0.13451440632343292 - ], - [ - 0.5764131546020508 - ] - ], - [ - [ - -1.8602362871170044 - ], - [ - -0.5626684427261353 - ], - [ - -0.621222972869873 - ], - [ - -0.179324209690094 - ] - ], - [ - [ - -1.4445382356643677 - ], - [ - -0.14697036147117615 - ], - [ - -0.20552487671375275 - ], - [ - 0.2363738715648651 - ] - ] - ], - [ - [ - [ - -0.8422168493270874 - ], - [ - -0.7230744957923889 - ], - [ - -0.43592703342437744 - ], - [ - 0.40141114592552185 - ] - ], - [ - [ - -1.597954273223877 - ], - [ - -1.4788118600845337 - ], - [ - -1.191664457321167 - ], - [ - -0.3543262183666229 - ] - ], - [ - [ - -1.1822561025619507 - ], - [ - -1.063113808631897 - ], - [ - -0.7759662866592407 - ], - [ - 0.06137186288833618 - ] - ] - ], - [ - [ - [ - 0.3243708610534668 - ], - [ - -1.9587340354919434 - ], - [ - 0.21261098980903625 - ], - [ - 1.3695217370986938 - ] - ], - [ - [ - -0.431366503238678 - ], - [ - -2.7144713401794434 - ], - [ - -0.5431263446807861 - ], - [ - 0.6137844324111938 - ] - ], - [ - [ - -0.015668421983718872 - ], - [ - -2.2987732887268066 - ], - [ - -0.12742829322814941 - ], - [ - 1.0294824838638306 - ] - ] - ], - [ - [ - [ - 0.62556391954422 - ], - [ - 1.418311357498169 - ], - [ - -1.1559867858886719 - ], - [ - -0.7926174998283386 - ] - ], - [ - [ - -0.1301734447479248 - ], - [ - 0.662574052810669 - ], - [ - -1.9117240905761719 - ], - [ - -1.5483548641204834 - ] - ], - [ - [ - 0.2855246365070343 - ], - [ - 1.0782721042633057 - ], - [ - -1.4960260391235352 - ], - [ - -1.1326568126678467 - ] - ] - ] - ], - "expected_grad_x": [ - [ - [ - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ] - ] - ], - [ - [ - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ] - ] - ], - [ - [ - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ] - ] - ], - [ - [ - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ] - ] - ], - [ - [ - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ], - [ - 3.0 - ] - ] - ] - ], - "expected_grad_y": [ - [ - [ - 20.0 - ] - ], - [ - [ - 20.0 - ] - ], - [ - [ - 20.0 - ] - ] - ] - }, - { - "test_name": "broadcast_mul_(5, 1, 4, 1)_and_(3, 1, 1)", - "op_name": "mul", - "input_x": [ - [ - [ - [ - 0.7183824777603149 - ], - [ - -0.5719326138496399 - ], - [ - -0.46663370728492737 - ], - [ - 0.1017654687166214 - ] - ] - ], - [ - [ - [ - 0.7780604362487793 - ], - [ - -1.4069199562072754 - ], - [ - 0.4058326482772827 - ], - [ - 1.8279902935028076 - ] - ] - ], - [ - [ - [ - -1.4415538311004639 - ], - [ - -0.6341907978057861 - ], - [ - -1.9628868103027344 - ], - [ - -0.6502721905708313 - ] - ] - ], - [ - [ - [ - -1.4416067600250244 - ], - [ - -1.2435057163238525 - ], - [ - -1.226744532585144 - ], - [ - -0.14965394139289856 - ] - ] - ], - [ - [ - [ - -1.2425028085708618 - ], - [ - 1.4803948402404785 - ], - [ - 0.6343469023704529 - ], - [ - -0.7937742471694946 - ] - ] - ] - ], - "input_y": [ - [ - [ - -0.24528881907463074 - ] - ], - [ - [ - -0.477226585149765 - ] - ], - [ - [ - -1.3771432638168335 - ] - ] - ], - "expected_output": [ - [ - [ - [ - -0.1762111932039261 - ], - [ - 0.14028868079185486 - ], - [ - 0.11446002870798111 - ], - [ - -0.024961931630969048 - ] - ], - [ - [ - -0.34283122420310974 - ], - [ - 0.2729414403438568 - ], - [ - 0.22269001603126526 - ], - [ - -0.04856518656015396 - ] - ], - [ - [ - -0.9893155694007874 - ], - [ - 0.7876331210136414 - ], - [ - 0.6426214575767517 - ], - [ - -0.14014562964439392 - ] - ] - ], - [ - [ - [ - -0.19084952771663666 - ], - [ - 0.3451017439365387 - ], - [ - -0.09954620897769928 - ], - [ - -0.4483855664730072 - ] - ], - [ - [ - -0.37131112813949585 - ], - [ - 0.671419620513916 - ], - [ - -0.19367413222789764 - ], - [ - -0.8723655939102173 - ] - ], - [ - [ - -1.0715006589889526 - ], - [ - 1.9375303983688354 - ], - [ - -0.5588896870613098 - ], - [ - -2.517404556274414 - ] - ] - ], - [ - [ - [ - 0.3535970449447632 - ], - [ - 0.15555991232395172 - ], - [ - 0.4814741909503937 - ], - [ - 0.1595045030117035 - ] - ], - [ - [ - 0.6879478096961975 - ], - [ - 0.3026527166366577 - ], - [ - 0.9367417693138123 - ], - [ - 0.3103271722793579 - ] - ], - [ - [ - 1.9852261543273926 - ], - [ - 0.8733716011047363 - ], - [ - 2.703176259994507 - ], - [ - 0.8955179452896118 - ] - ] - ], - [ - [ - [ - 0.35361000895500183 - ], - [ - 0.30501803755760193 - ], - [ - 0.3009067177772522 - ], - [ - 0.03670843690633774 - ] - ], - [ - [ - 0.6879730820655823 - ], - [ - 0.5934339761734009 - ], - [ - 0.5854350924491882 - ], - [ - 0.07141883671283722 - ] - ], - [ - [ - 1.985298991203308 - ], - [ - 1.7124855518341064 - ], - [ - 1.6894029378890991 - ], - [ - 0.2060949206352234 - ] - ] - ], - [ - [ - [ - 0.3047720491886139 - ], - [ - -0.3631243109703064 - ], - [ - -0.1555982083082199 - ], - [ - 0.19470395147800446 - ] - ], - [ - [ - 0.5929553508758545 - ], - [ - -0.706483781337738 - ], - [ - -0.30272719264030457 - ], - [ - 0.37881016731262207 - ] - ], - [ - [ - 1.711104393005371 - ], - [ - -2.0387158393859863 - ], - [ - -0.8735865354537964 - ], - [ - 1.0931408405303955 - ] - ] - ] - ], - "expected_grad_x": [ - [ - [ - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ] - ] - ], - [ - [ - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ] - ] - ], - [ - [ - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ] - ] - ], - [ - [ - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ] - ] - ], - [ - [ - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ], - [ - -2.099658727645874 - ] - ] - ] - ], - "expected_grad_y": [ - [ - [ - -7.285405158996582 - ] - ], - [ - [ - -7.285405158996582 - ] - ], - [ - [ - -7.285405158996582 - ] - ] - ] - } - ], - "matmul": [ - { - "test_name": "matmul_1D_dot_product", - "input_x": [ - -0.13354362547397614, - -2.023963212966919, - -1.170003056526184 - ], - "input_y": [ - -1.1057088375091553, - -0.5529776215553284, - 1.1801894903182983 - ], - "expected_output": -0.11395859718322754, - "expected_grad_x": [ - -1.1057088375091553, - -0.5529776215553284, - 1.1801894903182983 - ], - "expected_grad_y": [ - -0.13354362547397614, - -2.023963212966919, - -1.170003056526184 - ] - }, - { - "test_name": "matmul_2D_matrix_multiply", - "input_x": [ - [ - 0.8215275406837463, - 0.1607755422592163, - -0.19208626449108124 - ], - [ - -0.6162866353988647, - -0.02657255157828331, - -0.25292056798934937 - ] - ], - "input_y": [ - [ - -0.28625473380088806, - 0.3182649314403534, - 1.1329631805419922, - -1.1634578704833984 - ], - [ - -2.6641499996185303, - 1.012193202972412, - -0.6236492991447449, - 0.5437685251235962 - ], - [ - -2.3363192081451416, - 0.10341913998126984, - 0.25140896439552307, - 1.244645357131958 - ] - ], - "expected_output": [ - [ - -0.21472150087356567, - 0.4043339192867279, - 0.7822006940841675, - -1.1074672937393188 - ], - [ - 0.838111400604248, - -0.24919579923152924, - -0.7452446222305298, - 0.38777783513069153 - ] - ], - "expected_grad_x": [ - [ - 0.001515507698059082, - -1.7318376302719116, - -0.736845850944519 - ], - [ - 0.001515507698059082, - -1.7318376302719116, - -0.736845850944519 - ] - ], - "expected_grad_y": [ - [ - 0.2052409052848816, - 0.2052409052848816, - 0.2052409052848816, - 0.2052409052848816 - ], - [ - 0.1342029869556427, - 0.1342029869556427, - 0.1342029869556427, - 0.1342029869556427 - ], - [ - -0.4450068473815918, - -0.4450068473815918, - -0.4450068473815918, - -0.4450068473815918 - ] - ] - }, - { - "test_name": "matmul_1D_2D_prepend_remove", - "input_x": [ - 0.5262587070465088, - 0.7186952829360962, - 0.2846910357475281 - ], - "input_y": [ - [ - 0.40772733092308044, - 0.25750425457954407, - 0.9894949793815613, - -0.13609549403190613 - ], - [ - -0.046313412487506866, - -0.8070783019065857, - -0.8997132778167725, - 0.4604453444480896 - ], - [ - 0.09099376946687698, - 1.264731764793396, - -0.5384116172790527, - -0.5032119154930115 - ] - ], - "expected_output": [ - 0.20718994736671448, - -0.08447171002626419, - -0.27917027473449707, - 0.11603852361440659 - ], - "expected_grad_x": [ - 1.518631100654602, - -1.2926596403121948, - 0.3141019344329834 - ], - "expected_grad_y": [ - [ - 0.5262587070465088, - 0.5262587070465088, - 0.5262587070465088, - 0.5262587070465088 - ], - [ - 0.7186952829360962, - 0.7186952829360962, - 0.7186952829360962, - 0.7186952829360962 - ], - [ - 0.2846910357475281, - 0.2846910357475281, - 0.2846910357475281, - 0.2846910357475281 - ] - ] - }, - { - "test_name": "matmul_2D_1D_matrix_vector", - "input_x": [ - [ - -1.1151187419891357, - -0.6466555595397949, - -0.9256587624549866 - ], - [ - 1.9982808828353882, - 0.34709975123405457, - -0.10135623067617416 - ] - ], - "input_y": [ - -0.7542831897735596, - 1.9345619678497314, - -1.2589340209960938 - ], - "expected_output": [ - 0.7554633021354675, - -0.7081828713417053 - ], - "expected_grad_x": [ - [ - -0.7542831897735596, - 1.9345619678497314, - -1.2589340209960938 - ], - [ - -0.7542831897735596, - 1.9345619678497314, - -1.2589340209960938 - ] - ], - "expected_grad_y": [ - 0.8831621408462524, - -0.29955580830574036, - -1.027014970779419 - ] - }, - { - "test_name": "matmul_ND_batched_with_broadcast", - "input_x": [ - [ - [ - [ - -0.38954418897628784, - 0.5330391526222229, - -0.24234455823898315 - ], - [ - 0.6653695106506348, - 0.9382926821708679, - 0.044521868228912354 - ] - ] - ], - [ - [ - [ - 1.1535056829452515, - 1.0917677879333496, - 0.04327869415283203 - ], - [ - -1.7126272916793823, - -1.030257225036621, - -0.5207390189170837 - ] - ] - ] - ], - "input_y": [ - [ - [ - 1.6714451313018799, - -0.4941222369670868 - ], - [ - 1.1431647539138794, - 1.3563427925109863 - ], - [ - -1.2485027313232422, - -0.02572690322995186 - ] - ], - [ - [ - 1.936702013015747, - -0.9197023510932922 - ], - [ - 0.8713390231132507, - -0.522757887840271 - ], - [ - -1.287382960319519, - -1.2039293050765991 - ] - ], - [ - [ - -0.6580986976623535, - -0.35780131816864014 - ], - [ - 0.4201647937297821, - -0.0068255518563091755 - ], - [ - 0.33024173974990845, - -0.9533721804618835 - ] - ] - ], - "expected_output": [ - [ - [ - [ - 0.2608177065849304, - 0.9217010736465454 - ], - [ - 2.1291661262512207, - 0.942727267742157 - ] - ], - [ - [ - 0.022017061710357666, - 0.3713800013065338 - ], - [ - 2.0488767623901367, - -1.1560429334640503 - ] - ], - [ - [ - 0.4002905488014221, - 0.3667857050895691 - ], - [ - -0.02893828973174095, - -0.28692036867141724 - ] - ] - ], - [ - [ - [ - 3.122058391571045, - 0.9097251296043396 - ], - [ - -3.3901724815368652, - -0.5377377867698669 - ] - ], - [ - [ - 3.129580497741699, - -1.6837165355682373 - ], - [ - -3.544161319732666, - 2.7406153678894043 - ] - ], - [ - [ - -0.28610578179359436, - -0.46143847703933716 - ], - [ - 0.5222302675247192, - 1.1162704229354858 - ] - ] - ] - ], - "expected_grad_x": [ - [ - [ - [ - 1.1784225702285767, - 3.261427640914917, - -4.388672351837158 - ], - [ - 1.1784225702285767, - 3.261427640914917, - -4.388672351837158 - ] - ] - ], - [ - [ - [ - 1.1784225702285767, - 3.261427640914917, - -4.388672351837158 - ], - [ - 1.1784225702285767, - 3.261427640914917, - -4.388672351837158 - ] - ] - ] - ], - "expected_grad_y": [ - [ - [ - -0.28329628705978394, - -0.28329628705978394 - ], - [ - 1.5328423976898193, - 1.5328423976898193 - ], - [ - -0.6752830147743225, - -0.6752830147743225 - ] - ], - [ - [ - -0.28329628705978394, - -0.28329628705978394 - ], - [ - 1.5328423976898193, - 1.5328423976898193 - ], - [ - -0.6752830147743225, - -0.6752830147743225 - ] - ], - [ - [ - -0.28329628705978394, - -0.28329628705978394 - ], - [ - 1.5328423976898193, - 1.5328423976898193 - ], - [ - -0.6752830147743225, - -0.6752830147743225 - ] - ] - ] - } - ], - "reductions": [ - { - "test_name": "sum_dim_None_keepdim_False", - "op_name": "sum", - "dim": null, - "keepdim": false, - "input": [ - [ - [ - -0.4858148694038391, - -0.49008455872535706, - 0.9206437468528748, - -0.6285682320594788, - 0.6663421988487244 - ], - [ - -0.03547006472945213, - -0.11422315984964371, - -0.05629456788301468, - 0.2728163003921509, - 0.7324181199073792 - ], - [ - 1.7147032022476196, - -2.687852621078491, - -0.042423129081726074, - 0.7085697650909424, - -1.2797164916992188 - ], - [ - -1.5433486700057983, - 1.2571464776992798, - 0.5763423442840576, - -0.9772611856460571, - -1.533514380455017 - ] - ], - [ - [ - 0.7982524633407593, - -0.5078546404838562, - -0.91661536693573, - 0.4702746272087097, - -1.750167965888977 - ], - [ - 0.9156812429428101, - -0.7037500739097595, - 1.2993873357772827, - -1.6580263376235962, - 3.150531768798828 - ], - [ - -0.2053070068359375, - -1.4739270210266113, - -0.03289732709527016, - 0.3655078113079071, - -0.03989681601524353 - ], - [ - -1.2108122110366821, - -1.6996815204620361, - -0.4819910228252411, - -0.9970720410346985, - -0.34807199239730835 - ] - ], - [ - [ - 0.29087918996810913, - -0.1686161607503891, - -0.7467212677001953, - 1.4040724039077759, - 1.2316521406173706 - ], - [ - 2.9194436073303223, - 0.4634987413883209, - 0.6845051050186157, - 1.5183887481689453, - -0.91494220495224 - ], - [ - 2.251573324203491, - -0.3680903911590576, - -2.4219810962677, - -0.08308011293411255, - 0.683392345905304 - ], - [ - 2.353518486022949, - 0.04335293173789978, - 0.580488383769989, - 0.6679447293281555, - 0.6449635624885559 - ] - ] - ], - "expected_output": 2.9822170734405518, - "expected_grad": [ - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "sum_dim_0_keepdim_False", - "op_name": "sum", - "dim": 0, - "keepdim": false, - "input": [ - [ - [ - 1.4343817234039307, - -1.9291707277297974, - -1.6733232736587524, - 0.9231958985328674, - -0.020498022437095642 - ], - [ - 0.48795756697654724, - 0.37779226899147034, - -1.057392954826355, - -0.22911065816879272, - -0.3448553681373596 - ], - [ - 0.4634801745414734, - 1.4675588607788086, - 1.5677039623260498, - 0.4278451204299927, - -0.2732718884944916 - ], - [ - 0.5940448641777039, - -0.34265488386154175, - 1.2370060682296753, - 1.1887205839157104, - 1.002081274986267 - ] - ], - [ - [ - -1.4646551609039307, - -0.030163101851940155, - -0.11644338816404343, - 0.3850177526473999, - 0.05211031809449196 - ], - [ - 0.2882064878940582, - 0.35200777649879456, - -0.3861907422542572, - 0.3567925691604614, - 1.7113765478134155 - ], - [ - 0.21664851903915405, - 0.3170451521873474, - -0.1140289157629013, - -0.8452204465866089, - 0.5263259410858154 - ], - [ - 0.12554097175598145, - -1.7527469396591187, - 0.7751637697219849, - -0.10626579821109772, - 0.8907954692840576 - ] - ], - [ - [ - 2.0987792015075684, - -0.5285679697990417, - -0.4658718407154083, - 0.49164071679115295, - 0.6064606308937073 - ], - [ - -0.46068817377090454, - -0.8800807595252991, - -1.4766337871551514, - 0.982934296131134, - 0.034095875918865204 - ], - [ - -0.461677223443985, - 0.3484693765640259, - -1.7167327404022217, - 0.04617787152528763, - 0.09389957040548325 - ], - [ - -1.35635244846344, - -1.0603324174880981, - 1.0654057264328003, - 0.8679789900779724, - -0.5582399368286133 - ] - ] - ], - "expected_output": [ - [ - 2.0685057640075684, - -2.4879016876220703, - -2.255638599395752, - 1.7998543977737427, - 0.6380729079246521 - ], - [ - 0.3154758810997009, - -0.15028071403503418, - -2.920217514038086, - 1.1106162071228027, - 1.400617003440857 - ], - [ - 0.21845147013664246, - 2.133073329925537, - -0.2630577087402344, - -0.3711974620819092, - 0.3469536304473877 - ], - [ - -0.6367666125297546, - -3.155734062194824, - 3.07757568359375, - 1.9504337310791016, - 1.3346368074417114 - ] - ], - "expected_grad": [ - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "sum_dim_0_keepdim_True", - "op_name": "sum", - "dim": 0, - "keepdim": true, - "input": [ - [ - [ - 0.02351505309343338, - 0.28558799624443054, - 0.020343216136097908, - 0.9289091229438782, - -0.9238923788070679 - ], - [ - 1.1473842859268188, - 0.941576361656189, - 0.4414193034172058, - -1.7462857961654663, - 0.7103408575057983 - ], - [ - -0.10175959765911102, - -0.9663392901420593, - -1.4231536388397217, - -0.7846477627754211, - 1.7235876321792603 - ], - [ - 0.1520993411540985, - -0.17470814287662506, - -1.7561272382736206, - 1.4259073734283447, - 0.5127183794975281 - ] - ], - [ - [ - -0.4026731848716736, - 1.9770677089691162, - -0.030815819278359413, - -1.737373948097229, - -0.09136287868022919 - ], - [ - -0.5283262729644775, - -0.46433013677597046, - -0.15669254958629608, - -1.5964131355285645, - -1.5322294235229492 - ], - [ - -0.11408505588769913, - -0.9761450290679932, - 0.24113479256629944, - -0.05469474941492081, - 0.04771281033754349 - ], - [ - -0.8637551665306091, - -1.141897201538086, - -0.8292406797409058, - 0.32627707719802856, - -0.14103326201438904 - ] - ], - [ - [ - -0.25818052887916565, - -1.340453863143921, - -0.5561836957931519, - 1.173104166984558, - 0.6556643843650818 - ], - [ - -0.7471360564231873, - 1.1705763339996338, - 1.6411151885986328, - 0.428303986787796, - -1.0703928470611572 - ], - [ - -0.6159464716911316, - -1.0194525718688965, - 0.37926265597343445, - 0.9845729470252991, - -1.7715047597885132 - ], - [ - 0.4349344074726105, - 0.06312361359596252, - -0.6894504427909851, - -0.2829807698726654, - 0.6600029468536377 - ] - ] - ], - "expected_output": [ - [ - [ - -0.6373386383056641, - 0.9222018718719482, - -0.5666562914848328, - 0.3646393418312073, - -0.3595908284187317 - ], - [ - -0.12807804346084595, - 1.647822618484497, - 1.9258419275283813, - -2.9143950939178467, - -1.892281413078308 - ], - [ - -0.8317911624908447, - -2.9619369506835938, - -0.8027561902999878, - 0.14523041248321533, - -0.00020432472229003906 - ], - [ - -0.27672144770622253, - -1.2534817457199097, - -3.2748184204101562, - 1.4692035913467407, - 1.0316880941390991 - ] - ] - ], - "expected_grad": [ - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "sum_dim_1_keepdim_False", - "op_name": "sum", - "dim": 1, - "keepdim": false, - "input": [ - [ - [ - -1.2625644207000732, - -0.1746397167444229, - 0.5484238862991333, - 0.45765289664268494, - 0.9676891565322876 - ], - [ - -0.6673583388328552, - 1.6183183193206787, - -0.26440465450286865, - -1.9805819988250732, - 0.6427897214889526 - ], - [ - -0.3697128891944885, - -0.24597389996051788, - 0.3293827772140503, - 0.6973733305931091, - 0.8342204093933105 - ], - [ - -1.098692774772644, - 0.17085814476013184, - -0.7267439365386963, - -3.832531690597534, - 0.11584769189357758 - ] - ], - [ - [ - 1.9915446043014526, - 1.0238094329833984, - 2.1327197551727295, - 0.23347528278827667, - -0.3182602822780609 - ], - [ - -0.28946641087532043, - -0.9444983005523682, - -0.1793764978647232, - 0.31204938888549805, - 0.717379093170166 - ], - [ - -0.2302778661251068, - 0.7147674560546875, - 0.14227113127708435, - -0.9353750944137573, - -0.8332573175430298 - ], - [ - -0.952683687210083, - -0.36366915702819824, - -1.2479252815246582, - -0.09261447191238403, - 0.6533640027046204 - ] - ], - [ - [ - -0.5295901894569397, - -0.6448984146118164, - -0.369537353515625, - -0.47141557931900024, - 1.2438589334487915 - ], - [ - -1.7002424001693726, - -1.2208786010742188, - -1.3158544301986694, - -1.8084080219268799, - -0.4799889922142029 - ], - [ - 0.7350953221321106, - -0.269319087266922, - 0.8924283385276794, - 1.3709611892700195, - 0.7821508049964905 - ], - [ - -0.30908405780792236, - 0.6509400010108948, - -1.5479099750518799, - -1.2930028438568115, - 0.8795658946037292 - ] - ] - ], - "expected_output": [ - [ - -3.3983283042907715, - 1.3685628175735474, - -0.11334192752838135, - -4.658087253570557, - 2.560546875 - ], - [ - 0.5191166400909424, - 0.43040943145751953, - 0.847689151763916, - -0.48246490955352783, - 0.21922549605369568 - ], - [ - -1.8038214445114136, - -1.4841561317443848, - -2.3408734798431396, - -2.2018651962280273, - 2.425586700439453 - ] - ], - "expected_grad": [ - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "sum_dim_1_keepdim_True", - "op_name": "sum", - "dim": 1, - "keepdim": true, - "input": [ - [ - [ - -0.03328368067741394, - -0.1935928761959076, - -0.7671046257019043, - 1.041800618171692, - -0.5939895510673523 - ], - [ - -0.9907869696617126, - -0.9927570819854736, - -0.2557562291622162, - -0.22515931725502014, - 0.7214905023574829 - ], - [ - 0.12578019499778748, - 1.4050774574279785, - 0.19477412104606628, - -0.4741835296154022, - 0.1276102066040039 - ], - [ - 0.6101059317588806, - -0.3841469883918762, - -0.921748697757721, - -0.4872817397117615, - -0.5074361562728882 - ] - ], - [ - [ - 0.5522661805152893, - 0.061027202755212784, - -0.9556332230567932, - -0.7779799103736877, - 1.3941880464553833 - ], - [ - -0.2754690647125244, - -0.5164039731025696, - 0.1548738032579422, - -0.8348855972290039, - 0.22885975241661072 - ], - [ - -2.0042972564697266, - 0.005512263625860214, - -0.3478994369506836, - 0.5377600193023682, - -0.9290909767150879 - ], - [ - 1.1321873664855957, - -0.7327660322189331, - 1.1509846448898315, - -0.6960206627845764, - 0.5155009627342224 - ] - ], - [ - [ - 0.27344995737075806, - 0.6651293039321899, - 1.0537790060043335, - 0.7269541621208191, - -0.4144572615623474 - ], - [ - -0.7832543253898621, - 1.1300108432769775, - -1.612937569618225, - 0.445094496011734, - 0.051411572843790054 - ], - [ - -0.35013654828071594, - -1.006677508354187, - -0.534939169883728, - 0.9171100854873657, - -1.031330943107605 - ], - [ - -0.3431452810764313, - -0.5040718913078308, - 0.07251296937465668, - -1.078025221824646, - -0.39548805356025696 - ] - ] - ], - "expected_output": [ - [ - [ - -0.2881844639778137, - -0.16541951894760132, - -1.74983549118042, - -0.14482393860816956, - -0.25232499837875366 - ] - ], - [ - [ - -0.5953128337860107, - -1.1826305389404297, - 0.002325773239135742, - -1.7711260318756104, - 1.2094578742980957 - ] - ], - [ - [ - -1.2030861377716064, - 0.28439074754714966, - -1.0215847492218018, - 1.0111335515975952, - -1.7898646593093872 - ] - ] - ], - "expected_grad": [ - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "sum_dim_-1_keepdim_False", - "op_name": "sum", - "dim": -1, - "keepdim": false, - "input": [ - [ - [ - -0.16857317090034485, - 0.688886284828186, - 0.09771557152271271, - 1.052785038948059, - -1.1113090515136719 - ], - [ - -0.9389597773551941, - -1.3075956106185913, - 0.9676118493080139, - -0.7394251227378845, - -1.5103271007537842 - ], - [ - 0.08060058951377869, - -1.8929684162139893, - 0.5650917887687683, - 0.8412631750106812, - -0.9580911993980408 - ], - [ - -0.7895215749740601, - 0.015372429974377155, - -0.027610722929239273, - -0.053718894720077515, - -0.7734133005142212 - ] - ], - [ - [ - -1.3837915658950806, - 0.97823166847229, - 1.2639201879501343, - -2.0509865283966064, - 0.7195857763290405 - ], - [ - 0.5959717631340027, - -1.8225737810134888, - -0.1343626081943512, - 0.49848124384880066, - 0.3930509090423584 - ], - [ - -0.6577728390693665, - 0.24517367780208588, - 0.20588766038417816, - -0.8329556584358215, - -0.820264458656311 - ], - [ - -0.8202312588691711, - 0.9118992686271667, - -1.6226643323898315, - 0.6528452634811401, - 0.474252313375473 - ] - ], - [ - [ - -1.0028913021087646, - 0.06786083430051804, - 0.5943557024002075, - -1.4299345016479492, - -1.8149548768997192 - ], - [ - -0.48883718252182007, - 0.3190588653087616, - 0.8207234740257263, - 0.26855215430259705, - 0.5349103808403015 - ], - [ - 0.2828715443611145, - 0.2559785544872284, - -0.3839770257472992, - 0.9996393918991089, - -0.411981463432312 - ], - [ - 1.7920981645584106, - -0.7672699093818665, - -1.307977557182312, - -1.7257500886917114, - -0.03232753649353981 - ] - ] - ], - "expected_output": [ - [ - 0.5595046877861023, - -3.528696060180664, - -1.364104151725769, - -1.628892183303833 - ], - [ - -0.47304046154022217, - -0.4694325029850006, - -1.8599317073822021, - -0.4038987159729004 - ], - [ - -3.585564136505127, - 1.4544076919555664, - 0.7425310015678406, - -2.041226863861084 - ] - ], - "expected_grad": [ - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ], - [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] - ] - ] - }, - { - "test_name": "sum_dim_-1_keepdim_True", - "op_name": "sum", - "dim": -1, - "keepdim": true, - "input": [ - [ - [ - 1.3067461252212524, - 0.1913401335477829, - 1.3767470121383667, - 0.6892044544219971, - 0.43921586871147156 - ], [ - -0.04813985526561737, - -0.3315163552761078, - -0.23632389307022095, - -0.08464081585407257, - -0.2434539496898651 + [-1.9291036128997803], + [0.03497670218348503], + [-0.4833625555038452], + [-1.2260730266571045] ], [ - -1.4118940830230713, - -1.0503880977630615, - 1.110618233680725, - 0.21369199454784393, - 0.9332243204116821 + [-1.6395642757415771], + [0.2299439013004303], + [-0.44963574409484863], + [-0.40768420696258545] ], [ - 0.7342482805252075, - -1.1814165115356445, - -0.9001671671867371, - 2.1022186279296875, - 0.13313262164592743 + [-0.011143443174660206], + [1.8151899576187134], + [0.6066091060638428], + [0.5963938236236572] ] ], [ [ - 0.022425031289458275, - -0.2799490988254547, - -0.13277991116046906, - -1.1816505193710327, - -1.7333787679672241 + [0.5361921191215515], + [1.2350000143051147], + [-0.21214154362678528], + [1.387345790863037] ], [ - 1.1858826875686646, - 0.4465799629688263, - 1.1301037073135376, - -0.3333589434623718, - 0.8935588598251343 + [-0.6384463906288147], + [0.737216591835022], + [1.1485421657562256], + [0.725890040397644] ], [ - -1.948160171508789, - -1.366417646408081, - 0.009384111501276493, - 0.6304294466972351, - 0.8632985949516296 - ], - [ - 1.1419644355773926, - 0.3109254240989685, - -0.10642467439174652, - -1.2388849258422852, - -1.1811842918395996 + [-0.29366371035575867], + [-0.6286743879318237], + [-0.04226749762892723], + [-0.27004849910736084] ] + ] + ], + "input_y": [ + [ + [0.1034090593457222] ], [ - [ - 0.8579769134521484, - -1.6933249235153198, - 0.28935855627059937, - 0.12979160249233246, - 0.9177106618881226 - ], - [ - -0.08528606593608856, - 0.646186888217926, - 0.9474418759346008, - -0.9643430113792419, - -0.05544678866863251 - ], - [ - 0.6487414836883545, - -1.5244767665863037, - 0.7500134110450745, - -2.1544389724731445, - 1.4023377895355225 - ], - [ - 0.38867735862731934, - 0.7254555821418762, - -1.389511227607727, - -0.8552696704864502, - -1.5335310697555542 - ] + [-0.5241618156433105] + ], + [ + [-0.8587943315505981] ] ], "expected_output": [ [ [ - 4.003253936767578 - ], - [ - -0.9440748691558838 - ], - [ - -0.20474763214588165 - ], - [ - 0.888015866279602 - ] - ], - [ - [ - -3.305333137512207 - ], - [ - 3.322766065597534 + [-1.8256945610046387], + [0.13838575780391693], + [-0.3799535036087036], + [-1.122663974761963] ], [ - -1.8114655017852783 + [-2.1637260913848877], + [-0.29421791434288025], + [-0.9737975597381592], + [-0.931846022605896] ], [ - -1.0736039876937866 + [-0.8699377775192261], + [0.9563956260681152], + [-0.25218522548675537], + [-0.2624005079269409] ] ], [ [ - 0.5015128254890442 + [0.6396011710166931], + [1.3384090662002563], + [-0.10873248428106308], + [1.4907548427581787] ], [ - 0.48855286836624146 + [-1.1626081466674805], + [0.21305477619171143], + [0.624380350112915], + [0.2017282247543335] ], [ - -0.8778231143951416 - ], - [ - -2.6641790866851807 + [-1.1524580717086792], + [-1.4874687194824219], + [-0.9010618329048157], + [-1.128842830657959] ] ] ], - "expected_grad": [ + "expected_grad_x": [ [ [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + [1.0], + [1.0], + [1.0], + [1.0] ], [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + [1.0], + [1.0], + [1.0], + [1.0] ], [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + [1.0], + [1.0], + [1.0], + [1.0] ] ], [ [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + [1.0], + [1.0], + [1.0], + [1.0] ], [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + [1.0], + [1.0], + [1.0], + [1.0] ], [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 + [1.0], + [1.0], + [1.0], + [1.0] ] + ] + ], + "expected_grad_y": [ + [ + [8.0] ], [ - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0 - ] + [8.0] + ], + [ + [8.0] ] ] }, { - "test_name": "mean_dim_None_keepdim_False", - "op_name": "mean", - "dim": null, - "keepdim": false, - "input": [ + "test_name": "broadcast_mul_(2, 3, 4, 1)_and_(3, 1, 1)", + "op_name": "mul", + "input_x": [ [ [ - -1.1046700477600098, - 0.3997063636779785, - -0.7377328872680664, - 0.8807763457298279, - -0.7662639021873474 - ], - [ - 1.4585676193237305, - 1.7723872661590576, - 0.32965973019599915, - -0.014356887899339199, - 1.0570905208587646 + [2.8818862438201904], + [-1.1672022342681885], + [1.9413354396820068], + [-1.163609266281128] ], [ - 0.40178006887435913, - 0.6623095273971558, - -0.8157885074615479, - 1.7509973049163818, - -0.07119281589984894 + [-1.5966553688049316], + [0.08320564776659012], + [-0.9222075343132019], + [-0.3711417317390442] ], [ - -0.3190559148788452, - 0.050714727491140366, - 0.019659370183944702, - -0.06124546006321907, - -0.9422666430473328 + [0.1490848809480667], + [-0.2603190541267395], + [-0.7125067710876465], + [-0.7577925324440002] ] ], [ [ - 1.4318883419036865, - 0.13153165578842163, - -0.18222470581531525, - 0.3660371005535126, - 0.5798347592353821 + [-0.6056803464889526], + [-0.001647569122724235], + [-0.48284876346588135], + [-1.0801341533660889] ], [ - 0.2429470419883728, - -1.2091906070709229, - 0.07767737656831741, - 0.17619068920612335, - 0.578863799571991 + [0.9042091369628906], + [-0.03959815204143524], + [0.3362662196159363], + [-0.9519665837287903] ], [ - 1.5511679649353027, - 0.08444352447986603, - 1.2101210355758667, - -0.8561125993728638, - -0.01396828331053257 - ], - [ - -0.2777872681617737, - -0.7856798768043518, - 0.46062397956848145, - 0.566218376159668, - 1.1541569232940674 + [-0.08652620017528534], + [0.832058310508728], + [0.9070028066635132], + [0.03912770003080368] ] + ] + ], + "input_y": [ + [ + [-1.5896711349487305] ], + [ + [-0.040549930185079575] + ], + [ + [1.9009761810302734] + ] + ], + "expected_output": [ [ [ - -0.4426518380641937, - 1.2387607097625732, - -1.0242971181869507, - 0.7994512319564819, - 0.2551962435245514 - ], - [ - -1.102837324142456, - 0.8238721489906311, - 0.0035749999806284904, - -1.7263970375061035, - 0.23050972819328308 + [-4.58125114440918], + [1.855467677116394], + [-3.0860848426818848], + [1.849756121635437] ], [ - -0.006388451438397169, - -0.3764995038509369, - -0.12150754034519196, - 0.41562098264694214, - 1.0095174312591553 + [0.0647442638874054], + [-0.0033739833161234856], + [0.037395451217889786], + [0.015049771405756474] ], [ - 0.6818063259124756, - -0.7300068736076355, - -0.8303658366203308, - -0.9434769749641418, - 2.028413772583008 + [0.2834067940711975], + [-0.49486032128334045], + [-1.3544584512710571], + [-1.4405455589294434] ] - ] - ], - "expected_output": 0.15700183808803558, - "expected_grad": [ + ], [ [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 - ], - [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [0.9628325700759888], + [0.0026190930511802435], + [0.7675707340240479], + [1.7170580625534058] ], [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [-0.03666561841964722], + [0.001605702331289649], + [-0.013635572046041489], + [0.03860217705368996] ], [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [-0.16448424756526947], + [1.5817229747772217], + [1.7241907119750977], + [0.07438082247972488] ] - ], + ] + ], + "expected_grad_x": [ [ [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 - ], - [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [-1.5896711349487305], + [-1.5896711349487305], + [-1.5896711349487305], + [-1.5896711349487305] ], [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [-0.040549930185079575], + [-0.040549930185079575], + [-0.040549930185079575], + [-0.040549930185079575] ], [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [1.9009761810302734], + [1.9009761810302734], + [1.9009761810302734], + [1.9009761810302734] ] ], [ [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 - ], - [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [-1.5896711349487305], + [-1.5896711349487305], + [-1.5896711349487305], + [-1.5896711349487305] ], [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [-0.040549930185079575], + [-0.040549930185079575], + [-0.040549930185079575], + [-0.040549930185079575] ], [ - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107, - 0.01666666753590107 + [1.9009761810302734], + [1.9009761810302734], + [1.9009761810302734], + [1.9009761810302734] ] ] + ], + "expected_grad_y": [ + [ + [0.3220992088317871] + ], + [ + [-2.5578882694244385] + ], + [ + [0.11012923717498779] + ] ] }, { - "test_name": "mean_dim_0_keepdim_False", - "op_name": "mean", - "dim": 0, - "keepdim": false, - "input": [ + "test_name": "broadcast_add_(1,)_and_(3, 1, 2)", + "op_name": "add", + "input_x": [-0.6620396375656128], + "input_y": [ [ - [ - 0.1755259782075882, - 0.29882222414016724, - -0.6017733812332153, - 1.1090705394744873, - -0.26971787214279175 - ], - [ - -0.4379420578479767, - -1.0124340057373047, - -0.14667245745658875, - 0.15679313242435455, - 0.19906163215637207 - ], - [ - 0.6868006587028503, - -0.4260328412055969, - -0.7560138702392578, - 0.17112013697624207, - -0.7641999125480652 - ], - [ - -0.44291654229164124, - 1.180337905883789, - 0.37527406215667725, - 0.16405928134918213, - -0.5820143818855286 - ] + [0.2589207887649536, -1.0626986026763916] ], [ - [ - -0.6077602505683899, - -0.20455589890480042, - 0.5790372490882874, - -0.19989891350269318, - -0.06916097551584244 - ], - [ - -0.2501976788043976, - -0.631926953792572, - -0.10361812263727188, - 0.9832454323768616, - -0.21117885410785675 - ], - [ - 0.8466978073120117, - 0.8503185510635376, - -1.003414511680603, - -0.9655314683914185, - 0.21109014749526978 - ], - [ - -1.413875699043274, - 0.8920503854751587, - -0.30397742986679077, - -0.05114508792757988, - -0.6013848185539246 - ] + [-1.4913355112075806, 0.16728094220161438] ], [ - [ - 0.11547855287790298, - -0.17881472408771515, - -0.09405016899108887, - -0.6329993009567261, - -1.0465848445892334 - ], - [ - 1.3759163618087769, - 0.05762922391295433, - 0.35209375619888306, - 1.0967378616333008, - -0.9882838726043701 - ], - [ - 1.9996482133865356, - -1.2997536659240723, - -0.7523331046104431, - -0.47686854004859924, - 1.2204824686050415 - ], - [ - -0.15345095098018646, - -0.5119454264640808, - 0.11924147605895996, - 1.428880214691162, - 2.0869503021240234 - ] + [0.7527865171432495, 0.611292839050293] ] ], "expected_output": [ [ - -0.1055852472782135, - -0.028182798996567726, - -0.038928765803575516, - 0.09205744415521622, - -0.46182122826576233 - ], - [ - 0.22925888001918793, - -0.5289105772972107, - 0.033934395760297775, - 0.7455921173095703, - -0.333467036485672 + [-0.4031188488006592, -1.7247382402420044] ], [ - 1.1777156591415405, - -0.2918226420879364, - -0.8372538089752197, - -0.42375993728637695, - 0.22245757281780243 + [-2.1533751487731934, -0.4947586953639984] ], [ - -0.6700810790061951, - 0.5201475620269775, - 0.06351270526647568, - 0.5139314532279968, - 0.30118370056152344 + [0.09074687957763672, -0.050746798515319824] ] ], - "expected_grad": [ + "expected_grad_x": [6.0], + "expected_grad_y": [ [ - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ] + [1.0, 1.0] ], [ - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ] + [1.0, 1.0] ], [ - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ] + [1.0, 1.0] ] ] }, { - "test_name": "mean_dim_0_keepdim_True", - "op_name": "mean", - "dim": 0, - "keepdim": true, - "input": [ + "test_name": "broadcast_mul_(1,)_and_(3, 1, 2)", + "op_name": "mul", + "input_x": [-1.7093836069107056], + "input_y": [ [ - [ - 0.9313072562217712, - 0.11275313794612885, - -0.29632923007011414, - 0.6281623244285583, - 0.797209620475769 - ], - [ - 0.6957338452339172, - -0.18519674241542816, - 0.19908924400806427, - 0.21209175884723663, - 1.1861251592636108 - ], - [ - -0.08824097365140915, - -1.1839087009429932, - -0.23501551151275635, - 0.6680712103843689, - -0.7205530405044556 - ], - [ - 0.9816026091575623, - -0.15770527720451355, - 0.5783246755599976, - 0.5183308720588684, - 0.10639314353466034 - ] + [-0.6855810284614563, -0.10798398405313492] ], [ - [ - -0.0708099901676178, - 0.1868356168270111, - -1.135615348815918, - -0.6121562123298645, - 0.4646506905555725 - ], - [ - 0.9826740026473999, - 0.4591689705848694, - 0.3639809787273407, - 0.24808230996131897, - -0.5714194178581238 - ], - [ - -1.8829892873764038, - 1.6257703304290771, - 1.1227099895477295, - -0.24534782767295837, - 0.42072793841362 - ], - [ - 1.2927830219268799, - -0.062042392790317535, - -0.07447009533643723, - 1.8144526481628418, - 0.4126001298427582 - ] + [-0.5913975834846497, 0.7366381287574768] ], [ - [ - 1.5678290128707886, - -0.5997704267501831, - 0.13211850821971893, - -0.4554636776447296, - -0.32575365900993347 - ], - [ - 2.110002040863037, - -0.5582384467124939, - 0.3878994286060333, - -2.2768142223358154, - 0.37306782603263855 - ], - [ - -0.9947562217712402, - -1.3262041807174683, - -0.599851667881012, - 0.17797666788101196, - -1.143309235572815 - ], - [ - 1.3394620418548584, - -0.996752142906189, - -0.6021904945373535, - 0.32188680768013, - 0.1322384774684906 - ] + [1.6831679344177246, -0.3644360899925232] ] ], "expected_output": [ [ - [ - 0.8094420433044434, - -0.10006055980920792, - -0.43327537178993225, - -0.1464858502149582, - 0.31203556060791016 - ], - [ - 1.262803316116333, - -0.09475541114807129, - 0.3169898986816406, - -0.6055467128753662, - 0.3292578458786011 - ], - [ - -0.9886621832847595, - -0.2947808504104614, - 0.09594760090112686, - 0.2002333402633667, - -0.4810447692871094 - ], - [ - 1.2046159505844116, - -0.4054999351501465, - -0.03277863934636116, - 0.884890079498291, - 0.21707725524902344 - ] + [1.1719210147857666, 0.1845860481262207] + ], + [ + [1.01092529296875, -1.2591971158981323] + ], + [ + [-2.8771796226501465, 0.6229611039161682] ] ], - "expected_grad": [ + "expected_grad_x": [0.6704073548316956], + "expected_grad_y": [ [ - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ] + [-1.7093836069107056, -1.7093836069107056] ], [ - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ] + [-1.7093836069107056, -1.7093836069107056] ], [ - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ], - [ - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408, - 0.3333333432674408 - ] + [-1.7093836069107056, -1.7093836069107056] ] ] }, { - "test_name": "mean_dim_1_keepdim_False", - "op_name": "mean", - "dim": 1, - "keepdim": false, - "input": [ + "test_name": "broadcast_add_(5, 1, 4, 1)_and_(3, 1, 1)", + "op_name": "add", + "input_x": [ [ [ - 0.27381452918052673, - 1.7188366651535034, - 1.3450311422348022, - -1.2653104066848755, - 0.45117413997650146 - ], - [ - 0.6597211360931396, - -2.012479305267334, - -0.516261100769043, - -1.0803741216659546, - 1.424518346786499 - ], - [ - -1.1213253736495972, - 0.3918372392654419, - -0.49036842584609985, - -0.2890629470348358, - -0.7217605710029602 - ], - [ - 1.9135220050811768, - 1.668276309967041, - 0.674127995967865, - 1.1708104610443115, - 0.02161409705877304 + [1.6522549390792847], + [-0.4681110680103302], + [-1.3070950508117676], + [-0.2728694975376129] ] ], [ [ - -0.9156265258789062, - 0.21846671402454376, - -0.5406830906867981, - -0.8299271464347839, - 2.0619850158691406 - ], - [ - 0.3048802316188812, - -1.4610782861709595, - -0.20266015827655792, - 0.03146770969033241, - 0.2910449504852295 - ], - [ - 0.5939645171165466, - 1.3427438735961914, - -0.6950612664222717, - 0.8987486362457275, - -0.763476550579071 - ], + [-1.0562596321105957], + [0.24130821228027344], + [0.18275369703769684], + [0.6246524453163147] + ] + ], + [ [ - -0.19663105905056, - -0.3633078634738922, - -1.5530608892440796, - -0.15105754137039185, - -0.5337246656417847 + [-0.7939775586128235], + [-0.674835205078125], + [-0.3876877427101135], + [0.44965043663978577] ] ], [ [ - 1.6809849739074707, - -0.11213088780641556, - -0.5451535582542419, - 0.5253366231918335, - 0.5843788981437683 - ], - [ - -2.286334276199341, - 0.5851041674613953, - 1.2774115800857544, - 0.8801257610321045, - 0.5200220942497253 - ], - [ - -1.0255969762802124, - 1.7627143859863281, - -0.0564274862408638, - 0.9568160176277161, - -0.6867133378982544 - ], + [0.3726101517677307], + [-1.9104946851730347], + [0.26085028052330017], + [1.4177610874176025] + ] + ], + [ [ - 1.02428138256073, - 1.7308460474014282, - -0.32468941807746887, - 0.3143851161003113, - -0.0669134333729744 + [0.6738032102584839], + [1.4665507078170776], + [-1.1077474355697632], + [-0.7443782091140747] ] ] ], - "expected_output": [ + "input_y": [ [ - 0.4314330816268921, - 0.4416177272796631, - 0.2531324028968811, - -0.3659842610359192, - 0.2938864827156067 + [-0.048239294439554214] ], [ - -0.053353201597929, - -0.06579387933015823, - -0.7478663921356201, - -0.012692078948020935, - 0.2639571726322174 + [-0.8039766550064087] ], [ - -0.15166622400283813, - 0.991633415222168, - 0.0877852812409401, - 0.6691659092903137, - 0.08769355714321136 + [-0.3882785737514496] ] ], - "expected_grad": [ + "expected_output": [ [ [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [1.604015588760376], + [-0.5163503885269165], + [-1.3553344011306763], + [-0.32110878825187683] ], [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [0.848278284072876], + [-1.2720876932144165], + [-2.1110715866088867], + [-1.0768461227416992] ], [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [1.2639763355255127], + [-0.8563896417617798], + [-1.6953736543655396], + [-0.6611480712890625] ] ], [ [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [-1.1044989824295044], + [0.19306892156600952], + [0.13451440632343292], + [0.5764131546020508] ], [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [-1.8602362871170044], + [-0.5626684427261353], + [-0.621222972869873], + [-0.179324209690094] ], [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [-1.4445382356643677], + [-0.14697036147117615], + [-0.20552487671375275], + [0.2363738715648651] ] ], [ [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ] - ] - ] - }, - { - "test_name": "mean_dim_1_keepdim_True", - "op_name": "mean", - "dim": 1, - "keepdim": true, - "input": [ - [ - [ - 0.8160833120346069, - -0.8233374357223511, - -2.1418421268463135, - 0.7724379897117615, - -0.6358500719070435 - ], - [ - 0.2520127594470978, - 0.9832903742790222, - 0.27252840995788574, - -0.9334322810173035, - -0.120673269033432 + [-0.8422168493270874], + [-0.7230744957923889], + [-0.43592703342437744], + [0.40141114592552185] ], [ - -1.6670103073120117, - -2.2226719856262207, - -1.0847980976104736, - 0.612401008605957, - -0.5785004496574402 + [-1.597954273223877], + [-1.4788118600845337], + [-1.191664457321167], + [-0.3543262183666229] ], [ - -0.725740909576416, - 0.42209234833717346, - -1.268004298210144, - 1.395574688911438, - -0.4016047418117523 + [-1.1822561025619507], + [-1.063113808631897], + [-0.7759662866592407], + [0.06137186288833618] ] ], [ [ - -0.47602152824401855, - 0.6024074554443359, - -0.13895398378372192, - -0.5199072957038879, - -0.49655959010124207 - ], - [ - 1.612599492073059, - -0.3255579173564911, - 0.9303890466690063, - -0.2840443551540375, - 0.8463886380195618 + [0.3243708610534668], + [-1.9587340354919434], + [0.21261098980903625], + [1.3695217370986938] ], [ - 0.018565375357866287, - -1.6755516529083252, - -1.5852235555648804, - 1.1069889068603516, - -0.6744462847709656 + [-0.431366503238678], + [-2.7144713401794434], + [-0.5431263446807861], + [0.6137844324111938] ], [ - -1.8892930746078491, - -1.842443585395813, - 0.13227719068527222, - -0.792870283126831, - 1.2297093868255615 + [-0.015668421983718872], + [-2.2987732887268066], + [-0.12742829322814941], + [1.0294824838638306] ] ], [ [ - -0.013317405246198177, - -0.30806609988212585, - -0.3388381898403168, - -0.46696820855140686, - 0.14354214072227478 - ], - [ - -0.9078568816184998, - 2.190314531326294, - 0.2566744089126587, - 0.4625372588634491, - -1.1410428285598755 + [0.62556391954422], + [1.418311357498169], + [-1.1559867858886719], + [-0.7926174998283386] ], [ - 1.7502615451812744, - -0.11171314865350723, - -1.1738200187683105, - -0.6320435404777527, - -1.0962568521499634 + [-0.1301734447479248], + [0.662574052810669], + [-1.9117240905761719], + [-1.5483548641204834] ], [ - -0.7847272753715515, - -0.5752313137054443, - 0.5138634443283081, - 1.050782322883606, - 1.3841030597686768 + [0.2855246365070343], + [1.0782721042633057], + [-1.4960260391235352], + [-1.1326568126678467] ] ] ], - "expected_output": [ + "expected_grad_x": [ [ [ - -0.33116379380226135, - -0.4101566970348358, - -1.055528998374939, - 0.46174535155296326, - -0.4341571629047394 + [3.0], + [3.0], + [3.0], + [3.0] ] ], [ [ - -0.18353742361068726, - -0.8102864027023315, - -0.16537782549858093, - -0.12245824933052063, - 0.22627303004264832 + [3.0], + [3.0], + [3.0], + [3.0] ] ], [ [ - 0.011089995503425598, - 0.2988259792327881, - -0.18553009629249573, - 0.10357695817947388, - -0.17741364240646362 + [3.0], + [3.0], + [3.0], + [3.0] ] - ] - ], - "expected_grad": [ + ], [ [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [3.0], + [3.0], + [3.0], + [3.0] ] ], [ [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 + [3.0], + [3.0], + [3.0], + [3.0] ] + ] + ], + "expected_grad_y": [ + [ + [20.0] ], [ - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ], - [ - 0.25, - 0.25, - 0.25, - 0.25, - 0.25 - ] + [20.0] + ], + [ + [20.0] ] ] }, { - "test_name": "mean_dim_-1_keepdim_False", - "op_name": "mean", - "dim": -1, - "keepdim": false, - "input": [ + "test_name": "broadcast_mul_(5, 1, 4, 1)_and_(3, 1, 1)", + "op_name": "mul", + "input_x": [ [ [ - 1.459913969039917, - -1.9324012994766235, - 0.295070618391037, - 1.953094482421875, - 0.062261566519737244 - ], - [ - -1.1078839302062988, - 0.976121723651886, - -0.07730520516633987, - -0.29665258526802063, - -0.26533499360084534 - ], - [ - -0.79975426197052, - 1.0418704748153687, - 1.3010565042495728, - -0.40846967697143555, - -0.7162472605705261 - ], - [ - -1.0271012783050537, - 0.1834021359682083, - -0.05814415216445923, - 0.3220038414001465, - 0.4668942093849182 + [0.7183824777603149], + [-0.5719326138496399], + [-0.46663370728492737], + [0.1017654687166214] ] ], [ [ - 0.014412929303944111, - -1.1832906007766724, - 0.03632983937859535, - 2.4672696590423584, - 1.3323793411254883 - ], - [ - -0.09307997673749924, - -1.1491583585739136, - 0.39312395453453064, - -0.3892734944820404, - 0.5293436646461487 - ], - [ - -0.6360014081001282, - -0.2509534955024719, - 0.4555503726005554, - -0.27460846304893494, - 0.9494737386703491 - ], - [ - -0.8720837235450745, - 0.8029743432998657, - 0.27744394540786743, - 0.33585336804389954, - -0.7603669166564941 + [0.7780604362487793], + [-1.4069199562072754], + [0.4058326482772827], + [1.8279902935028076] ] ], [ [ - -0.6846820712089539, - -0.7688948512077332, - 1.9104690551757812, - -0.9281872510910034, - -0.49309614300727844 - ], - [ - 0.50408536195755, - 0.998515248298645, - 0.0367455929517746, - 0.2297750562429428, - -1.984581470489502 - ], + [-1.4415538311004639], + [-0.6341907978057861], + [-1.9628868103027344], + [-0.6502721905708313] + ] + ], + [ [ - -1.2512000799179077, - 0.6219334602355957, - 0.051693860441446304, - -0.5315346121788025, - 0.5726004242897034 - ], + [-1.4416067600250244], + [-1.2435057163238525], + [-1.226744532585144], + [-0.14965394139289856] + ] + ], + [ [ - 0.3863498866558075, - 0.27223649621009827, - 0.46132177114486694, - 0.13579803705215454, - 0.516796886920929 + [-1.2425028085708618], + [1.4803948402404785], + [0.6343469023704529], + [-0.7937742471694946] ] ] ], - "expected_output": [ + "input_y": [ [ - 0.3675878643989563, - -0.15421099960803986, - 0.08369116485118866, - -0.022589052096009254 + [-0.24528881907463074] ], [ - 0.533420205116272, - -0.14180883765220642, - 0.04869214817881584, - -0.04323578625917435 + [-0.477226585149765] ], [ - -0.19287827610969543, - -0.04309204965829849, - -0.10730139166116714, - 0.35450059175491333 + [-1.3771432638168335] ] ], - "expected_grad": [ + "expected_output": [ [ [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-0.1762111932039261], + [0.14028868079185486], + [0.11446002870798111], + [-0.024961931630969048] ], [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-0.34283122420310974], + [0.2729414403438568], + [0.22269001603126526], + [-0.04856518656015396] ], [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-0.9893155694007874], + [0.7876331210136414], + [0.6426214575767517], + [-0.14014562964439392] ] ], [ [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-0.19084952771663666], + [0.3451017439365387], + [-0.09954620897769928], + [-0.4483855664730072] ], [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-0.37131112813949585], + [0.671419620513916], + [-0.19367413222789764], + [-0.8723655939102173] ], [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-1.0715006589889526], + [1.9375303983688354], + [-0.5588896870613098], + [-2.517404556274414] ] ], [ [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ] - ] - ] - }, - { - "test_name": "mean_dim_-1_keepdim_True", - "op_name": "mean", - "dim": -1, - "keepdim": true, - "input": [ - [ - [ - 1.0863715410232544, - -0.48916497826576233, - 1.751997470855713, - -0.3743889033794403, - 0.9508031606674194 - ], - [ - 1.3071852922439575, - -0.7512642741203308, - 0.005139758810400963, - 1.6046744585037231, - 0.08605138957500458 + [0.3535970449447632], + [0.15555991232395172], + [0.4814741909503937], + [0.1595045030117035] ], [ - 1.9344228506088257, - -0.44564706087112427, - -0.47476428747177124, - -0.30261677503585815, - -0.29394063353538513 + [0.6879478096961975], + [0.3026527166366577], + [0.9367417693138123], + [0.3103271722793579] ], [ - 2.5355067253112793, - 1.848445177078247, - -1.1966158151626587, - -0.4228180944919586, - -0.7322655916213989 + [1.9852261543273926], + [0.8733716011047363], + [2.703176259994507], + [0.8955179452896118] ] ], [ [ - -0.3979387581348419, - -0.004983691032975912, - -2.165992498397827, - 0.5304996371269226, - 2.260444164276123 - ], - [ - -0.3309515118598938, - 1.8614799976348877, - -0.11587686836719513, - -0.6822512745857239, - 0.4212978780269623 + [0.35361000895500183], + [0.30501803755760193], + [0.3009067177772522], + [0.03670843690633774] ], [ - -1.3226412534713745, - 1.2114580869674683, - -0.8475749492645264, - -0.09313177317380905, - -1.2082672119140625 + [0.6879730820655823], + [0.5934339761734009], + [0.5854350924491882], + [0.07141883671283722] ], [ - 3.168529987335205, - 2.297508955001831, - -0.14129851758480072, - -1.9953597784042358, - 0.035315316170454025 + [1.985298991203308], + [1.7124855518341064], + [1.6894029378890991], + [0.2060949206352234] ] ], [ [ - -1.0469098091125488, - -0.16152557730674744, - -0.5230178833007812, - -1.1935372352600098, - 1.8063979148864746 - ], - [ - 0.9378061294555664, - -0.38452786207199097, - 0.658501386642456, - 0.7616772055625916, - -0.6450856328010559 + [0.3047720491886139], + [-0.3631243109703064], + [-0.1555982083082199], + [0.19470395147800446] ], [ - 1.6012887954711914, - 0.35755881667137146, - 0.26440107822418213, - -0.5598823428153992, - 1.4536970853805542 + [0.5929553508758545], + [-0.706483781337738], + [-0.30272719264030457], + [0.37881016731262207] ], [ - -0.2962888479232788, - -0.4702155888080597, - -1.499106526374817, - -0.01866411603987217, - -1.5055760145187378 + [1.711104393005371], + [-2.0387158393859863], + [-0.8735865354537964], + [1.0931408405303955] ] ] ], - "expected_output": [ + "expected_grad_x": [ [ [ - 0.5851236581802368 - ], - [ - 0.4503573477268219 - ], - [ - 0.08349082618951797 - ], - [ - 0.40645045042037964 + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874] ] ], [ [ - 0.04440578073263168 - ], - [ - 0.23073963820934296 - ], - [ - -0.4520314633846283 - ], - [ - 0.6729391813278198 + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874] ] ], [ [ - -0.223718523979187 - ], - [ - 0.26567426323890686 - ], - [ - 0.6234126687049866 - ], - [ - -0.7579702138900757 + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874] ] - ] - ], - "expected_grad": [ + ], [ [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874] ] ], [ [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874], + [-2.099658727645874] ] + ] + ], + "expected_grad_y": [ + [ + [-7.285405158996582] ], [ - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ], - [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224 - ] + [-7.285405158996582] + ], + [ + [-7.285405158996582] ] ] + } + ], + "matmul": [ + { + "test_name": "matmul_1D_dot_product", + "input_x": [-0.13354362547397614, -2.023963212966919, -1.170003056526184], + "input_y": [-1.1057088375091553, -0.5529776215553284, 1.1801894903182983], + "expected_output": -0.11395859718322754, + "expected_grad_x": [-1.1057088375091553, -0.5529776215553284, 1.1801894903182983], + "expected_grad_y": [-0.13354362547397614, -2.023963212966919, -1.170003056526184] }, { - "test_name": "max_dim_None_keepdim_False", - "op_name": "max", - "dim": null, - "keepdim": false, - "input": [ + "test_name": "matmul_2D_matrix_multiply", + "input_x": [ + [0.8215275406837463, 0.1607755422592163, -0.19208626449108124], + [-0.6162866353988647, -0.02657255157828331, -0.25292056798934937] + ], + "input_y": [ + [-0.28625473380088806, 0.3182649314403534, 1.1329631805419922, -1.1634578704833984], + [-2.6641499996185303, 1.012193202972412, -0.6236492991447449, 0.5437685251235962], + [-2.3363192081451416, 0.10341913998126984, 0.25140896439552307, 1.244645357131958] + ], + "expected_output": [ + [-0.21472150087356567, 0.4043339192867279, 0.7822006940841675, -1.1074672937393188], + [0.838111400604248, -0.24919579923152924, -0.7452446222305298, 0.38777783513069153] + ], + "expected_grad_x": [ + [0.001515507698059082, -1.7318376302719116, -0.736845850944519], + [0.001515507698059082, -1.7318376302719116, -0.736845850944519] + ], + "expected_grad_y": [ + [0.2052409052848816, 0.2052409052848816, 0.2052409052848816, 0.2052409052848816], + [0.1342029869556427, 0.1342029869556427, 0.1342029869556427, 0.1342029869556427], + [-0.4450068473815918, -0.4450068473815918, -0.4450068473815918, -0.4450068473815918] + ] + }, + { + "test_name": "matmul_1D_2D_prepend_remove", + "input_x": [0.5262587070465088, 0.7186952829360962, 0.2846910357475281], + "input_y": [ + [0.40772733092308044, 0.25750425457954407, 0.9894949793815613, -0.13609549403190613], + [-0.046313412487506866, -0.8070783019065857, -0.8997132778167725, 0.4604453444480896], + [0.09099376946687698, 1.264731764793396, -0.5384116172790527, -0.5032119154930115] + ], + "expected_output": [0.20718994736671448, -0.08447171002626419, -0.27917027473449707, 0.11603852361440659], + "expected_grad_x": [1.518631100654602, -1.2926596403121948, 0.3141019344329834], + "expected_grad_y": [ + [0.5262587070465088, 0.5262587070465088, 0.5262587070465088, 0.5262587070465088], + [0.7186952829360962, 0.7186952829360962, 0.7186952829360962, 0.7186952829360962], + [0.2846910357475281, 0.2846910357475281, 0.2846910357475281, 0.2846910357475281] + ] + }, + { + "test_name": "matmul_2D_1D_matrix_vector", + "input_x": [ + [-1.1151187419891357, -0.6466555595397949, -0.9256587624549866], + [1.9982808828353882, 0.34709975123405457, -0.10135623067617416] + ], + "input_y": [-0.7542831897735596, 1.9345619678497314, -1.2589340209960938], + "expected_output": [0.7554633021354675, -0.7081828713417053], + "expected_grad_x": [ + [-0.7542831897735596, 1.9345619678497314, -1.2589340209960938], + [-0.7542831897735596, 1.9345619678497314, -1.2589340209960938] + ], + "expected_grad_y": [0.8831621408462524, -0.29955580830574036, -1.027014970779419] + }, + { + "test_name": "matmul_ND_batched_with_broadcast", + "input_x": [ [ [ - 1.3179066181182861, - 0.7556464672088623, - 1.2471561431884766, - 0.7881364822387695, - 1.5493229627609253 - ], - [ - -0.6088662147521973, - 1.4112409353256226, - -0.9075624346733093, - 1.1897660493850708, - -0.4802001118659973 - ], - [ - 2.2536263465881348, - 1.1717573404312134, - 0.8793008327484131, - -0.7796709537506104, - 1.4039242267608643 - ], - [ - 2.2192718982696533, - 0.36377331614494324, - 1.2563191652297974, - -0.1220834031701088, - 0.10120877623558044 + [-0.38954418897628784, 0.5330391526222229, -0.24234455823898315], + [0.6653695106506348, 0.9382926821708679, 0.044521868228912354] ] ], [ [ - 0.47121289372444153, - 0.6840168237686157, - -0.7728962898254395, - -0.3962509334087372, - 0.6629142165184021 - ], - [ - 0.6556671857833862, - 0.058465536683797836, - 0.7882350087165833, - -1.0857888460159302, - 1.0519514083862305 - ], - [ - 0.2087085098028183, - -1.4547972679138184, - -0.17086558043956757, - -2.0883853435516357, - 0.7963455319404602 - ], - [ - 0.4962165355682373, - 0.6029451489448547, - -0.5226418375968933, - 0.06845283508300781, - 0.3298587203025818 + [1.1535056829452515, 1.0917677879333496, 0.04327869415283203], + [-1.7126272916793823, -1.030257225036621, -0.5207390189170837] ] + ] + ], + "input_y": [ + [ + [1.6714451313018799, -0.4941222369670868], + [1.1431647539138794, 1.3563427925109863], + [-1.2485027313232422, -0.02572690322995186] ], [ - [ - -0.31479185819625854, - 0.02101830020546913, - -0.054547298699617386, - -0.8116031885147095, - -0.441931813955307 - ], - [ - 0.01032029278576374, - 1.8312735557556152, - -0.6159215569496155, - -0.6072822213172913, - -2.05973744392395 - ], - [ - 1.5289140939712524, - 0.3378683924674988, - -0.6198564171791077, - -0.7939390540122986, - 0.6710167527198792 - ], - [ - -0.4096096158027649, - -0.530225396156311, - 0.2532861530780792, - -0.19900000095367432, - 0.6101416945457458 - ] + [1.936702013015747, -0.9197023510932922], + [0.8713390231132507, -0.522757887840271], + [-1.287382960319519, -1.2039293050765991] + ], + [ + [-0.6580986976623535, -0.35780131816864014], + [0.4201647937297821, -0.0068255518563091755], + [0.33024173974990845, -0.9533721804618835] ] ], - "expected_output": 2.2536263465881348, - "expected_grad": [ + "expected_output": [ [ [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + [0.2608177065849304, 0.9217010736465454], + [2.1291661262512207, 0.942727267742157] ], [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 + [0.022017061710357666, 0.3713800013065338], + [2.0488767623901367, -1.1560429334640503] ], [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + [0.4002905488014221, 0.3667857050895691], + [-0.02893828973174095, -0.28692036867141724] ] ], [ [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + [3.122058391571045, 0.9097251296043396], + [-3.3901724815368652, -0.5377377867698669] ], [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + [3.129580497741699, -1.6837165355682373], + [-3.544161319732666, 2.7406153678894043] ], [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], + [-0.28610578179359436, -0.46143847703933716], + [0.5222302675247192, 1.1162704229354858] + ] + ] + ], + "expected_grad_x": [ + [ [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + [1.1784225702285767, 3.261427640914917, -4.388672351837158], + [1.1784225702285767, 3.261427640914917, -4.388672351837158] ] ], [ [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + [1.1784225702285767, 3.261427640914917, -4.388672351837158], + [1.1784225702285767, 3.261427640914917, -4.388672351837158] ] ] + ], + "expected_grad_y": [ + [ + [-0.28329628705978394, -0.28329628705978394], + [1.5328423976898193, 1.5328423976898193], + [-0.6752830147743225, -0.6752830147743225] + ], + [ + [-0.28329628705978394, -0.28329628705978394], + [1.5328423976898193, 1.5328423976898193], + [-0.6752830147743225, -0.6752830147743225] + ], + [ + [-0.28329628705978394, -0.28329628705978394], + [1.5328423976898193, 1.5328423976898193], + [-0.6752830147743225, -0.6752830147743225] + ] ] - }, + } + ], + "reductions": [ { - "test_name": "max_dim_0_keepdim_False", - "op_name": "max", - "dim": 0, + "test_name": "sum_dim_None_keepdim_False", + "op_name": "sum", + "dim": null, "keepdim": false, "input": [ [ - [ - 1.5443801879882812, - -0.35117071866989136, - 0.35557520389556885, - -1.8119957447052002, - 0.46456536650657654 - ], - [ - -0.5480050444602966, - -1.0596239566802979, - 0.17400647699832916, - 0.7506431937217712, - -0.6409745812416077 - ], - [ - -0.15132363140583038, - 0.625577986240387, - -0.6219039559364319, - -1.087321400642395, - -1.3252078294754028 - ], - [ - 0.37722504138946533, - -1.4066274166107178, - -0.2883475422859192, - -0.9860185384750366, - 1.4865750074386597 - ] + [-0.4858148694038391, -0.49008455872535706, 0.9206437468528748, -0.6285682320594788, 0.6663421988487244], + [-0.03547006472945213, -0.11422315984964371, -0.05629456788301468, 0.2728163003921509, 0.7324181199073792], + [1.7147032022476196, -2.687852621078491, -0.042423129081726074, 0.7085697650909424, -1.2797164916992188], + [-1.5433486700057983, 1.2571464776992798, 0.5763423442840576, -0.9772611856460571, -1.533514380455017] ], [ - [ - 0.14713206887245178, - -1.366032361984253, - -0.6708536148071289, - 0.9521092176437378, - -2.338611602783203 - ], - [ - -1.59005606174469, - -0.8660301566123962, - 1.278135895729065, - 0.35259687900543213, - -0.07500791549682617 - ], - [ - 0.40587425231933594, - 0.5351168513298035, - -1.4525551795959473, - 1.2706263065338135, - 0.2695809602737427 - ], - [ - -0.031602293252944946, - -1.2756946086883545, - -0.6372569799423218, - -0.761553168296814, - -0.4670298099517822 - ] + [0.7982524633407593, -0.5078546404838562, -0.91661536693573, 0.4702746272087097, -1.750167965888977], + [0.9156812429428101, -0.7037500739097595, 1.2993873357772827, -1.6580263376235962, 3.150531768798828], + [-0.2053070068359375, -1.4739270210266113, -0.03289732709527016, 0.3655078113079071, -0.03989681601524353], + [-1.2108122110366821, -1.6996815204620361, -0.4819910228252411, -0.9970720410346985, -0.34807199239730835] ], [ - [ - -2.774542808532715, - -0.20163610577583313, - -0.489888072013855, - -1.5937029123306274, - 0.7888379693031311 - ], - [ - -0.9375290870666504, - -0.14468862116336823, - -0.974236011505127, - 0.6229617595672607, - -0.34589967131614685 - ], - [ - -1.7239394187927246, - -0.9909027814865112, - -0.49027347564697266, - 0.09400757402181625, - 0.8530552983283997 - ], - [ - -0.01044454239308834, - 1.114724040031433, - -1.1784462928771973, - 0.6866339445114136, - 1.5644149780273438 - ] + [0.29087918996810913, -0.1686161607503891, -0.7467212677001953, 1.4040724039077759, 1.2316521406173706], + [2.9194436073303223, 0.4634987413883209, 0.6845051050186157, 1.5183887481689453, -0.91494220495224], + [2.251573324203491, -0.3680903911590576, -2.4219810962677, -0.08308011293411255, 0.683392345905304], + [2.353518486022949, 0.04335293173789978, 0.580488383769989, 0.6679447293281555, 0.6449635624885559] ] ], - "expected_output": [ + "expected_output": 2.9822170734405518, + "expected_grad": [ + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ], [ - 1.5443801879882812, - -0.20163610577583313, - 0.35557520389556885, - 0.9521092176437378, - 0.7888379693031311 + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - -0.5480050444602966, - -0.14468862116336823, - 1.278135895729065, - 0.7506431937217712, - -0.07500791549682617 + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ] + ] + }, + { + "test_name": "sum_dim_0_keepdim_False", + "op_name": "sum", + "dim": 0, + "keepdim": false, + "input": [ + [ + [1.4343817234039307, -1.9291707277297974, -1.6733232736587524, 0.9231958985328674, -0.020498022437095642], + [0.48795756697654724, 0.37779226899147034, -1.057392954826355, -0.22911065816879272, -0.3448553681373596], + [0.4634801745414734, 1.4675588607788086, 1.5677039623260498, 0.4278451204299927, -0.2732718884944916], + [0.5940448641777039, -0.34265488386154175, 1.2370060682296753, 1.1887205839157104, 1.002081274986267] ], [ - 0.40587425231933594, - 0.625577986240387, - -0.49027347564697266, - 1.2706263065338135, - 0.8530552983283997 + [-1.4646551609039307, -0.030163101851940155, -0.11644338816404343, 0.3850177526473999, 0.05211031809449196], + [0.2882064878940582, 0.35200777649879456, -0.3861907422542572, 0.3567925691604614, 1.7113765478134155], + [0.21664851903915405, 0.3170451521873474, -0.1140289157629013, -0.8452204465866089, 0.5263259410858154], + [0.12554097175598145, -1.7527469396591187, 0.7751637697219849, -0.10626579821109772, 0.8907954692840576] ], [ - 0.37722504138946533, - 1.114724040031433, - -0.2883475422859192, - 0.6866339445114136, - 1.5644149780273438 + [2.0987792015075684, -0.5285679697990417, -0.4658718407154083, 0.49164071679115295, 0.6064606308937073], + [-0.46068817377090454, -0.8800807595252991, -1.4766337871551514, 0.982934296131134, 0.034095875918865204], + [-0.461677223443985, 0.3484693765640259, -1.7167327404022217, 0.04617787152528763, 0.09389957040548325], + [-1.35635244846344, -1.0603324174880981, 1.0654057264328003, 0.8679789900779724, -0.5582399368286133] ] ], + "expected_output": [ + [2.0685057640075684, -2.4879016876220703, -2.255638599395752, 1.7998543977737427, 0.6380729079246521], + [0.3154758810997009, -0.15028071403503418, -2.920217514038086, 1.1106162071228027, 1.400617003440857], + [0.21845147013664246, 2.133073329925537, -0.2630577087402344, -0.3711974620819092, 0.3469536304473877], + [-0.6367666125297546, -3.155734062194824, 3.07757568359375, 1.9504337310791016, 1.3346368074417114] + ], "expected_grad": [ [ - [ - 1.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 1.0, - 0.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 1.0 - ], - [ - 1.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 0.0, - 1.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ] ] }, { - "test_name": "max_dim_0_keepdim_True", - "op_name": "max", + "test_name": "sum_dim_0_keepdim_True", + "op_name": "sum", "dim": 0, "keepdim": true, "input": [ [ - [ - 0.15242499113082886, - 0.06238764151930809, - 0.4020906984806061, - 1.6428531408309937, - -0.4024767577648163 - ], - [ - -0.6926602125167847, - 0.5779818296432495, - -0.02104124240577221, - 0.3675006031990051, - -1.6424492597579956 - ], - [ - 1.6906514167785645, - -1.885027527809143, - -0.7859907150268555, - -1.2742111682891846, - -1.0625808238983154 - ], - [ - -0.632580041885376, - -0.8688688278198242, - -1.5556751489639282, - 0.4562793970108032, - 0.26206839084625244 - ] + [0.02351505309343338, 0.28558799624443054, 0.020343216136097908, 0.9289091229438782, -0.9238923788070679], + [1.1473842859268188, 0.941576361656189, 0.4414193034172058, -1.7462857961654663, 0.7103408575057983], + [-0.10175959765911102, -0.9663392901420593, -1.4231536388397217, -0.7846477627754211, 1.7235876321792603], + [0.1520993411540985, -0.17470814287662506, -1.7561272382736206, 1.4259073734283447, 0.5127183794975281] ], [ - [ - 0.5024110674858093, - -0.4759514033794403, - 1.6630321741104126, - -1.454459547996521, - 1.3266892433166504 - ], - [ - 0.6551998853683472, - 0.6860383749008179, - -0.6831625699996948, - 0.8929892778396606, - 1.6672981977462769 - ], - [ - -1.0136138200759888, - -1.391968846321106, - -0.8026610612869263, - 0.45739221572875977, - -0.1074383333325386 - ], - [ - 2.130958080291748, - 0.24406017363071442, - 1.0900812149047852, - 0.7718657851219177, - 0.01673818565905094 - ] + [-0.4026731848716736, 1.9770677089691162, -0.030815819278359413, -1.737373948097229, -0.09136287868022919], + [-0.5283262729644775, -0.46433013677597046, -0.15669254958629608, -1.5964131355285645, -1.5322294235229492], + [-0.11408505588769913, -0.9761450290679932, 0.24113479256629944, -0.05469474941492081, 0.04771281033754349], + [-0.8637551665306091, -1.141897201538086, -0.8292406797409058, 0.32627707719802856, -0.14103326201438904] ], [ - [ - 0.2065047323703766, - -0.3839341402053833, - -0.5727554559707642, - -0.368385910987854, - 1.0989755392074585 - ], - [ - -0.2800213098526001, - -0.4368455111980438, - -0.7779284715652466, - 1.2181257009506226, - -0.1532776802778244 - ], - [ - 0.3922649621963501, - -0.24747081100940704, - 0.2792662978172302, - 0.2393292933702469, - 0.08084768056869507 - ], - [ - 0.45395395159721375, - -1.3717968463897705, - -0.47459128499031067, - -0.9676264524459839, - -0.6989938616752625 - ] + [-0.25818052887916565, -1.340453863143921, -0.5561836957931519, 1.173104166984558, 0.6556643843650818], + [-0.7471360564231873, 1.1705763339996338, 1.6411151885986328, 0.428303986787796, -1.0703928470611572], + [-0.6159464716911316, -1.0194525718688965, 0.37926265597343445, 0.9845729470252991, -1.7715047597885132], + [0.4349344074726105, 0.06312361359596252, -0.6894504427909851, -0.2829807698726654, 0.6600029468536377] ] ], "expected_output": [ [ - [ - 0.5024110674858093, - 0.06238764151930809, - 1.6630321741104126, - 1.6428531408309937, - 1.3266892433166504 - ], - [ - 0.6551998853683472, - 0.6860383749008179, - -0.02104124240577221, - 1.2181257009506226, - 1.6672981977462769 - ], - [ - 1.6906514167785645, - -0.24747081100940704, - 0.2792662978172302, - 0.45739221572875977, - 0.08084768056869507 - ], - [ - 2.130958080291748, - 0.24406017363071442, - 1.0900812149047852, - 0.7718657851219177, - 0.26206839084625244 - ] + [-0.6373386383056641, 0.9222018718719482, -0.5666562914848328, 0.3646393418312073, -0.3595908284187317], + [-0.12807804346084595, 1.647822618484497, 1.9258419275283813, -2.9143950939178467, -1.892281413078308], + [-0.8317911624908447, -2.9619369506835938, -0.8027561902999878, 0.14523041248321533, -0.00020432472229003906], + [-0.27672144770622253, -1.2534817457199097, -3.2748184204101562, 1.4692035913467407, 1.0316880941390991] ] ], "expected_grad": [ [ - [ - 0.0, - 1.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 1.0, - 0.0, - 1.0, - 0.0, - 1.0 - ], - [ - 1.0, - 1.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 1.0, - 1.0, - 1.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ] ] }, { - "test_name": "max_dim_1_keepdim_False", - "op_name": "max", + "test_name": "sum_dim_1_keepdim_False", + "op_name": "sum", "dim": 1, "keepdim": false, "input": [ [ - [ - 1.1716068983078003, - -1.7179490327835083, - -0.534604549407959, - -1.306166410446167, - -0.9246346950531006 - ], - [ - 0.6214187741279602, - 0.1785161793231964, - 0.2866869568824768, - 0.4850883483886719, - 0.005962289869785309 - ], - [ - -0.3370489478111267, - 1.0511995553970337, - -1.3509515523910522, - 0.5409456491470337, - 1.134432315826416 - ], - [ - -0.4212900400161743, - -0.10431576520204544, - 0.9755558371543884, - -1.0027341842651367, - 1.28053879737854 - ] + [-1.2625644207000732, -0.1746397167444229, 0.5484238862991333, 0.45765289664268494, 0.9676891565322876], + [-0.6673583388328552, 1.6183183193206787, -0.26440465450286865, -1.9805819988250732, 0.6427897214889526], + [-0.3697128891944885, -0.24597389996051788, 0.3293827772140503, 0.6973733305931091, 0.8342204093933105], + [-1.098692774772644, 0.17085814476013184, -0.7267439365386963, -3.832531690597534, 0.11584769189357758] ], [ - [ - 1.2130928039550781, - 0.12110324949026108, - -1.2743698358535767, - 0.884564220905304, - 0.12699493765830994 - ], - [ - -0.8810292482376099, - 1.8218294382095337, - 1.5863804817199707, - 0.865519106388092, - -0.27654826641082764 - ], - [ - -0.19467514753341675, - -0.03429529443383217, - 0.7240417003631592, - 0.13301636278629303, - -1.0541536808013916 - ], - [ - -2.312596321105957, - -0.902730405330658, - -1.4185947179794312, - 0.37751105427742004, - -0.2093215435743332 - ] + [1.9915446043014526, 1.0238094329833984, 2.1327197551727295, 0.23347528278827667, -0.3182602822780609], + [-0.28946641087532043, -0.9444983005523682, -0.1793764978647232, 0.31204938888549805, 0.717379093170166], + [-0.2302778661251068, 0.7147674560546875, 0.14227113127708435, -0.9353750944137573, -0.8332573175430298], + [-0.952683687210083, -0.36366915702819824, -1.2479252815246582, -0.09261447191238403, 0.6533640027046204] ], [ - [ - -1.1487538814544678, - 0.22709836065769196, - -0.9184321165084839, - 0.9846003651618958, - -0.06645472347736359 - ], - [ - 1.2572640180587769, - 0.1582425981760025, - -1.742975115776062, - -1.2938947677612305, - 1.3074569702148438 - ], - [ - -0.8769122958183289, - -0.015859045088291168, - -0.6937687397003174, - -0.8013211488723755, - -0.07756809890270233 - ], - [ - -0.5014570951461792, - -2.2269856929779053, - -0.17264695465564728, - -0.4442422091960907, - 0.2926892936229706 - ] + [-0.5295901894569397, -0.6448984146118164, -0.369537353515625, -0.47141557931900024, 1.2438589334487915], + [-1.7002424001693726, -1.2208786010742188, -1.3158544301986694, -1.8084080219268799, -0.4799889922142029], + [0.7350953221321106, -0.269319087266922, 0.8924283385276794, 1.3709611892700195, 0.7821508049964905], + [-0.30908405780792236, 0.6509400010108948, -1.5479099750518799, -1.2930028438568115, 0.8795658946037292] + ] + ], + "expected_output": [ + [-3.3983283042907715, 1.3685628175735474, -0.11334192752838135, -4.658087253570557, 2.560546875], + [0.5191166400909424, 0.43040943145751953, 0.847689151763916, -0.48246490955352783, 0.21922549605369568], + [-1.8038214445114136, -1.4841561317443848, -2.3408734798431396, -2.2018651962280273, 2.425586700439453] + ], + "expected_grad": [ + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ], + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ], + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ] + ] + }, + { + "test_name": "sum_dim_1_keepdim_True", + "op_name": "sum", + "dim": 1, + "keepdim": true, + "input": [ + [ + [-0.03328368067741394, -0.1935928761959076, -0.7671046257019043, 1.041800618171692, -0.5939895510673523], + [-0.9907869696617126, -0.9927570819854736, -0.2557562291622162, -0.22515931725502014, 0.7214905023574829], + [0.12578019499778748, 1.4050774574279785, 0.19477412104606628, -0.4741835296154022, 0.1276102066040039], + [0.6101059317588806, -0.3841469883918762, -0.921748697757721, -0.4872817397117615, -0.5074361562728882] + ], + [ + [0.5522661805152893, 0.061027202755212784, -0.9556332230567932, -0.7779799103736877, 1.3941880464553833], + [-0.2754690647125244, -0.5164039731025696, 0.1548738032579422, -0.8348855972290039, 0.22885975241661072], + [-2.0042972564697266, 0.005512263625860214, -0.3478994369506836, 0.5377600193023682, -0.9290909767150879], + [1.1321873664855957, -0.7327660322189331, 1.1509846448898315, -0.6960206627845764, 0.5155009627342224] + ], + [ + [0.27344995737075806, 0.6651293039321899, 1.0537790060043335, 0.7269541621208191, -0.4144572615623474], + [-0.7832543253898621, 1.1300108432769775, -1.612937569618225, 0.445094496011734, 0.051411572843790054], + [-0.35013654828071594, -1.006677508354187, -0.534939169883728, 0.9171100854873657, -1.031330943107605], + [-0.3431452810764313, -0.5040718913078308, 0.07251296937465668, -1.078025221824646, -0.39548805356025696] ] ], "expected_output": [ [ - 1.1716068983078003, - 1.0511995553970337, - 0.9755558371543884, - 0.5409456491470337, - 1.28053879737854 + [-0.2881844639778137, -0.16541951894760132, -1.74983549118042, -0.14482393860816956, -0.25232499837875366] ], [ - 1.2130928039550781, - 1.8218294382095337, - 1.5863804817199707, - 0.884564220905304, - 0.12699493765830994 + [-0.5953128337860107, -1.1826305389404297, 0.002325773239135742, -1.7711260318756104, 1.2094578742980957] ], [ - 1.2572640180587769, - 0.22709836065769196, - -0.17264695465564728, - 0.9846003651618958, - 1.3074569702148438 + [-1.2030861377716064, 0.28439074754714966, -1.0215847492218018, 1.0111335515975952, -1.7898646593093872] ] ], "expected_grad": [ [ - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 1.0, - 0.0, - 0.0, - 1.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 0.0, - 1.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ] ] }, { - "test_name": "max_dim_1_keepdim_True", - "op_name": "max", - "dim": 1, + "test_name": "sum_dim_-1_keepdim_False", + "op_name": "sum", + "dim": -1, + "keepdim": false, + "input": [ + [ + [-0.16857317090034485, 0.688886284828186, 0.09771557152271271, 1.052785038948059, -1.1113090515136719], + [-0.9389597773551941, -1.3075956106185913, 0.9676118493080139, -0.7394251227378845, -1.5103271007537842], + [0.08060058951377869, -1.8929684162139893, 0.5650917887687683, 0.8412631750106812, -0.9580911993980408], + [-0.7895215749740601, 0.015372429974377155, -0.027610722929239273, -0.053718894720077515, -0.7734133005142212] + ], + [ + [-1.3837915658950806, 0.97823166847229, 1.2639201879501343, -2.0509865283966064, 0.7195857763290405], + [0.5959717631340027, -1.8225737810134888, -0.1343626081943512, 0.49848124384880066, 0.3930509090423584], + [-0.6577728390693665, 0.24517367780208588, 0.20588766038417816, -0.8329556584358215, -0.820264458656311], + [-0.8202312588691711, 0.9118992686271667, -1.6226643323898315, 0.6528452634811401, 0.474252313375473] + ], + [ + [-1.0028913021087646, 0.06786083430051804, 0.5943557024002075, -1.4299345016479492, -1.8149548768997192], + [-0.48883718252182007, 0.3190588653087616, 0.8207234740257263, 0.26855215430259705, 0.5349103808403015], + [0.2828715443611145, 0.2559785544872284, -0.3839770257472992, 0.9996393918991089, -0.411981463432312], + [1.7920981645584106, -0.7672699093818665, -1.307977557182312, -1.7257500886917114, -0.03232753649353981] + ] + ], + "expected_output": [ + [0.5595046877861023, -3.528696060180664, -1.364104151725769, -1.628892183303833], + [-0.47304046154022217, -0.4694325029850006, -1.8599317073822021, -0.4038987159729004], + [-3.585564136505127, 1.4544076919555664, 0.7425310015678406, -2.041226863861084] + ], + "expected_grad": [ + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ], + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ], + [ + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] + ] + ] + }, + { + "test_name": "sum_dim_-1_keepdim_True", + "op_name": "sum", + "dim": -1, "keepdim": true, "input": [ [ - [ - 0.05868193879723549, - 1.5382329225540161, - 1.0444575548171997, - -0.26301294565200806, - 0.2191448211669922 - ], - [ - 0.05122251436114311, - -0.6351413130760193, - -0.9322060346603394, - -0.2185828685760498, - 0.4121098220348358 - ], - [ - -1.132474660873413, - -2.3891191482543945, - 0.7177993655204773, - -1.5831094980239868, - 0.6412859559059143 - ], - [ - -0.2708216905593872, - -0.6109879612922668, - 0.11032737791538239, - 0.12355764210224152, - -1.4388847351074219 - ] + [1.3067461252212524, 0.1913401335477829, 1.3767470121383667, 0.6892044544219971, 0.43921586871147156], + [-0.04813985526561737, -0.3315163552761078, -0.23632389307022095, -0.08464081585407257, -0.2434539496898651], + [-1.4118940830230713, -1.0503880977630615, 1.110618233680725, 0.21369199454784393, 0.9332243204116821], + [0.7342482805252075, -1.1814165115356445, -0.9001671671867371, 2.1022186279296875, 0.13313262164592743] ], [ - [ - -0.45935776829719543, - 0.719353199005127, - -1.2023998498916626, - -0.5769718289375305, - 0.7339244484901428 - ], - [ - 0.0939386859536171, - 1.0834808349609375, - 0.8089823126792908, - -0.9773237109184265, - -0.26083904504776 - ], - [ - -0.07018473744392395, - -1.206803798675537, - 1.5053801536560059, - -0.0004540873342193663, - -0.8399935364723206 - ], - [ - -0.9963456988334656, - 1.9695827960968018, - -0.6241140961647034, - -0.11510364711284637, - 1.3116685152053833 - ] + [0.022425031289458275, -0.2799490988254547, -0.13277991116046906, -1.1816505193710327, -1.7333787679672241], + [1.1858826875686646, 0.4465799629688263, 1.1301037073135376, -0.3333589434623718, 0.8935588598251343], + [-1.948160171508789, -1.366417646408081, 0.009384111501276493, 0.6304294466972351, 0.8632985949516296], + [1.1419644355773926, 0.3109254240989685, -0.10642467439174652, -1.2388849258422852, -1.1811842918395996] ], [ - [ - 0.9128003120422363, - -0.8139405250549316, - -0.32805025577545166, - -1.6033560037612915, - -0.6016383171081543 - ], - [ - -0.3473812937736511, - -0.9625334739685059, - 0.9539335370063782, - -1.4123497009277344, - 0.812851071357727 - ], - [ - 1.4345933198928833, - 0.05774686485528946, - 0.8243234157562256, - 0.3210548460483551, - -0.6046251654624939 - ], - [ - -0.6875012516975403, - 0.20559696853160858, - -0.7192203998565674, - -1.1452873945236206, - 0.888896107673645 - ] + [0.8579769134521484, -1.6933249235153198, 0.28935855627059937, 0.12979160249233246, 0.9177106618881226], + [-0.08528606593608856, 0.646186888217926, 0.9474418759346008, -0.9643430113792419, -0.05544678866863251], + [0.6487414836883545, -1.5244767665863037, 0.7500134110450745, -2.1544389724731445, 1.4023377895355225], + [0.38867735862731934, 0.7254555821418762, -1.389511227607727, -0.8552696704864502, -1.5335310697555542] ] ], "expected_output": [ [ - [ - 0.05868193879723549, - 1.5382329225540161, - 1.0444575548171997, - 0.12355764210224152, - 0.6412859559059143 - ] + [4.003253936767578], + [-0.9440748691558838], + [-0.20474763214588165], + [0.888015866279602] ], [ - [ - 0.0939386859536171, - 1.9695827960968018, - 1.5053801536560059, - -0.0004540873342193663, - 1.3116685152053833 - ] + [-3.305333137512207], + [3.322766065597534], + [-1.8114655017852783], + [-1.0736039876937866] ], [ - [ - 1.4345933198928833, - 0.20559696853160858, - 0.9539335370063782, - 0.3210548460483551, - 0.888896107673645 - ] + [0.5015128254890442], + [0.48855286836624146], + [-0.8778231143951416], + [-2.6641790866851807] ] ], "expected_grad": [ [ - [ - 1.0, - 1.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ], [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 1.0 - ] + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0, 1.0] ] ] }, { - "test_name": "max_dim_-1_keepdim_False", - "op_name": "max", - "dim": -1, + "test_name": "mean_dim_None_keepdim_False", + "op_name": "mean", + "dim": null, "keepdim": false, "input": [ [ - [ - 1.102234125137329, - 0.1452106386423111, - -1.0025994777679443, - -0.8691359758377075, - 1.034902811050415 - ], - [ - 1.141363263130188, - -0.6113547086715698, - 0.5669911503791809, - 0.08074041455984116, - 0.769339919090271 - ], - [ - -1.206941843032837, - -0.1684180051088333, - -1.0213230848312378, - 0.45474377274513245, - 0.05628223717212677 - ], - [ - 0.1908469796180725, - 1.134475827217102, - -0.6270834803581238, - -0.2348310351371765, - 0.1834784746170044 - ] + [-1.1046700477600098, 0.3997063636779785, -0.7377328872680664, 0.8807763457298279, -0.7662639021873474], + [1.4585676193237305, 1.7723872661590576, 0.32965973019599915, -0.014356887899339199, 1.0570905208587646], + [0.40178006887435913, 0.6623095273971558, -0.8157885074615479, 1.7509973049163818, -0.07119281589984894], + [-0.3190559148788452, 0.050714727491140366, 0.019659370183944702, -0.06124546006321907, -0.9422666430473328] ], [ - [ - 0.8270988464355469, - 0.6817458271980286, - 0.40630635619163513, - 1.706158995628357, - -0.3331676423549652 - ], - [ - 1.3781265020370483, - 0.22484587132930756, - -2.3762154579162598, - 0.4015538990497589, - -2.294616460800171 - ], - [ - 0.9543997049331665, - -0.3883368968963623, - -0.6146398186683655, - -0.4274226725101471, - -1.4890133142471313 - ], - [ - 0.5850116610527039, - -0.6405912041664124, - -1.9063634872436523, - -0.21498170495033264, - 0.1672649085521698 - ] + [1.4318883419036865, 0.13153165578842163, -0.18222470581531525, 0.3660371005535126, 0.5798347592353821], + [0.2429470419883728, -1.2091906070709229, 0.07767737656831741, 0.17619068920612335, 0.578863799571991], + [1.5511679649353027, 0.08444352447986603, 1.2101210355758667, -0.8561125993728638, -0.01396828331053257], + [-0.2777872681617737, -0.7856798768043518, 0.46062397956848145, 0.566218376159668, 1.1541569232940674] ], [ - [ - -0.02165069803595543, - 0.7171346545219421, - -1.3825470209121704, - 0.5667335987091064, - 0.1853654533624649 - ], - [ - 1.7064272165298462, - 2.270893096923828, - 0.6268392205238342, - 1.6014127731323242, - 1.196624517440796 - ], - [ - 0.07062987983226776, - -0.06806328892707825, - -0.8778694272041321, - -0.666265070438385, - 0.34564408659935 - ], - [ - -0.1972421109676361, - -1.5218473672866821, - -0.06109791249036789, - -0.49620160460472107, - 1.5591261386871338 - ] + [-0.4426518380641937, 1.2387607097625732, -1.0242971181869507, 0.7994512319564819, 0.2551962435245514], + [-1.102837324142456, 0.8238721489906311, 0.0035749999806284904, -1.7263970375061035, 0.23050972819328308], + [-0.006388451438397169, -0.3764995038509369, -0.12150754034519196, 0.41562098264694214, 1.0095174312591553], + [0.6818063259124756, -0.7300068736076355, -0.8303658366203308, -0.9434769749641418, 2.028413772583008] ] ], - "expected_output": [ + "expected_output": 0.15700183808803558, + "expected_grad": [ + [ + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107] + ], + [ + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107] + ], [ - 1.102234125137329, - 1.141363263130188, - 0.45474377274513245, - 1.134475827217102 + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107], + [0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107, 0.01666666753590107] + ] + ] + }, + { + "test_name": "mean_dim_0_keepdim_False", + "op_name": "mean", + "dim": 0, + "keepdim": false, + "input": [ + [ + [0.1755259782075882, 0.29882222414016724, -0.6017733812332153, 1.1090705394744873, -0.26971787214279175], + [-0.4379420578479767, -1.0124340057373047, -0.14667245745658875, 0.15679313242435455, 0.19906163215637207], + [0.6868006587028503, -0.4260328412055969, -0.7560138702392578, 0.17112013697624207, -0.7641999125480652], + [-0.44291654229164124, 1.180337905883789, 0.37527406215667725, 0.16405928134918213, -0.5820143818855286] ], [ - 1.706158995628357, - 1.3781265020370483, - 0.9543997049331665, - 0.5850116610527039 + [-0.6077602505683899, -0.20455589890480042, 0.5790372490882874, -0.19989891350269318, -0.06916097551584244], + [-0.2501976788043976, -0.631926953792572, -0.10361812263727188, 0.9832454323768616, -0.21117885410785675], + [0.8466978073120117, 0.8503185510635376, -1.003414511680603, -0.9655314683914185, 0.21109014749526978], + [-1.413875699043274, 0.8920503854751587, -0.30397742986679077, -0.05114508792757988, -0.6013848185539246] ], [ - 0.7171346545219421, - 2.270893096923828, - 0.34564408659935, - 1.5591261386871338 + [0.11547855287790298, -0.17881472408771515, -0.09405016899108887, -0.6329993009567261, -1.0465848445892334], + [1.3759163618087769, 0.05762922391295433, 0.35209375619888306, 1.0967378616333008, -0.9882838726043701], + [1.9996482133865356, -1.2997536659240723, -0.7523331046104431, -0.47686854004859924, 1.2204824686050415], + [-0.15345095098018646, -0.5119454264640808, 0.11924147605895996, 1.428880214691162, 2.0869503021240234] ] ], + "expected_output": [ + [-0.1055852472782135, -0.028182798996567726, -0.038928765803575516, 0.09205744415521622, -0.46182122826576233], + [0.22925888001918793, -0.5289105772972107, 0.033934395760297775, 0.7455921173095703, -0.333467036485672], + [1.1777156591415405, -0.2918226420879364, -0.8372538089752197, -0.42375993728637695, 0.22245757281780243], + [-0.6700810790061951, 0.5201475620269775, 0.06351270526647568, 0.5139314532279968, 0.30118370056152344] + ], "expected_grad": [ [ - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ] + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408] ], [ - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408] ], [ - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408] ] ] }, { - "test_name": "max_dim_-1_keepdim_True", - "op_name": "max", - "dim": -1, + "test_name": "mean_dim_0_keepdim_True", + "op_name": "mean", + "dim": 0, "keepdim": true, "input": [ [ - [ - 0.08976225554943085, - -2.1487770080566406, - -0.26685312390327454, - 0.06450489908456802, - -1.4932622909545898 - ], - [ - 1.6294554471969604, - -1.738688588142395, - 1.7332375049591064, - 2.0544910430908203, - 1.293807029724121 - ], - [ - 0.8169977068901062, - -1.0389111042022705, - -1.4858906269073486, - 1.4143908023834229, - 0.7241055965423584 - ], - [ - 1.134980320930481, - -0.2217475324869156, - 2.139716625213623, - 0.19970077276229858, - 0.8841625452041626 - ] + [0.9313072562217712, 0.11275313794612885, -0.29632923007011414, 0.6281623244285583, 0.797209620475769], + [0.6957338452339172, -0.18519674241542816, 0.19908924400806427, 0.21209175884723663, 1.1861251592636108], + [-0.08824097365140915, -1.1839087009429932, -0.23501551151275635, 0.6680712103843689, -0.7205530405044556], + [0.9816026091575623, -0.15770527720451355, 0.5783246755599976, 0.5183308720588684, 0.10639314353466034] ], [ - [ - 0.949975848197937, - -0.10251139849424362, - 0.9830695986747742, - -1.6503483057022095, - 0.10293407738208771 - ], - [ - -1.2885284423828125, - -0.7290129065513611, - -1.3367583751678467, - 0.28592362999916077, - 1.0034847259521484 - ], - [ - 0.6469754576683044, - 1.3000932931900024, - -0.634432315826416, - 0.09809456765651703, - -2.255279064178467 - ], - [ - -1.0050581693649292, - 0.27072352170944214, - 0.2964065372943878, - -0.010661646723747253, - 0.32635602355003357 - ] + [-0.0708099901676178, 0.1868356168270111, -1.135615348815918, -0.6121562123298645, 0.4646506905555725], + [0.9826740026473999, 0.4591689705848694, 0.3639809787273407, 0.24808230996131897, -0.5714194178581238], + [-1.8829892873764038, 1.6257703304290771, 1.1227099895477295, -0.24534782767295837, 0.42072793841362], + [1.2927830219268799, -0.062042392790317535, -0.07447009533643723, 1.8144526481628418, 0.4126001298427582] ], [ - [ - -0.779302179813385, - 1.35313880443573, - 0.9089425206184387, - -1.2521377801895142, - -0.1434730738401413 - ], - [ - 0.10889503359794617, - 0.09379234164953232, - -0.7034569978713989, - -0.17944560945034027, - 0.45458918809890747 - ], - [ - -0.26298829913139343, - 0.39442673325538635, - 0.3479395806789398, - -1.4978502988815308, - 0.7075753211975098 - ], - [ - 0.693645179271698, - -0.07173124700784683, - -0.2537860572338104, - 0.2973843812942505, - -1.541783332824707 - ] + [1.5678290128707886, -0.5997704267501831, 0.13211850821971893, -0.4554636776447296, -0.32575365900993347], + [2.110002040863037, -0.5582384467124939, 0.3878994286060333, -2.2768142223358154, 0.37306782603263855], + [-0.9947562217712402, -1.3262041807174683, -0.599851667881012, 0.17797666788101196, -1.143309235572815], + [1.3394620418548584, -0.996752142906189, -0.6021904945373535, 0.32188680768013, 0.1322384774684906] ] ], "expected_output": [ [ - [ - 0.08976225554943085 - ], - [ - 2.0544910430908203 - ], - [ - 1.4143908023834229 - ], - [ - 2.139716625213623 - ] - ], - [ - [ - 0.9830695986747742 - ], - [ - 1.0034847259521484 - ], - [ - 1.3000932931900024 - ], - [ - 0.32635602355003357 - ] - ], - [ - [ - 1.35313880443573 - ], - [ - 0.45458918809890747 - ], - [ - 0.7075753211975098 - ], - [ - 0.693645179271698 - ] + [0.8094420433044434, -0.10006055980920792, -0.43327537178993225, -0.1464858502149582, 0.31203556060791016], + [1.262803316116333, -0.09475541114807129, 0.3169898986816406, -0.6055467128753662, 0.3292578458786011], + [-0.9886621832847595, -0.2947808504104614, 0.09594760090112686, 0.2002333402633667, -0.4810447692871094], + [1.2046159505844116, -0.4054999351501465, -0.03277863934636116, 0.884890079498291, 0.21707725524902344] ] ], "expected_grad": [ [ - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ] + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408] ], [ - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408] ], [ - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408], + [0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408] ] ] }, { - "test_name": "min_dim_None_keepdim_False", - "op_name": "min", - "dim": null, + "test_name": "mean_dim_1_keepdim_False", + "op_name": "mean", + "dim": 1, "keepdim": false, "input": [ [ - [ - -1.4054443836212158, - 0.007234930992126465, - 0.5773534178733826, - 0.30951234698295593, - -0.8588898777961731 - ], - [ - 0.526231050491333, - -0.06828558444976807, - 1.2680625915527344, - 0.23789522051811218, - -1.805619716644287 - ], - [ - 1.746630311012268, - -1.526967167854309, - 0.3485613167285919, - 0.7839732766151428, - 1.5388095378875732 - ], - [ - 1.1633633375167847, - 0.8717845678329468, - 0.21581949293613434, - 0.1374770998954773, - -1.1221222877502441 - ] + [0.27381452918052673, 1.7188366651535034, 1.3450311422348022, -1.2653104066848755, 0.45117413997650146], + [0.6597211360931396, -2.012479305267334, -0.516261100769043, -1.0803741216659546, 1.424518346786499], + [-1.1213253736495972, 0.3918372392654419, -0.49036842584609985, -0.2890629470348358, -0.7217605710029602], + [1.9135220050811768, 1.668276309967041, 0.674127995967865, 1.1708104610443115, 0.02161409705877304] ], [ - [ - 0.1467854380607605, - -0.17452457547187805, - -0.7465326189994812, - -1.163095235824585, - -1.0377240180969238 - ], - [ - 0.6390634179115295, - -0.929384708404541, - 0.07479915767908096, - 0.641934871673584, - 1.1865335702896118 - ], - [ - -0.7681276798248291, - -0.8917787075042725, - 0.19665859639644623, - 0.6306189298629761, - 1.6684050559997559 - ], - [ - 1.258668065071106, - 0.16344283521175385, - 0.8060418367385864, - -0.6885544061660767, - -0.23013491928577423 - ] + [-0.9156265258789062, 0.21846671402454376, -0.5406830906867981, -0.8299271464347839, 2.0619850158691406], + [0.3048802316188812, -1.4610782861709595, -0.20266015827655792, 0.03146770969033241, 0.2910449504852295], + [0.5939645171165466, 1.3427438735961914, -0.6950612664222717, 0.8987486362457275, -0.763476550579071], + [-0.19663105905056, -0.3633078634738922, -1.5530608892440796, -0.15105754137039185, -0.5337246656417847] ], [ - [ - 1.1331552267074585, - 0.42492198944091797, - -0.07918443530797958, - 0.3510800898075104, - 0.45417457818984985 - ], - [ - 0.3879549503326416, - -0.6664285659790039, - -0.5420844554901123, - 2.9302103519439697, - 0.03980718180537224 - ], - [ - -1.2734509706497192, - 1.154341697692871, - 0.7456277012825012, - -0.46407395601272583, - 0.354059636592865 - ], - [ - 0.5733898282051086, - -1.9253568649291992, - 1.3460670709609985, - -0.9440423846244812, - 0.5850473642349243 - ] + [1.6809849739074707, -0.11213088780641556, -0.5451535582542419, 0.5253366231918335, 0.5843788981437683], + [-2.286334276199341, 0.5851041674613953, 1.2774115800857544, 0.8801257610321045, 0.5200220942497253], + [-1.0255969762802124, 1.7627143859863281, -0.0564274862408638, 0.9568160176277161, -0.6867133378982544], + [1.02428138256073, 1.7308460474014282, -0.32468941807746887, 0.3143851161003113, -0.0669134333729744] ] ], - "expected_output": -1.9253568649291992, + "expected_output": [ + [0.4314330816268921, 0.4416177272796631, 0.2531324028968811, -0.3659842610359192, 0.2938864827156067], + [-0.053353201597929, -0.06579387933015823, -0.7478663921356201, -0.012692078948020935, 0.2639571726322174], + [-0.15166622400283813, 0.991633415222168, 0.0877852812409401, 0.6691659092903137, 0.08769355714321136] + ], "expected_grad": [ - [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [ + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25] ], [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25] ], [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ] + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25] ] ] }, { - "test_name": "min_dim_0_keepdim_False", - "op_name": "min", - "dim": 0, - "keepdim": false, + "test_name": "mean_dim_1_keepdim_True", + "op_name": "mean", + "dim": 1, + "keepdim": true, "input": [ [ - [ - -0.7561046481132507, - -0.6087163090705872, - 0.06523545831441879, - 0.2073671668767929, - -0.4843977093696594 - ], - [ - -0.4931473731994629, - 0.695488691329956, - 1.5209262371063232, - -1.5004045963287354, - 1.424126148223877 - ], - [ - 0.4264316260814667, - 1.725341796875, - -1.1767886877059937, - -0.5571966767311096, - 2.1753745079040527 - ], - [ - -0.4421183466911316, - -1.742424488067627, - -0.7672881484031677, - 1.4304224252700806, - 0.39234694838523865 - ] + [0.8160833120346069, -0.8233374357223511, -2.1418421268463135, 0.7724379897117615, -0.6358500719070435], + [0.2520127594470978, 0.9832903742790222, 0.27252840995788574, -0.9334322810173035, -0.120673269033432], + [-1.6670103073120117, -2.2226719856262207, -1.0847980976104736, 0.612401008605957, -0.5785004496574402], + [-0.725740909576416, 0.42209234833717346, -1.268004298210144, 1.395574688911438, -0.4016047418117523] ], [ - [ - -1.3970006704330444, - -2.0020906925201416, - -0.26867592334747314, - -0.701147735118866, - 0.31265851855278015 - ], - [ - -0.3883015811443329, - 0.8928799033164978, - 0.7249560952186584, - 0.4335167407989502, - 0.9744104146957397 - ], - [ - -0.21621425449848175, - -0.29577603936195374, - -0.2591007351875305, - 0.7960927486419678, - 0.5791953802108765 - ], - [ - -0.13450507819652557, - -1.3556065559387207, - -0.394126832485199, - -0.7559952735900879, - 0.5876944661140442 - ] + [-0.47602152824401855, 0.6024074554443359, -0.13895398378372192, -0.5199072957038879, -0.49655959010124207], + [1.612599492073059, -0.3255579173564911, 0.9303890466690063, -0.2840443551540375, 0.8463886380195618], + [0.018565375357866287, -1.6755516529083252, -1.5852235555648804, 1.1069889068603516, -0.6744462847709656], + [-1.8892930746078491, -1.842443585395813, 0.13227719068527222, -0.792870283126831, 1.2297093868255615] ], [ - [ - -1.3335460424423218, - 0.9432480931282043, - -1.1379897594451904, - -1.1207023859024048, - -0.6139907240867615 - ], - [ - 0.9939887523651123, - 0.5297332406044006, - -0.3778044879436493, - 1.417391061782837, - 0.4910713732242584 - ], - [ - 0.9159647822380066, - 0.1735081523656845, - -1.438053846359253, - 0.6212812662124634, - -1.969196081161499 - ], - [ - -0.2445336878299713, - -0.6776713728904724, - 0.47822806239128113, - -1.8905819654464722, - 0.2990115284919739 - ] + [-0.013317405246198177, -0.30806609988212585, -0.3388381898403168, -0.46696820855140686, 0.14354214072227478], + [-0.9078568816184998, 2.190314531326294, 0.2566744089126587, 0.4625372588634491, -1.1410428285598755], + [1.7502615451812744, -0.11171314865350723, -1.1738200187683105, -0.6320435404777527, -1.0962568521499634], + [-0.7847272753715515, -0.5752313137054443, 0.5138634443283081, 1.050782322883606, 1.3841030597686768] ] ], "expected_output": [ [ - -1.3970006704330444, - -2.0020906925201416, - -1.1379897594451904, - -1.1207023859024048, - -0.6139907240867615 + [-0.33116379380226135, -0.4101566970348358, -1.055528998374939, 0.46174535155296326, -0.4341571629047394] + ], + [ + [-0.18353742361068726, -0.8102864027023315, -0.16537782549858093, -0.12245824933052063, 0.22627303004264832] + ], + [ + [0.011089995503425598, 0.2988259792327881, -0.18553009629249573, 0.10357695817947388, -0.17741364240646362] + ] + ], + "expected_grad": [ + [ + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25] + ], + [ + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25] ], [ - -0.4931473731994629, - 0.5297332406044006, - -0.3778044879436493, - -1.5004045963287354, - 0.4910713732242584 + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25], + [0.25, 0.25, 0.25, 0.25, 0.25] + ] + ] + }, + { + "test_name": "mean_dim_-1_keepdim_False", + "op_name": "mean", + "dim": -1, + "keepdim": false, + "input": [ + [ + [1.459913969039917, -1.9324012994766235, 0.295070618391037, 1.953094482421875, 0.062261566519737244], + [-1.1078839302062988, 0.976121723651886, -0.07730520516633987, -0.29665258526802063, -0.26533499360084534], + [-0.79975426197052, 1.0418704748153687, 1.3010565042495728, -0.40846967697143555, -0.7162472605705261], + [-1.0271012783050537, 0.1834021359682083, -0.05814415216445923, 0.3220038414001465, 0.4668942093849182] ], [ - -0.21621425449848175, - -0.29577603936195374, - -1.438053846359253, - -0.5571966767311096, - -1.969196081161499 + [0.014412929303944111, -1.1832906007766724, 0.03632983937859535, 2.4672696590423584, 1.3323793411254883], + [-0.09307997673749924, -1.1491583585739136, 0.39312395453453064, -0.3892734944820404, 0.5293436646461487], + [-0.6360014081001282, -0.2509534955024719, 0.4555503726005554, -0.27460846304893494, 0.9494737386703491], + [-0.8720837235450745, 0.8029743432998657, 0.27744394540786743, 0.33585336804389954, -0.7603669166564941] ], [ - -0.4421183466911316, - -1.742424488067627, - -0.7672881484031677, - -1.8905819654464722, - 0.2990115284919739 + [-0.6846820712089539, -0.7688948512077332, 1.9104690551757812, -0.9281872510910034, -0.49309614300727844], + [0.50408536195755, 0.998515248298645, 0.0367455929517746, 0.2297750562429428, -1.984581470489502], + [-1.2512000799179077, 0.6219334602355957, 0.051693860441446304, -0.5315346121788025, 0.5726004242897034], + [0.3863498866558075, 0.27223649621009827, 0.46132177114486694, 0.13579803705215454, 0.516796886920929] ] ], + "expected_output": [ + [0.3675878643989563, -0.15421099960803986, 0.08369116485118866, -0.022589052096009254], + [0.533420205116272, -0.14180883765220642, 0.04869214817881584, -0.04323578625917435], + [-0.19287827610969543, -0.04309204965829849, -0.10730139166116714, 0.35450059175491333] + ], "expected_grad": [ [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 1.0, - 1.0, - 0.0, - 0.0 - ] + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224] ], [ - [ - 1.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224] ], [ - [ - 0.0, - 0.0, - 1.0, - 1.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 1.0 - ] + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224] ] ] }, { - "test_name": "min_dim_0_keepdim_True", - "op_name": "min", - "dim": 0, + "test_name": "mean_dim_-1_keepdim_True", + "op_name": "mean", + "dim": -1, "keepdim": true, "input": [ [ - [ - 0.4874853193759918, - -1.5288264751434326, - 0.3616181015968323, - 0.4444722533226013, - 0.37175261974334717 - ], - [ - 0.17289385199546814, - -1.2141680717468262, - 1.9441745281219482, - -0.5341972708702087, - -0.07878366857767105 - ], - [ - 0.9717959761619568, - 0.15757296979427338, - -0.1293685883283615, - 0.9459248185157776, - 0.7486283779144287 - ], - [ - 1.3489890098571777, - -0.11803387850522995, - 0.8932477235794067, - 0.8591998815536499, - 1.068840742111206 - ] + [1.0863715410232544, -0.48916497826576233, 1.751997470855713, -0.3743889033794403, 0.9508031606674194], + [1.3071852922439575, -0.7512642741203308, 0.005139758810400963, 1.6046744585037231, 0.08605138957500458], + [1.9344228506088257, -0.44564706087112427, -0.47476428747177124, -0.30261677503585815, -0.29394063353538513], + [2.5355067253112793, 1.848445177078247, -1.1966158151626587, -0.4228180944919586, -0.7322655916213989] ], [ - [ - 1.035352349281311, - -1.0888819694519043, - -0.9833644032478333, - 0.18595486879348755, - -0.5669856071472168 - ], - [ - -1.0098682641983032, - -0.4541301131248474, - 0.6979333758354187, - 0.546902596950531, - 0.5524624586105347 - ], - [ - 0.2402925342321396, - -1.1295276880264282, - 2.641334295272827, - -0.42235150933265686, - 0.3279983699321747 - ], - [ - -0.22356857359409332, - 0.6338478326797485, - 1.2712687253952026, - 0.5257611274719238, - -0.08859143406152725 - ] + [-0.3979387581348419, -0.004983691032975912, -2.165992498397827, 0.5304996371269226, 2.260444164276123], + [-0.3309515118598938, 1.8614799976348877, -0.11587686836719513, -0.6822512745857239, 0.4212978780269623], + [-1.3226412534713745, 1.2114580869674683, -0.8475749492645264, -0.09313177317380905, -1.2082672119140625], + [3.168529987335205, 2.297508955001831, -0.14129851758480072, -1.9953597784042358, 0.035315316170454025] ], [ - [ - 0.2868587076663971, - 1.34219491481781, - -0.4532349705696106, - 1.0591752529144287, - -0.007002960424870253 - ], - [ - 1.0370234251022339, - 0.12661591172218323, - 0.9138452410697937, - 0.15242700278759003, - -1.77699875831604 - ], - [ - -0.2700897455215454, - 1.132546067237854, - -0.4591978192329407, - 0.7583627104759216, - -0.25366878509521484 - ], - [ - -0.6026967763900757, - 0.41119346022605896, - -0.4785611629486084, - -0.3798253536224365, - -0.6784350275993347 - ] + [-1.0469098091125488, -0.16152557730674744, -0.5230178833007812, -1.1935372352600098, 1.8063979148864746], + [0.9378061294555664, -0.38452786207199097, 0.658501386642456, 0.7616772055625916, -0.6450856328010559], + [1.6012887954711914, 0.35755881667137146, 0.26440107822418213, -0.5598823428153992, 1.4536970853805542], + [-0.2962888479232788, -0.4702155888080597, -1.499106526374817, -0.01866411603987217, -1.5055760145187378] ] ], "expected_output": [ [ - [ - 0.2868587076663971, - -1.5288264751434326, - -0.9833644032478333, - 0.18595486879348755, - -0.5669856071472168 - ], - [ - -1.0098682641983032, - -1.2141680717468262, - 0.6979333758354187, - -0.5341972708702087, - -1.77699875831604 - ], - [ - -0.2700897455215454, - -1.1295276880264282, - -0.4591978192329407, - -0.42235150933265686, - -0.25366878509521484 - ], - [ - -0.6026967763900757, - -0.11803387850522995, - -0.4785611629486084, - -0.3798253536224365, - -0.6784350275993347 - ] + [0.5851236581802368], + [0.4503573477268219], + [0.08349082618951797], + [0.40645045042037964] + ], + [ + [0.04440578073263168], + [0.23073963820934296], + [-0.4520314633846283], + [0.6729391813278198] + ], + [ + [-0.223718523979187], + [0.26567426323890686], + [0.6234126687049866], + [-0.7579702138900757] ] ], "expected_grad": [ [ - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ] + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224] ], [ - [ - 0.0, - 0.0, - 1.0, - 1.0, - 1.0 - ], - [ - 1.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224] ], [ - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 1.0, - 0.0, - 1.0, - 0.0, - 1.0 - ], - [ - 1.0, - 0.0, - 1.0, - 1.0, - 1.0 - ] + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224], + [0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224, 0.20000000298023224] ] ] }, { - "test_name": "min_dim_1_keepdim_False", - "op_name": "min", - "dim": 1, + "test_name": "max_dim_None_keepdim_False", + "op_name": "max", + "dim": null, "keepdim": false, "input": [ [ - [ - 1.1780027151107788, - 0.3302285671234131, - 0.3409285247325897, - 0.0966181680560112, - 0.8048174381256104 - ], - [ - -0.9308503866195679, - -0.7495615482330322, - -1.1345824003219604, - 1.743110179901123, - 0.24290774762630463 - ], - [ - 0.2789574861526489, - 0.3315619230270386, - -0.05199375003576279, - -0.38996851444244385, - 0.45961233973503113 - ], - [ - 1.5001028776168823, - 0.4969956576824188, - 0.8539602756500244, - -1.2495394945144653, - -1.8244128227233887 - ] + [1.3179066181182861, 0.7556464672088623, 1.2471561431884766, 0.7881364822387695, 1.5493229627609253], + [-0.6088662147521973, 1.4112409353256226, -0.9075624346733093, 1.1897660493850708, -0.4802001118659973], + [2.2536263465881348, 1.1717573404312134, 0.8793008327484131, -0.7796709537506104, 1.4039242267608643], + [2.2192718982696533, 0.36377331614494324, 1.2563191652297974, -0.1220834031701088, 0.10120877623558044] ], [ - [ - 1.9353760480880737, - 0.32966846227645874, - -0.5037038922309875, - 0.5824847221374512, - -0.04406149685382843 - ], - [ - 0.26977765560150146, - -1.149574875831604, - 0.5576037764549255, - -0.4423902630805969, - -1.1938692331314087 - ], - [ - 0.5121238231658936, - 0.3450745940208435, - 1.2737618684768677, - -0.5269590616226196, - 0.36447712779045105 - ], - [ - -1.3918713331222534, - -0.13599461317062378, - 0.5021628141403198, - 0.3100223243236542, - 0.08071848005056381 - ] + [0.47121289372444153, 0.6840168237686157, -0.7728962898254395, -0.3962509334087372, 0.6629142165184021], + [0.6556671857833862, 0.058465536683797836, 0.7882350087165833, -1.0857888460159302, 1.0519514083862305], + [0.2087085098028183, -1.4547972679138184, -0.17086558043956757, -2.0883853435516357, 0.7963455319404602], + [0.4962165355682373, 0.6029451489448547, -0.5226418375968933, 0.06845283508300781, 0.3298587203025818] ], [ - [ - 0.2132561206817627, - -0.21911364793777466, - 1.0261167287826538, - -0.15927140414714813, - 0.12461294233798981 - ], - [ - 1.5179888010025024, - 0.2487545758485794, - -0.9334361553192139, - 1.019239902496338, - 0.0731339082121849 - ], - [ - -0.531711220741272, - -0.03542341664433479, - -0.5915296077728271, - -0.014602077193558216, - 0.2609618306159973 - ], - [ - 0.1303926557302475, - 1.2057738304138184, - 2.191358804702759, - -0.9426639676094055, - -0.3424133360385895 - ] + [-0.31479185819625854, 0.02101830020546913, -0.054547298699617386, -0.8116031885147095, -0.441931813955307], + [0.01032029278576374, 1.8312735557556152, -0.6159215569496155, -0.6072822213172913, -2.05973744392395], + [1.5289140939712524, 0.3378683924674988, -0.6198564171791077, -0.7939390540122986, 0.6710167527198792], + [-0.4096096158027649, -0.530225396156311, 0.2532861530780792, -0.19900000095367432, 0.6101416945457458] ] ], - "expected_output": [ + "expected_output": 2.2536263465881348, + "expected_grad": [ + [ + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] + ], + [ + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] + ], + [ + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] + ] + ] + }, + { + "test_name": "max_dim_0_keepdim_False", + "op_name": "max", + "dim": 0, + "keepdim": false, + "input": [ [ - -0.9308503866195679, - -0.7495615482330322, - -1.1345824003219604, - -1.2495394945144653, - -1.8244128227233887 + [1.5443801879882812, -0.35117071866989136, 0.35557520389556885, -1.8119957447052002, 0.46456536650657654], + [-0.5480050444602966, -1.0596239566802979, 0.17400647699832916, 0.7506431937217712, -0.6409745812416077], + [-0.15132363140583038, 0.625577986240387, -0.6219039559364319, -1.087321400642395, -1.3252078294754028], + [0.37722504138946533, -1.4066274166107178, -0.2883475422859192, -0.9860185384750366, 1.4865750074386597] ], [ - -1.3918713331222534, - -1.149574875831604, - -0.5037038922309875, - -0.5269590616226196, - -1.1938692331314087 + [0.14713206887245178, -1.366032361984253, -0.6708536148071289, 0.9521092176437378, -2.338611602783203], + [-1.59005606174469, -0.8660301566123962, 1.278135895729065, 0.35259687900543213, -0.07500791549682617], + [0.40587425231933594, 0.5351168513298035, -1.4525551795959473, 1.2706263065338135, 0.2695809602737427], + [-0.031602293252944946, -1.2756946086883545, -0.6372569799423218, -0.761553168296814, -0.4670298099517822] ], [ - -0.531711220741272, - -0.21911364793777466, - -0.9334361553192139, - -0.9426639676094055, - -0.3424133360385895 + [-2.774542808532715, -0.20163610577583313, -0.489888072013855, -1.5937029123306274, 0.7888379693031311], + [-0.9375290870666504, -0.14468862116336823, -0.974236011505127, 0.6229617595672607, -0.34589967131614685], + [-1.7239394187927246, -0.9909027814865112, -0.49027347564697266, 0.09400757402181625, 0.8530552983283997], + [-0.01044454239308834, 1.114724040031433, -1.1784462928771973, 0.6866339445114136, 1.5644149780273438] ] ], + "expected_output": [ + [1.5443801879882812, -0.20163610577583313, 0.35557520389556885, 0.9521092176437378, 0.7888379693031311], + [-0.5480050444602966, -0.14468862116336823, 1.278135895729065, 0.7506431937217712, -0.07500791549682617], + [0.40587425231933594, 0.625577986240387, -0.49027347564697266, 1.2706263065338135, 0.8530552983283997], + [0.37722504138946533, 1.114724040031433, -0.2883475422859192, 0.6866339445114136, 1.5644149780273438] + ], "expected_grad": [ [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 1.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 1.0 - ] + [1.0, 0.0, 1.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 1.0, 0.0, 0.0] ], [ - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 1.0], + [1.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ], [ - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 1.0 - ] + [0.0, 1.0, 0.0, 0.0, 1.0], + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 1.0], + [0.0, 1.0, 0.0, 1.0, 1.0] ] ] }, { - "test_name": "min_dim_1_keepdim_True", - "op_name": "min", - "dim": 1, + "test_name": "max_dim_0_keepdim_True", + "op_name": "max", + "dim": 0, "keepdim": true, "input": [ [ - [ - 1.2685400247573853, - 0.1908181607723236, - 0.6423386931419373, - 0.5231516361236572, - 0.3537774980068207 - ], - [ - 0.14756281673908234, - -0.6777421832084656, - -0.14288291335105896, - 0.918861985206604, - 0.15021729469299316 - ], - [ - -0.7345491647720337, - 1.491151213645935, - -1.0409657955169678, - 0.9087132811546326, - 0.3067242503166199 - ], - [ - 2.699211597442627, - -1.8668535947799683, - 1.0313161611557007, - -1.0959745645523071, - -1.1971251964569092 - ] + [0.15242499113082886, 0.06238764151930809, 0.4020906984806061, 1.6428531408309937, -0.4024767577648163], + [-0.6926602125167847, 0.5779818296432495, -0.02104124240577221, 0.3675006031990051, -1.6424492597579956], + [1.6906514167785645, -1.885027527809143, -0.7859907150268555, -1.2742111682891846, -1.0625808238983154], + [-0.632580041885376, -0.8688688278198242, -1.5556751489639282, 0.4562793970108032, 0.26206839084625244] ], [ - [ - 0.3215359151363373, - -0.21750344336032867, - 0.8391018509864807, - -1.0961977243423462, - 1.1836506128311157 - ], - [ - -1.63896906375885, - -0.5325616598129272, - -0.04153263941407204, - 0.8015749454498291, - -0.6946583986282349 - ], - [ - 0.20143039524555206, - -0.9889429807662964, - 0.20942160487174988, - 0.9820282459259033, - -1.3028837442398071 - ], - [ - -0.561603844165802, - 0.8338823318481445, - -0.26739558577537537, - 0.23192813992500305, - 1.012840986251831 - ] + [0.5024110674858093, -0.4759514033794403, 1.6630321741104126, -1.454459547996521, 1.3266892433166504], + [0.6551998853683472, 0.6860383749008179, -0.6831625699996948, 0.8929892778396606, 1.6672981977462769], + [-1.0136138200759888, -1.391968846321106, -0.8026610612869263, 0.45739221572875977, -0.1074383333325386], + [2.130958080291748, 0.24406017363071442, 1.0900812149047852, 0.7718657851219177, 0.01673818565905094] ], [ - [ - -1.4937485456466675, - 0.9061921834945679, - -1.4567253589630127, - 1.2727082967758179, - 1.6362823247909546 - ], - [ - -0.9645407795906067, - 1.1407610177993774, - 0.41566601395606995, - 2.026231527328491, - -1.0126259326934814 - ], - [ - 0.9119246602058411, - -0.28909119963645935, - -0.39347609877586365, - 0.4535541534423828, - -1.1785883903503418 - ], - [ - 0.789819061756134, - 1.1420683860778809, - 0.5569579005241394, - 0.6643039584159851, - -0.19934415817260742 - ] + [0.2065047323703766, -0.3839341402053833, -0.5727554559707642, -0.368385910987854, 1.0989755392074585], + [-0.2800213098526001, -0.4368455111980438, -0.7779284715652466, 1.2181257009506226, -0.1532776802778244], + [0.3922649621963501, -0.24747081100940704, 0.2792662978172302, 0.2393292933702469, 0.08084768056869507], + [0.45395395159721375, -1.3717968463897705, -0.47459128499031067, -0.9676264524459839, -0.6989938616752625] ] ], "expected_output": [ [ - [ - -0.7345491647720337, - -1.8668535947799683, - -1.0409657955169678, - -1.0959745645523071, - -1.1971251964569092 - ] - ], - [ - [ - -1.63896906375885, - -0.9889429807662964, - -0.26739558577537537, - -1.0961977243423462, - -1.3028837442398071 - ] - ], - [ - [ - -1.4937485456466675, - -0.28909119963645935, - -1.4567253589630127, - 0.4535541534423828, - -1.1785883903503418 - ] + [0.5024110674858093, 0.06238764151930809, 1.6630321741104126, 1.6428531408309937, 1.3266892433166504], + [0.6551998853683472, 0.6860383749008179, -0.02104124240577221, 1.2181257009506226, 1.6672981977462769], + [1.6906514167785645, -0.24747081100940704, 0.2792662978172302, 0.45739221572875977, 0.08084768056869507], + [2.130958080291748, 0.24406017363071442, 1.0900812149047852, 0.7718657851219177, 0.26206839084625244] ] ], "expected_grad": [ [ - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0, - 1.0 - ] + [0.0, 1.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0] ], [ - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ] + [1.0, 0.0, 1.0, 0.0, 1.0], + [1.0, 1.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [1.0, 1.0, 1.0, 1.0, 0.0] ], [ - [ - 1.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 1.0, 1.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ] ] }, { - "test_name": "min_dim_-1_keepdim_False", - "op_name": "min", - "dim": -1, + "test_name": "max_dim_1_keepdim_False", + "op_name": "max", + "dim": 1, "keepdim": false, "input": [ [ - [ - -0.9770270586013794, - -0.584597110748291, - -1.5499167442321777, - 0.3021530210971832, - -0.34727850556373596 - ], - [ - -0.20263050496578217, - -0.27478426694869995, - -0.017359629273414612, - -0.6773730516433716, - 0.6478610038757324 - ], - [ - -0.9755827188491821, - 1.8391462564468384, - -0.0034865080378949642, - 0.4103865623474121, - 1.752099633216858 - ], - [ - 0.66091388463974, - -1.0182898044586182, - -1.101527452468872, - 0.9167301654815674, - 1.1085376739501953 - ] + [1.1716068983078003, -1.7179490327835083, -0.534604549407959, -1.306166410446167, -0.9246346950531006], + [0.6214187741279602, 0.1785161793231964, 0.2866869568824768, 0.4850883483886719, 0.005962289869785309], + [-0.3370489478111267, 1.0511995553970337, -1.3509515523910522, 0.5409456491470337, 1.134432315826416], + [-0.4212900400161743, -0.10431576520204544, 0.9755558371543884, -1.0027341842651367, 1.28053879737854] ], [ - [ - -2.0887160301208496, - 2.1544744968414307, - 0.9984968304634094, - -0.013719181530177593, - -0.9246350526809692 - ], - [ - -1.5019725561141968, - 0.7051315307617188, - 0.37148424983024597, - -0.714340090751648, - -0.15940190851688385 - ], - [ - 0.34379199147224426, - 0.4355435073375702, - -0.2341606765985489, - 0.18855510652065277, - 0.019730882719159126 - ], - [ - -0.24155908823013306, - -1.8511996269226074, - 0.2684777081012726, - -0.30269020795822144, - -0.3692476451396942 - ] + [1.2130928039550781, 0.12110324949026108, -1.2743698358535767, 0.884564220905304, 0.12699493765830994], + [-0.8810292482376099, 1.8218294382095337, 1.5863804817199707, 0.865519106388092, -0.27654826641082764], + [-0.19467514753341675, -0.03429529443383217, 0.7240417003631592, 0.13301636278629303, -1.0541536808013916], + [-2.312596321105957, -0.902730405330658, -1.4185947179794312, 0.37751105427742004, -0.2093215435743332] ], [ - [ - -0.8595789074897766, - 0.2909909188747406, - 0.6529440879821777, - 2.0979738235473633, - 0.43178966641426086 - ], - [ - -1.228909969329834, - -0.06794015318155289, - -2.2453958988189697, - 1.5783367156982422, - -0.5161778330802917 - ], - [ - -0.19803878664970398, - 0.8383589386940002, - 1.144734501838684, - -1.3692904710769653, - -0.3902406692504883 - ], - [ - 0.950104296207428, - -2.147958517074585, - -0.06174112856388092, - 0.2618931531906128, - 0.4153856635093689 - ] + [-1.1487538814544678, 0.22709836065769196, -0.9184321165084839, 0.9846003651618958, -0.06645472347736359], + [1.2572640180587769, 0.1582425981760025, -1.742975115776062, -1.2938947677612305, 1.3074569702148438], + [-0.8769122958183289, -0.015859045088291168, -0.6937687397003174, -0.8013211488723755, -0.07756809890270233], + [-0.5014570951461792, -2.2269856929779053, -0.17264695465564728, -0.4442422091960907, 0.2926892936229706] ] ], "expected_output": [ - [ - -1.5499167442321777, - -0.6773730516433716, - -0.9755827188491821, - -1.101527452468872 - ], - [ - -2.0887160301208496, - -1.5019725561141968, - -0.2341606765985489, - -1.8511996269226074 - ], - [ - -0.8595789074897766, - -2.2453958988189697, - -1.3692904710769653, - -2.147958517074585 - ] + [1.1716068983078003, 1.0511995553970337, 0.9755558371543884, 0.5409456491470337, 1.28053879737854], + [1.2130928039550781, 1.8218294382095337, 1.5863804817199707, 0.884564220905304, 0.12699493765830994], + [1.2572640180587769, 0.22709836065769196, -0.17264695465564728, 0.9846003651618958, 1.3074569702148438] ], "expected_grad": [ [ - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ] + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 1.0] ], [ - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ] + [1.0, 0.0, 0.0, 1.0, 1.0], + [0.0, 1.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ], [ - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ] + [0.0, 1.0, 0.0, 1.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0] ] ] }, { - "test_name": "min_dim_-1_keepdim_True", - "op_name": "min", - "dim": -1, + "test_name": "max_dim_1_keepdim_True", + "op_name": "max", + "dim": 1, "keepdim": true, "input": [ [ - [ - 0.5631878972053528, - 0.19998317956924438, - 0.8093208074569702, - -0.5293470621109009, - 0.448284387588501 - ], - [ - -0.8013262152671814, - 0.6317405700683594, - 1.3970056772232056, - -1.3542675971984863, - 0.13657432794570923 - ], - [ - 0.8511560559272766, - 1.1925286054611206, - 0.5439687371253967, - -1.2077754735946655, - 1.1914323568344116 - ], - [ - 1.2834670543670654, - 0.8253968954086304, - 1.7004607915878296, - 0.9272356629371643, - 0.026323553174734116 - ] + [0.05868193879723549, 1.5382329225540161, 1.0444575548171997, -0.26301294565200806, 0.2191448211669922], + [0.05122251436114311, -0.6351413130760193, -0.9322060346603394, -0.2185828685760498, 0.4121098220348358], + [-1.132474660873413, -2.3891191482543945, 0.7177993655204773, -1.5831094980239868, 0.6412859559059143], + [-0.2708216905593872, -0.6109879612922668, 0.11032737791538239, 0.12355764210224152, -1.4388847351074219] ], [ - [ - 0.7056452035903931, - 1.0615094900131226, - -1.6115124225616455, - 0.45299890637397766, - -1.1804884672164917 - ], - [ - 0.5873482823371887, - -0.1269814372062683, - 0.05342012271285057, - 1.0922929048538208, - -1.3024108409881592 - ], - [ - 1.3521305322647095, - -1.1749324798583984, - 0.11568229645490646, - 0.21853865683078766, - 1.1232846975326538 - ], - [ - -0.7424628138542175, - 0.22881479561328888, - -0.4537980556488037, - 0.797391414642334, - 1.4051463603973389 - ] + [-0.45935776829719543, 0.719353199005127, -1.2023998498916626, -0.5769718289375305, 0.7339244484901428], + [0.0939386859536171, 1.0834808349609375, 0.8089823126792908, -0.9773237109184265, -0.26083904504776], + [-0.07018473744392395, -1.206803798675537, 1.5053801536560059, -0.0004540873342193663, -0.8399935364723206], + [-0.9963456988334656, 1.9695827960968018, -0.6241140961647034, -0.11510364711284637, 1.3116685152053833] ], [ - [ - -0.5578140616416931, - 2.0406908988952637, - -2.4602458477020264, - 1.2475563287734985, - 0.46312710642814636 - ], - [ - 0.3421548902988434, - -0.1932428628206253, - 0.04506998881697655, - 0.10006450116634369, - -0.3069831430912018 - ], - [ - -0.7462528347969055, - -1.4819915294647217, - -0.782849133014679, - -0.3068717420101166, - 1.822840690612793 - ], - [ - 0.24596092104911804, - 0.26649534702301025, - -0.518925130367279, - -2.0522587299346924, - -1.131065011024475 - ] + [0.9128003120422363, -0.8139405250549316, -0.32805025577545166, -1.6033560037612915, -0.6016383171081543], + [-0.3473812937736511, -0.9625334739685059, 0.9539335370063782, -1.4123497009277344, 0.812851071357727], + [1.4345933198928833, 0.05774686485528946, 0.8243234157562256, 0.3210548460483551, -0.6046251654624939], + [-0.6875012516975403, 0.20559696853160858, -0.7192203998565674, -1.1452873945236206, 0.888896107673645] ] ], "expected_output": [ [ - [ - -0.5293470621109009 - ], - [ - -1.3542675971984863 - ], - [ - -1.2077754735946655 - ], - [ - 0.026323553174734116 - ] + [0.05868193879723549, 1.5382329225540161, 1.0444575548171997, 0.12355764210224152, 0.6412859559059143] ], [ - [ - -1.6115124225616455 - ], - [ - -1.3024108409881592 - ], - [ - -1.1749324798583984 - ], - [ - -0.7424628138542175 - ] + [0.0939386859536171, 1.9695827960968018, 1.5053801536560059, -0.0004540873342193663, 1.3116685152053833] ], [ - [ - -2.4602458477020264 - ], - [ - -0.3069831430912018 - ], - [ - -1.4819915294647217 - ], - [ - -2.0522587299346924 - ] + [1.4345933198928833, 0.20559696853160858, 0.9539335370063782, 0.3210548460483551, 0.888896107673645] ] ], "expected_grad": [ [ - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ] + [1.0, 1.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 1.0, 0.0] ], [ - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 1.0, - 0.0, - 0.0, - 0.0, - 0.0 - ] + [0.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 1.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 1.0] ], [ - [ - 0.0, - 0.0, - 1.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 1.0, - 0.0 - ] + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 1.0] ] ] - } - ], - "linear": [ + }, { - "test_name": "linear_2D_input", - "in_features": 10, - "out_features": 5, + "test_name": "max_dim_-1_keepdim_False", + "op_name": "max", + "dim": -1, + "keepdim": false, "input": [ [ - 1.995280146598816, - -0.6346070170402527, - 1.0690128803253174, - 1.160980463027954, - -1.7790907621383667, - 0.8086466789245605, - -0.1060129776597023, - 2.2590320110321045, - 0.3341250419616699, - -0.27466103434562683 - ], - [ - -0.29712751507759094, - -0.5143458247184753, - 1.5861903429031372, - 1.3935821056365967, - -0.08091596513986588, - -0.561027467250824, - -0.4829641580581665, - 0.4769587814807892, - 0.17047974467277527, - 0.845003604888916 - ], - [ - 1.797692060470581, - 1.4310468435287476, - -0.1232481449842453, - 0.0116643775254488, - 0.3026885390281677, - -0.7567965984344482, - 0.7330871224403381, - -1.003272533416748, - 0.2109839767217636, - 1.4640601873397827 - ] - ], - "weight": [ + [1.102234125137329, 0.1452106386423111, -1.0025994777679443, -0.8691359758377075, 1.034902811050415], + [1.141363263130188, -0.6113547086715698, 0.5669911503791809, 0.08074041455984116, 0.769339919090271], + [-1.206941843032837, -0.1684180051088333, -1.0213230848312378, 0.45474377274513245, 0.05628223717212677], + [0.1908469796180725, 1.134475827217102, -0.6270834803581238, -0.2348310351371765, 0.1834784746170044] + ], + [ + [0.8270988464355469, 0.6817458271980286, 0.40630635619163513, 1.706158995628357, -0.3331676423549652], + [1.3781265020370483, 0.22484587132930756, -2.3762154579162598, 0.4015538990497589, -2.294616460800171], + [0.9543997049331665, -0.3883368968963623, -0.6146398186683655, -0.4274226725101471, -1.4890133142471313], + [0.5850116610527039, -0.6405912041664124, -1.9063634872436523, -0.21498170495033264, 0.1672649085521698] + ], [ - -0.24328012764453888, - 0.028091339394450188, - -0.16780336201190948, - -0.06218525767326355, - -0.04895494133234024, - 0.015718938782811165, - -0.27727454900741577, - 0.2699316143989563, - -0.1345617175102234, - 0.09880602359771729 - ], - [ - 0.2177683264017105, - 0.12743021547794342, - 0.2214605212211609, - 0.17856846749782562, - 0.23155508935451508, - 0.06674247980117798, - 0.2019743025302887, - -0.1374560296535492, - -0.17039762437343597, - 0.15100044012069702 - ], - [ - 0.08297339081764221, - -0.011858473531901836, - -0.26674091815948486, - 0.1033318042755127, - 0.20483756065368652, - -0.036509934812784195, - 0.07265040278434753, - 0.14077845215797424, - -0.312299907207489, - -0.05202847719192505 - ], - [ - -0.11730943620204926, - -0.1616298258304596, - 0.19328103959560394, - 0.3135358691215515, - 0.050457291305065155, - 0.19681504368782043, - -0.2346036732196808, - 0.055711012333631516, - -0.04089835286140442, - -0.1950366348028183 - ], - [ - 0.06484019756317139, - 0.10066336393356323, - -0.015273772180080414, - 0.134284108877182, - 0.15182378888130188, - 0.2868318259716034, - 0.018331248313188553, - 0.011266625486314297, - -0.004526200238615274, - 0.04364045336842537 + [-0.02165069803595543, 0.7171346545219421, -1.3825470209121704, 0.5667335987091064, 0.1853654533624649], + [1.7064272165298462, 2.270893096923828, 0.6268392205238342, 1.6014127731323242, 1.196624517440796], + [0.07062987983226776, -0.06806328892707825, -0.8778694272041321, -0.666265070438385, 0.34564408659935], + [-0.1972421109676361, -1.5218473672866821, -0.06109791249036789, -0.49620160460472107, 1.5591261386871338] ] ], - "bias": [ - -0.2050478756427765, - -0.03892422094941139, - -0.2674124538898468, - -0.22181136906147003, - -0.26935896277427673 - ], "expected_output": [ + [1.102234125137329, 1.141363263130188, 0.45474377274513245, 1.134475827217102], + [1.706158995628357, 1.3781265020370483, 0.9543997049331665, 0.5850116610527039], + [0.7171346545219421, 2.270893096923828, 0.34564408659935, 1.5591261386871338] + ], + "expected_grad": [ [ - -0.2929801046848297, - -0.029548827558755875, - -0.4331992268562317, - 0.4773373007774353, - -0.0924459844827652 + [1.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0] ], [ - -0.18168585002422333, - 0.31021445989608765, - -0.6263059377670288, - 0.49329322576522827, - -0.3180721402168274 + [0.0, 0.0, 0.0, 1.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0] ], [ - -0.9667624235153198, - 1.0003747940063477, - -0.24155186116695404, - -1.339890480041504, - -0.11133930087089539 - ] - ], - "expected_grad_input": [ - [ - 0.004992350935935974, - 0.08269661664962769, - -0.03507646173238754, - 0.6675350666046143, - 0.5897188186645508, - 0.5295983552932739, - -0.21892227232456207, - 0.34023168683052063, - -0.6626837849617004, - 0.04638180509209633 - ], - [ - 0.004992350935935974, - 0.08269661664962769, - -0.03507646173238754, - 0.6675350666046143, - 0.5897188186645508, - 0.5295983552932739, - -0.21892227232456207, - 0.34023168683052063, - -0.6626837849617004, - 0.04638180509209633 - ], - [ - 0.004992350935935974, - 0.08269661664962769, - -0.03507646173238754, - 0.6675350666046143, - 0.5897188186645508, - 0.5295983552932739, - -0.21892227232456207, - 0.34023168683052063, - -0.6626837849617004, - 0.04638180509209633 - ] - ], - "expected_grad_weight": [ - [ - 3.495844841003418, - 0.28209400177001953, - 2.5319552421569824, - 2.5662269592285156, - -1.5573182106018066, - -0.5091773867607117, - 0.14410996437072754, - 1.7327182292938232, - 0.7155888080596924, - 2.034402847290039 - ], - [ - 3.495844841003418, - 0.28209400177001953, - 2.5319552421569824, - 2.5662269592285156, - -1.5573182106018066, - -0.5091773867607117, - 0.14410996437072754, - 1.7327182292938232, - 0.7155888080596924, - 2.034402847290039 - ], - [ - 3.495844841003418, - 0.28209400177001953, - 2.5319552421569824, - 2.5662269592285156, - -1.5573182106018066, - -0.5091773867607117, - 0.14410996437072754, - 1.7327182292938232, - 0.7155888080596924, - 2.034402847290039 - ], - [ - 3.495844841003418, - 0.28209400177001953, - 2.5319552421569824, - 2.5662269592285156, - -1.5573182106018066, - -0.5091773867607117, - 0.14410996437072754, - 1.7327182292938232, - 0.7155888080596924, - 2.034402847290039 - ], - [ - 3.495844841003418, - 0.28209400177001953, - 2.5319552421569824, - 2.5662269592285156, - -1.5573182106018066, - -0.5091773867607117, - 0.14410996437072754, - 1.7327182292938232, - 0.7155888080596924, - 2.034402847290039 + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 0.0, 1.0] ] - ], - "expected_grad_bias": [ - 3.0, - 3.0, - 3.0, - 3.0, - 3.0 ] }, { - "test_name": "linear_3D_batched_input", - "in_features": 4, - "out_features": 2, + "test_name": "max_dim_-1_keepdim_True", + "op_name": "max", + "dim": -1, + "keepdim": true, "input": [ [ - [ - -0.3233233392238617, - -0.3046680688858032, - -0.22401957213878632, - 0.2504769563674927 - ], - [ - 1.7058311700820923, - 1.3944706916809082, - 1.136904239654541, - 1.1797000169754028 - ], - [ - 0.6420789957046509, - -3.0800278186798096, - -1.3616151809692383, - -0.2960043251514435 - ] + [0.08976225554943085, -2.1487770080566406, -0.26685312390327454, 0.06450489908456802, -1.4932622909545898], + [1.6294554471969604, -1.738688588142395, 1.7332375049591064, 2.0544910430908203, 1.293807029724121], + [0.8169977068901062, -1.0389111042022705, -1.4858906269073486, 1.4143908023834229, 0.7241055965423584], + [1.134980320930481, -0.2217475324869156, 2.139716625213623, 0.19970077276229858, 0.8841625452041626] ], [ - [ - 1.1283513307571411, - -0.7886322736740112, - -0.038704462349414825, - 0.6835862398147583 - ], - [ - 0.5444626212120056, - 0.454408198595047, - 0.9106372594833374, - 0.9990993142127991 - ], - [ - -0.27131080627441406, - -0.9536606073379517, - -0.6736571192741394, - 1.259739637374878 - ] - ] - ], - "weight": [ - [ - 0.13263213634490967, - -0.20593488216400146, - 0.0932854413986206, - 0.43565016984939575 + [0.949975848197937, -0.10251139849424362, 0.9830695986747742, -1.6503483057022095, 0.10293407738208771], + [-1.2885284423828125, -0.7290129065513611, -1.3367583751678467, 0.28592362999916077, 1.0034847259521484], + [0.6469754576683044, 1.3000932931900024, -0.634432315826416, 0.09809456765651703, -2.255279064178467], + [-1.0050581693649292, 0.27072352170944214, 0.2964065372943878, -0.010661646723747253, 0.32635602355003357] ], [ - 0.22836577892303467, - 0.4893844723701477, - -0.21178466081619263, - -0.23876512050628662 + [-0.779302179813385, 1.35313880443573, 0.9089425206184387, -1.2521377801895142, -0.1434730738401413], + [0.10889503359794617, 0.09379234164953232, -0.7034569978713989, -0.17944560945034027, 0.45458918809890747], + [-0.26298829913139343, 0.39442673325538635, 0.3479395806789398, -1.4978502988815308, 0.7075753211975098], + [0.693645179271698, -0.07173124700784683, -0.2537860572338104, 0.2973843812942505, -1.541783332824707] ] ], - "bias": [ - -0.06348574161529541, - -0.10069990158081055 - ], "expected_output": [ [ - [ - 0.04459554702043533, - -0.33599695563316345 - ], - [ - 0.49558526277542114, - 0.44883573055267334 - ], - [ - 0.39998650550842285, - -1.1023441553115845 - ] + [0.08976225554943085], + [2.0544910430908203], + [1.4143908023834229], + [2.139716625213623] ], - [ - [ - 0.5427707433700562, - -0.3839870095252991 - ], - [ - 0.4353559911251068, - -0.18539203703403473 - ], - [ - 0.5828850865364075, - -0.7874763607978821 - ] - ] - ], - "expected_grad_input": [ - [ - [ - 0.36099791526794434, - 0.28344959020614624, - -0.11849921941757202, - 0.19688504934310913 - ], - [ - 0.36099791526794434, - 0.28344959020614624, - -0.11849921941757202, - 0.19688504934310913 - ], - [ - 0.36099791526794434, - 0.28344959020614624, - -0.11849921941757202, - 0.19688504934310913 - ] + [ + [0.9830695986747742], + [1.0034847259521484], + [1.3000932931900024], + [0.32635602355003357] ], [ - [ - 0.36099791526794434, - 0.28344959020614624, - -0.11849921941757202, - 0.19688504934310913 - ], - [ - 0.36099791526794434, - 0.28344959020614624, - -0.11849921941757202, - 0.19688504934310913 - ], - [ - 0.36099791526794434, - 0.28344959020614624, - -0.11849921941757202, - 0.19688504934310913 - ] + [1.35313880443573], + [0.45458918809890747], + [0.7075753211975098], + [0.693645179271698] ] ], - "expected_grad_weight": [ + "expected_grad": [ + [ + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0] + ], [ - 3.4260900020599365, - -3.2781100273132324, - -0.250454843044281, - 4.076597690582275 + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0] ], [ - 3.4260900020599365, - -3.2781100273132324, - -0.250454843044281, - 4.076597690582275 + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [1.0, 0.0, 0.0, 0.0, 0.0] ] - ], - "expected_grad_bias": [ - 6.0, - 6.0 ] - } - ], - "optimizers": [ + }, { - "test_name": "SGD_basic", - "optimizer": "SGD", - "kwargs": { - "lr": 0.1 - }, - "initial_weight": [ + "test_name": "min_dim_None_keepdim_False", + "op_name": "min", + "dim": null, + "keepdim": false, + "input": [ [ - 1.1711158752441406, - -0.2590734362602234, - -0.3033114969730377 + [-1.4054443836212158, 0.007234930992126465, 0.5773534178733826, 0.30951234698295593, -0.8588898777961731], + [0.526231050491333, -0.06828558444976807, 1.2680625915527344, 0.23789522051811218, -1.805619716644287], + [1.746630311012268, -1.526967167854309, 0.3485613167285919, 0.7839732766151428, 1.5388095378875732], + [1.1633633375167847, 0.8717845678329468, 0.21581949293613434, 0.1374770998954773, -1.1221222877502441] ], [ - 0.2349793165922165, - 1.0358152389526367, - 0.715836763381958 + [0.1467854380607605, -0.17452457547187805, -0.7465326189994812, -1.163095235824585, -1.0377240180969238], + [0.6390634179115295, -0.929384708404541, 0.07479915767908096, 0.641934871673584, 1.1865335702896118], + [-0.7681276798248291, -0.8917787075042725, 0.19665859639644623, 0.6306189298629761, 1.6684050559997559], + [1.258668065071106, 0.16344283521175385, 0.8060418367385864, -0.6885544061660767, -0.23013491928577423] ], [ - -0.7037585973739624, - -0.284278929233551, - 0.7185912728309631 + [1.1331552267074585, 0.42492198944091797, -0.07918443530797958, 0.3510800898075104, 0.45417457818984985], + [0.3879549503326416, -0.6664285659790039, -0.5420844554901123, 2.9302103519439697, 0.03980718180537224], + [-1.2734509706497192, 1.154341697692871, 0.7456277012825012, -0.46407395601272583, 0.354059636592865], + [0.5733898282051086, -1.9253568649291992, 1.3460670709609985, -0.9440423846244812, 0.5850473642349243] ] ], - "input_x": [ + "expected_output": -1.9253568649291992, + "expected_grad": [ [ - 1.8401010036468506, - 0.04152654483914375, - -1.7044862508773804 + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ], [ - -0.3476502001285553, - -0.3426065444946289, - 0.11469119042158127 + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ], [ - -0.4225151538848877, - 0.7643097639083862, - -0.5040589570999146 + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0] ] - ], - "expected_grad": [ + ] + }, + { + "test_name": "min_dim_0_keepdim_False", + "op_name": "min", + "dim": 0, + "keepdim": false, + "input": [ [ - 1.8401010036468506, - 0.04152654483914375, - -1.7044862508773804 + [-0.7561046481132507, -0.6087163090705872, 0.06523545831441879, 0.2073671668767929, -0.4843977093696594], + [-0.4931473731994629, 0.695488691329956, 1.5209262371063232, -1.5004045963287354, 1.424126148223877], + [0.4264316260814667, 1.725341796875, -1.1767886877059937, -0.5571966767311096, 2.1753745079040527], + [-0.4421183466911316, -1.742424488067627, -0.7672881484031677, 1.4304224252700806, 0.39234694838523865] ], [ - -0.3476502001285553, - -0.3426065444946289, - 0.11469119042158127 + [-1.3970006704330444, -2.0020906925201416, -0.26867592334747314, -0.701147735118866, 0.31265851855278015], + [-0.3883015811443329, 0.8928799033164978, 0.7249560952186584, 0.4335167407989502, 0.9744104146957397], + [-0.21621425449848175, -0.29577603936195374, -0.2591007351875305, 0.7960927486419678, 0.5791953802108765], + [-0.13450507819652557, -1.3556065559387207, -0.394126832485199, -0.7559952735900879, 0.5876944661140442] ], [ - -0.4225151538848877, - 0.7643097639083862, - -0.5040589570999146 + [-1.3335460424423218, 0.9432480931282043, -1.1379897594451904, -1.1207023859024048, -0.6139907240867615], + [0.9939887523651123, 0.5297332406044006, -0.3778044879436493, 1.417391061782837, 0.4910713732242584], + [0.9159647822380066, 0.1735081523656845, -1.438053846359253, 0.6212812662124634, -1.969196081161499], + [-0.2445336878299713, -0.6776713728904724, 0.47822806239128113, -1.8905819654464722, 0.2990115284919739] ] ], - "expected_updated_weight": [ + "expected_output": [ + [-1.3970006704330444, -2.0020906925201416, -1.1379897594451904, -1.1207023859024048, -0.6139907240867615], + [-0.4931473731994629, 0.5297332406044006, -0.3778044879436493, -1.5004045963287354, 0.4910713732242584], + [-0.21621425449848175, -0.29577603936195374, -1.438053846359253, -0.5571966767311096, -1.969196081161499], + [-0.4421183466911316, -1.742424488067627, -0.7672881484031677, -1.8905819654464722, 0.2990115284919739] + ], + "expected_grad": [ [ - 0.9871057868003845, - -0.26322609186172485, - -0.1328628659248352 + [0.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [1.0, 1.0, 1.0, 0.0, 0.0] ], [ - 0.269744336605072, - 1.0700758695602417, - 0.7043676376342773 + [1.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ], [ - -0.6615070700645447, - -0.36070990562438965, - 0.7689971923828125 + [0.0, 0.0, 1.0, 1.0, 1.0], + [0.0, 1.0, 1.0, 0.0, 1.0], + [0.0, 0.0, 1.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 1.0, 1.0] ] ] }, { - "test_name": "SGD_momentum", - "optimizer": "SGD", - "kwargs": { - "lr": 0.1, - "momentum": 0.9 - }, - "initial_weight": [ + "test_name": "min_dim_0_keepdim_True", + "op_name": "min", + "dim": 0, + "keepdim": true, + "input": [ [ - -0.9779782891273499, - 1.0851811170578003, - 0.24460527300834656 + [0.4874853193759918, -1.5288264751434326, 0.3616181015968323, 0.4444722533226013, 0.37175261974334717], + [0.17289385199546814, -1.2141680717468262, 1.9441745281219482, -0.5341972708702087, -0.07878366857767105], + [0.9717959761619568, 0.15757296979427338, -0.1293685883283615, 0.9459248185157776, 0.7486283779144287], + [1.3489890098571777, -0.11803387850522995, 0.8932477235794067, 0.8591998815536499, 1.068840742111206] ], [ - 0.10595189034938812, - 0.9393600821495056, - 0.3916529417037964 + [1.035352349281311, -1.0888819694519043, -0.9833644032478333, 0.18595486879348755, -0.5669856071472168], + [-1.0098682641983032, -0.4541301131248474, 0.6979333758354187, 0.546902596950531, 0.5524624586105347], + [0.2402925342321396, -1.1295276880264282, 2.641334295272827, -0.42235150933265686, 0.3279983699321747], + [-0.22356857359409332, 0.6338478326797485, 1.2712687253952026, 0.5257611274719238, -0.08859143406152725] ], [ - 0.4106380343437195, - -0.0652524009346962, - 0.5183061361312866 + [0.2868587076663971, 1.34219491481781, -0.4532349705696106, 1.0591752529144287, -0.007002960424870253], + [1.0370234251022339, 0.12661591172218323, 0.9138452410697937, 0.15242700278759003, -1.77699875831604], + [-0.2700897455215454, 1.132546067237854, -0.4591978192329407, 0.7583627104759216, -0.25366878509521484], + [-0.6026967763900757, 0.41119346022605896, -0.4785611629486084, -0.3798253536224365, -0.6784350275993347] ] ], - "input_x": [ + "expected_output": [ + [ + [0.2868587076663971, -1.5288264751434326, -0.9833644032478333, 0.18595486879348755, -0.5669856071472168], + [-1.0098682641983032, -1.2141680717468262, 0.6979333758354187, -0.5341972708702087, -1.77699875831604], + [-0.2700897455215454, -1.1295276880264282, -0.4591978192329407, -0.42235150933265686, -0.25366878509521484], + [-0.6026967763900757, -0.11803387850522995, -0.4785611629486084, -0.3798253536224365, -0.6784350275993347] + ] + ], + "expected_grad": [ [ - 0.05883641913533211, - 0.5554778575897217, - 1.053452968597412 + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0] ], [ - -0.2609460651874542, - -1.6987152099609375, - -0.08697007596492767 + [0.0, 0.0, 1.0, 1.0, 1.0], + [1.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ], [ - 2.333068609237671, - -0.035302918404340744, - 2.392319917678833 + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [1.0, 0.0, 1.0, 0.0, 1.0], + [1.0, 0.0, 1.0, 1.0, 1.0] ] - ], - "expected_grad": [ + ] + }, + { + "test_name": "min_dim_1_keepdim_False", + "op_name": "min", + "dim": 1, + "keepdim": false, + "input": [ [ - 0.05883641913533211, - 0.5554778575897217, - 1.053452968597412 + [1.1780027151107788, 0.3302285671234131, 0.3409285247325897, 0.0966181680560112, 0.8048174381256104], + [-0.9308503866195679, -0.7495615482330322, -1.1345824003219604, 1.743110179901123, 0.24290774762630463], + [0.2789574861526489, 0.3315619230270386, -0.05199375003576279, -0.38996851444244385, 0.45961233973503113], + [1.5001028776168823, 0.4969956576824188, 0.8539602756500244, -1.2495394945144653, -1.8244128227233887] ], [ - -0.2609460651874542, - -1.6987152099609375, - -0.08697007596492767 + [1.9353760480880737, 0.32966846227645874, -0.5037038922309875, 0.5824847221374512, -0.04406149685382843], + [0.26977765560150146, -1.149574875831604, 0.5576037764549255, -0.4423902630805969, -1.1938692331314087], + [0.5121238231658936, 0.3450745940208435, 1.2737618684768677, -0.5269590616226196, 0.36447712779045105], + [-1.3918713331222534, -0.13599461317062378, 0.5021628141403198, 0.3100223243236542, 0.08071848005056381] ], [ - 2.333068609237671, - -0.035302918404340744, - 2.392319917678833 + [0.2132561206817627, -0.21911364793777466, 1.0261167287826538, -0.15927140414714813, 0.12461294233798981], + [1.5179888010025024, 0.2487545758485794, -0.9334361553192139, 1.019239902496338, 0.0731339082121849], + [-0.531711220741272, -0.03542341664433479, -0.5915296077728271, -0.014602077193558216, 0.2609618306159973], + [0.1303926557302475, 1.2057738304138184, 2.191358804702759, -0.9426639676094055, -0.3424133360385895] ] ], - "expected_updated_weight": [ + "expected_output": [ + [-0.9308503866195679, -0.7495615482330322, -1.1345824003219604, -1.2495394945144653, -1.8244128227233887], + [-1.3918713331222534, -1.149574875831604, -0.5037038922309875, -0.5269590616226196, -1.1938692331314087], + [-0.531711220741272, -0.21911364793777466, -0.9334361553192139, -0.9426639676094055, -0.3424133360385895] + ], + "expected_grad": [ [ - -0.9838619232177734, - 1.0296332836151123, - 0.13925997912883759 + [0.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 1.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 1.0] ], [ - 0.13204649090766907, - 1.1092315912246704, - 0.4003499448299408 + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0] ], [ - 0.17733116447925568, - -0.061722107231616974, - 0.27907413244247437 + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 1.0] ] ] }, { - "test_name": "Adam_basic", - "optimizer": "Adam", - "kwargs": { - "lr": 0.1 - }, - "initial_weight": [ + "test_name": "min_dim_1_keepdim_True", + "op_name": "min", + "dim": 1, + "keepdim": true, + "input": [ [ - 0.861420214176178, - 1.0063271522521973, - 0.9432656168937683 + [1.2685400247573853, 0.1908181607723236, 0.6423386931419373, 0.5231516361236572, 0.3537774980068207], + [0.14756281673908234, -0.6777421832084656, -0.14288291335105896, 0.918861985206604, 0.15021729469299316], + [-0.7345491647720337, 1.491151213645935, -1.0409657955169678, 0.9087132811546326, 0.3067242503166199], + [2.699211597442627, -1.8668535947799683, 1.0313161611557007, -1.0959745645523071, -1.1971251964569092] ], [ - 0.22092591226100922, - -1.1125500202178955, - 0.1605069637298584 + [0.3215359151363373, -0.21750344336032867, 0.8391018509864807, -1.0961977243423462, 1.1836506128311157], + [-1.63896906375885, -0.5325616598129272, -0.04153263941407204, 0.8015749454498291, -0.6946583986282349], + [0.20143039524555206, -0.9889429807662964, 0.20942160487174988, 0.9820282459259033, -1.3028837442398071], + [-0.561603844165802, 0.8338823318481445, -0.26739558577537537, 0.23192813992500305, 1.012840986251831] ], [ - 1.8549803495407104, - -0.16434448957443237, - -0.4784829616546631 + [-1.4937485456466675, 0.9061921834945679, -1.4567253589630127, 1.2727082967758179, 1.6362823247909546], + [-0.9645407795906067, 1.1407610177993774, 0.41566601395606995, 2.026231527328491, -1.0126259326934814], + [0.9119246602058411, -0.28909119963645935, -0.39347609877586365, 0.4535541534423828, -1.1785883903503418], + [0.789819061756134, 1.1420683860778809, 0.5569579005241394, 0.6643039584159851, -0.19934415817260742] ] ], - "input_x": [ + "expected_output": [ [ - 0.38463443517684937, - -0.3245149850845337, - -1.5829708576202393 + [-0.7345491647720337, -1.8668535947799683, -1.0409657955169678, -1.0959745645523071, -1.1971251964569092] ], [ - -0.6101211309432983, - 0.2677954137325287, - 1.1987781524658203 + [-1.63896906375885, -0.9889429807662964, -0.26739558577537537, -1.0961977243423462, -1.3028837442398071] ], [ - 1.122973918914795, - 1.4562538862228394, - 0.9092239141464233 + [-1.4937485456466675, -0.28909119963645935, -1.4567253589630127, 0.4535541534423828, -1.1785883903503418] ] ], "expected_grad": [ [ - 0.38463443517684937, - -0.3245149850845337, - -1.5829708576202393 + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 1.0, 1.0] ], [ - -0.6101211309432983, - 0.2677954137325287, - 1.1987781524658203 + [0.0, 0.0, 0.0, 1.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 1.0], + [0.0, 0.0, 1.0, 0.0, 0.0] ], [ - 1.122973918914795, - 1.4562538862228394, - 0.9092239141464233 + [1.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 1.0, 1.0], + [0.0, 0.0, 0.0, 0.0, 0.0] ] - ], - "expected_updated_weight": [ + ] + }, + { + "test_name": "min_dim_-1_keepdim_False", + "op_name": "min", + "dim": -1, + "keepdim": false, + "input": [ [ - 0.7614202499389648, - 1.1063271760940552, - 1.0432655811309814 + [-0.9770270586013794, -0.584597110748291, -1.5499167442321777, 0.3021530210971832, -0.34727850556373596], + [-0.20263050496578217, -0.27478426694869995, -0.017359629273414612, -0.6773730516433716, 0.6478610038757324], + [-0.9755827188491821, 1.8391462564468384, -0.0034865080378949642, 0.4103865623474121, 1.752099633216858], + [0.66091388463974, -1.0182898044586182, -1.101527452468872, 0.9167301654815674, 1.1085376739501953] ], [ - 0.32092589139938354, - -1.2125500440597534, - 0.06050696223974228 + [-2.0887160301208496, 2.1544744968414307, 0.9984968304634094, -0.013719181530177593, -0.9246350526809692], + [-1.5019725561141968, 0.7051315307617188, 0.37148424983024597, -0.714340090751648, -0.15940190851688385], + [0.34379199147224426, 0.4355435073375702, -0.2341606765985489, 0.18855510652065277, 0.019730882719159126], + [-0.24155908823013306, -1.8511996269226074, 0.2684777081012726, -0.30269020795822144, -0.3692476451396942] ], [ - 1.7549803256988525, - -0.2643444836139679, - -0.578482985496521 - ] - ] - }, - { - "test_name": "Adam_custom_betas", - "optimizer": "Adam", - "kwargs": { - "lr": 0.1, - "betas": [ - 0.95, - 0.999 + [-0.8595789074897766, 0.2909909188747406, 0.6529440879821777, 2.0979738235473633, 0.43178966641426086], + [-1.228909969329834, -0.06794015318155289, -2.2453958988189697, 1.5783367156982422, -0.5161778330802917], + [-0.19803878664970398, 0.8383589386940002, 1.144734501838684, -1.3692904710769653, -0.3902406692504883], + [0.950104296207428, -2.147958517074585, -0.06174112856388092, 0.2618931531906128, 0.4153856635093689] ] - }, - "initial_weight": [ + ], + "expected_output": [ + [-1.5499167442321777, -0.6773730516433716, -0.9755827188491821, -1.101527452468872], + [-2.0887160301208496, -1.5019725561141968, -0.2341606765985489, -1.8511996269226074], + [-0.8595789074897766, -2.2453958988189697, -1.3692904710769653, -2.147958517074585] + ], + "expected_grad": [ [ - 0.9442354440689087, - 2.31821870803833, - 0.64822918176651 + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0] ], [ - -0.4594375491142273, - 0.8558579683303833, - 1.3270264863967896 + [1.0, 0.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0] ], [ - 0.9446682333946228, - -0.30597713589668274, - 0.44008857011795044 + [1.0, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 1.0, 0.0, 0.0, 0.0] ] - ], - "input_x": [ + ] + }, + { + "test_name": "min_dim_-1_keepdim_True", + "op_name": "min", + "dim": -1, + "keepdim": true, + "input": [ [ - -0.17014701664447784, - 0.12107481062412262, - 0.10815810412168503 + [0.5631878972053528, 0.19998317956924438, 0.8093208074569702, -0.5293470621109009, 0.448284387588501], + [-0.8013262152671814, 0.6317405700683594, 1.3970056772232056, -1.3542675971984863, 0.13657432794570923], + [0.8511560559272766, 1.1925286054611206, 0.5439687371253967, -1.2077754735946655, 1.1914323568344116], + [1.2834670543670654, 0.8253968954086304, 1.7004607915878296, 0.9272356629371643, 0.026323553174734116] ], [ - 0.5580024719238281, - -1.8953827619552612, - 0.12464731931686401 + [0.7056452035903931, 1.0615094900131226, -1.6115124225616455, 0.45299890637397766, -1.1804884672164917], + [0.5873482823371887, -0.1269814372062683, 0.05342012271285057, 1.0922929048538208, -1.3024108409881592], + [1.3521305322647095, -1.1749324798583984, 0.11568229645490646, 0.21853865683078766, 1.1232846975326538], + [-0.7424628138542175, 0.22881479561328888, -0.4537980556488037, 0.797391414642334, 1.4051463603973389] ], [ - -0.3046552538871765, - -0.7077358961105347, - -1.7160437107086182 + [-0.5578140616416931, 2.0406908988952637, -2.4602458477020264, 1.2475563287734985, 0.46312710642814636], + [0.3421548902988434, -0.1932428628206253, 0.04506998881697655, 0.10006450116634369, -0.3069831430912018], + [-0.7462528347969055, -1.4819915294647217, -0.782849133014679, -0.3068717420101166, 1.822840690612793], + [0.24596092104911804, 0.26649534702301025, -0.518925130367279, -2.0522587299346924, -1.131065011024475] ] ], - "expected_grad": [ + "expected_output": [ [ - -0.17014701664447784, - 0.12107481062412262, - 0.10815810412168503 + [-0.5293470621109009], + [-1.3542675971984863], + [-1.2077754735946655], + [0.026323553174734116] ], [ - 0.5580024719238281, - -1.8953827619552612, - 0.12464731931686401 + [-1.6115124225616455], + [-1.3024108409881592], + [-1.1749324798583984], + [-0.7424628138542175] ], [ - -0.3046552538871765, - -0.7077358961105347, - -1.7160437107086182 + [-2.4602458477020264], + [-0.3069831430912018], + [-1.4819915294647217], + [-2.0522587299346924] ] ], - "expected_updated_weight": [ + "expected_grad": [ [ - 1.0442354679107666, - 2.2182188034057617, - 0.5482292175292969 + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0] ], [ - -0.5594375133514404, - 0.9558579921722412, - 1.2270264625549316 + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 1.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 0.0, 0.0] ], [ - 1.044668197631836, - -0.20597714185714722, - 0.5400885939598083 + [0.0, 0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0, 1.0], + [0.0, 1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0, 0.0] ] ] } ], - "expand": [ + "linear": [ { - "test_name": "expand_1D_expand", + "test_name": "linear_2D_input", + "in_features": 10, + "out_features": 5, "input": [ - -0.5965784788131714 + [1.995280146598816, -0.6346070170402527, 1.0690128803253174, 1.160980463027954, -1.7790907621383667, 0.8086466789245605, -0.1060129776597023, 2.2590320110321045, 0.3341250419616699, -0.27466103434562683], + [-0.29712751507759094, -0.5143458247184753, 1.5861903429031372, 1.3935821056365967, -0.08091596513986588, -0.561027467250824, -0.4829641580581665, 0.4769587814807892, 0.17047974467277527, 0.845003604888916], + [1.797692060470581, 1.4310468435287476, -0.1232481449842453, 0.0116643775254488, 0.3026885390281677, -0.7567965984344482, 0.7330871224403381, -1.003272533416748, 0.2109839767217636, 1.4640601873397827] ], - "expand_shape": [ - 3 + "weight": [ + [-0.24328012764453888, 0.028091339394450188, -0.16780336201190948, -0.06218525767326355, -0.04895494133234024, 0.015718938782811165, -0.27727454900741577, 0.2699316143989563, -0.1345617175102234, 0.09880602359771729], + [0.2177683264017105, 0.12743021547794342, 0.2214605212211609, 0.17856846749782562, 0.23155508935451508, 0.06674247980117798, 0.2019743025302887, -0.1374560296535492, -0.17039762437343597, 0.15100044012069702], + [0.08297339081764221, -0.011858473531901836, -0.26674091815948486, 0.1033318042755127, 0.20483756065368652, -0.036509934812784195, 0.07265040278434753, 0.14077845215797424, -0.312299907207489, -0.05202847719192505], + [-0.11730943620204926, -0.1616298258304596, 0.19328103959560394, 0.3135358691215515, 0.050457291305065155, 0.19681504368782043, -0.2346036732196808, 0.055711012333631516, -0.04089835286140442, -0.1950366348028183], + [0.06484019756317139, 0.10066336393356323, -0.015273772180080414, 0.134284108877182, 0.15182378888130188, 0.2868318259716034, 0.018331248313188553, 0.011266625486314297, -0.004526200238615274, 0.04364045336842537] ], + "bias": [-0.2050478756427765, -0.03892422094941139, -0.2674124538898468, -0.22181136906147003, -0.26935896277427673], "expected_output": [ - -0.5965784788131714, - -0.5965784788131714, - -0.5965784788131714 + [-0.2929801046848297, -0.029548827558755875, -0.4331992268562317, 0.4773373007774353, -0.0924459844827652], + [-0.18168585002422333, 0.31021445989608765, -0.6263059377670288, 0.49329322576522827, -0.3180721402168274], + [-0.9667624235153198, 1.0003747940063477, -0.24155186116695404, -1.339890480041504, -0.11133930087089539] ], - "expected_grad": [ - 3.0 - ] + "expected_grad_input": [ + [0.004992350935935974, 0.08269661664962769, -0.03507646173238754, 0.6675350666046143, 0.5897188186645508, 0.5295983552932739, -0.21892227232456207, 0.34023168683052063, -0.6626837849617004, 0.04638180509209633], + [0.004992350935935974, 0.08269661664962769, -0.03507646173238754, 0.6675350666046143, 0.5897188186645508, 0.5295983552932739, -0.21892227232456207, 0.34023168683052063, -0.6626837849617004, 0.04638180509209633], + [0.004992350935935974, 0.08269661664962769, -0.03507646173238754, 0.6675350666046143, 0.5897188186645508, 0.5295983552932739, -0.21892227232456207, 0.34023168683052063, -0.6626837849617004, 0.04638180509209633] + ], + "expected_grad_weight": [ + [3.495844841003418, 0.28209400177001953, 2.5319552421569824, 2.5662269592285156, -1.5573182106018066, -0.5091773867607117, 0.14410996437072754, 1.7327182292938232, 0.7155888080596924, 2.034402847290039], + [3.495844841003418, 0.28209400177001953, 2.5319552421569824, 2.5662269592285156, -1.5573182106018066, -0.5091773867607117, 0.14410996437072754, 1.7327182292938232, 0.7155888080596924, 2.034402847290039], + [3.495844841003418, 0.28209400177001953, 2.5319552421569824, 2.5662269592285156, -1.5573182106018066, -0.5091773867607117, 0.14410996437072754, 1.7327182292938232, 0.7155888080596924, 2.034402847290039], + [3.495844841003418, 0.28209400177001953, 2.5319552421569824, 2.5662269592285156, -1.5573182106018066, -0.5091773867607117, 0.14410996437072754, 1.7327182292938232, 0.7155888080596924, 2.034402847290039], + [3.495844841003418, 0.28209400177001953, 2.5319552421569824, 2.5662269592285156, -1.5573182106018066, -0.5091773867607117, 0.14410996437072754, 1.7327182292938232, 0.7155888080596924, 2.034402847290039] + ], + "expected_grad_bias": [3.0, 3.0, 3.0, 3.0, 3.0] }, { - "test_name": "expand_prepend_2D", + "test_name": "linear_3D_batched_input", + "in_features": 4, + "out_features": 2, "input": [ - -0.6017999053001404, - 0.8372399806976318, - -0.5020561218261719 + [ + [-0.3233233392238617, -0.3046680688858032, -0.22401957213878632, 0.2504769563674927], + [1.7058311700820923, 1.3944706916809082, 1.136904239654541, 1.1797000169754028], + [0.6420789957046509, -3.0800278186798096, -1.3616151809692383, -0.2960043251514435] + ], + [ + [1.1283513307571411, -0.7886322736740112, -0.038704462349414825, 0.6835862398147583], + [0.5444626212120056, 0.454408198595047, 0.9106372594833374, 0.9990993142127991], + [-0.27131080627441406, -0.9536606073379517, -0.6736571192741394, 1.259739637374878] + ] ], - "expand_shape": [ - 2, - 3 + "weight": [ + [0.13263213634490967, -0.20593488216400146, 0.0932854413986206, 0.43565016984939575], + [0.22836577892303467, 0.4893844723701477, -0.21178466081619263, -0.23876512050628662] ], + "bias": [-0.06348574161529541, -0.10069990158081055], "expected_output": [ [ - -0.6017999053001404, - 0.8372399806976318, - -0.5020561218261719 + [0.04459554702043533, -0.33599695563316345], + [0.49558526277542114, 0.44883573055267334], + [0.39998650550842285, -1.1023441553115845] + ], + [ + [0.5427707433700562, -0.3839870095252991], + [0.4353559911251068, -0.18539203703403473], + [0.5828850865364075, -0.7874763607978821] + ] + ], + "expected_grad_input": [ + [ + [0.36099791526794434, 0.28344959020614624, -0.11849921941757202, 0.19688504934310913], + [0.36099791526794434, 0.28344959020614624, -0.11849921941757202, 0.19688504934310913], + [0.36099791526794434, 0.28344959020614624, -0.11849921941757202, 0.19688504934310913] ], [ - -0.6017999053001404, - 0.8372399806976318, - -0.5020561218261719 + [0.36099791526794434, 0.28344959020614624, -0.11849921941757202, 0.19688504934310913], + [0.36099791526794434, 0.28344959020614624, -0.11849921941757202, 0.19688504934310913], + [0.36099791526794434, 0.28344959020614624, -0.11849921941757202, 0.19688504934310913] ] ], + "expected_grad_weight": [ + [3.4260900020599365, -3.2781100273132324, -0.250454843044281, 4.076597690582275], + [3.4260900020599365, -3.2781100273132324, -0.250454843044281, 4.076597690582275] + ], + "expected_grad_bias": [6.0, 6.0] + } + ], + "optimizers": [ + { + "test_name": "SGD_basic", + "optimizer": "SGD", + "kwargs": { + "lr": 0.1 + }, + "initial_weight": [ + [1.1711158752441406, -0.2590734362602234, -0.3033114969730377], + [0.2349793165922165, 1.0358152389526367, 0.715836763381958], + [-0.7037585973739624, -0.284278929233551, 0.7185912728309631] + ], + "input_x": [ + [1.8401010036468506, 0.04152654483914375, -1.7044862508773804], + [-0.3476502001285553, -0.3426065444946289, 0.11469119042158127], + [-0.4225151538848877, 0.7643097639083862, -0.5040589570999146] + ], + "expected_grad": [ + [1.8401010036468506, 0.04152654483914375, -1.7044862508773804], + [-0.3476502001285553, -0.3426065444946289, 0.11469119042158127], + [-0.4225151538848877, 0.7643097639083862, -0.5040589570999146] + ], + "expected_updated_weight": [ + [0.9871057868003845, -0.26322609186172485, -0.1328628659248352], + [0.269744336605072, 1.0700758695602417, 0.7043676376342773], + [-0.6615070700645447, -0.36070990562438965, 0.7689971923828125] + ] + }, + { + "test_name": "SGD_momentum", + "optimizer": "SGD", + "kwargs": { + "lr": 0.1, + "momentum": 0.9 + }, + "initial_weight": [ + [-0.9779782891273499, 1.0851811170578003, 0.24460527300834656], + [0.10595189034938812, 0.9393600821495056, 0.3916529417037964], + [0.4106380343437195, -0.0652524009346962, 0.5183061361312866] + ], + "input_x": [ + [0.05883641913533211, 0.5554778575897217, 1.053452968597412], + [-0.2609460651874542, -1.6987152099609375, -0.08697007596492767], + [2.333068609237671, -0.035302918404340744, 2.392319917678833] + ], + "expected_grad": [ + [0.05883641913533211, 0.5554778575897217, 1.053452968597412], + [-0.2609460651874542, -1.6987152099609375, -0.08697007596492767], + [2.333068609237671, -0.035302918404340744, 2.392319917678833] + ], + "expected_updated_weight": [ + [-0.9838619232177734, 1.0296332836151123, 0.13925997912883759], + [0.13204649090766907, 1.1092315912246704, 0.4003499448299408], + [0.17733116447925568, -0.061722107231616974, 0.27907413244247437] + ] + }, + { + "test_name": "Adam_basic", + "optimizer": "Adam", + "kwargs": { + "lr": 0.1 + }, + "initial_weight": [ + [0.861420214176178, 1.0063271522521973, 0.9432656168937683], + [0.22092591226100922, -1.1125500202178955, 0.1605069637298584], + [1.8549803495407104, -0.16434448957443237, -0.4784829616546631] + ], + "input_x": [ + [0.38463443517684937, -0.3245149850845337, -1.5829708576202393], + [-0.6101211309432983, 0.2677954137325287, 1.1987781524658203], + [1.122973918914795, 1.4562538862228394, 0.9092239141464233] + ], + "expected_grad": [ + [0.38463443517684937, -0.3245149850845337, -1.5829708576202393], + [-0.6101211309432983, 0.2677954137325287, 1.1987781524658203], + [1.122973918914795, 1.4562538862228394, 0.9092239141464233] + ], + "expected_updated_weight": [ + [0.7614202499389648, 1.1063271760940552, 1.0432655811309814], + [0.32092589139938354, -1.2125500440597534, 0.06050696223974228], + [1.7549803256988525, -0.2643444836139679, -0.578482985496521] + ] + }, + { + "test_name": "Adam_custom_betas", + "optimizer": "Adam", + "kwargs": { + "lr": 0.1, + "betas": [0.95, 0.999] + }, + "initial_weight": [ + [0.9442354440689087, 2.31821870803833, 0.64822918176651], + [-0.4594375491142273, 0.8558579683303833, 1.3270264863967896], + [0.9446682333946228, -0.30597713589668274, 0.44008857011795044] + ], + "input_x": [ + [-0.17014701664447784, 0.12107481062412262, 0.10815810412168503], + [0.5580024719238281, -1.8953827619552612, 0.12464731931686401], + [-0.3046552538871765, -0.7077358961105347, -1.7160437107086182] + ], "expected_grad": [ - 2.0, - 2.0, - 2.0 + [-0.17014701664447784, 0.12107481062412262, 0.10815810412168503], + [0.5580024719238281, -1.8953827619552612, 0.12464731931686401], + [-0.3046552538871765, -0.7077358961105347, -1.7160437107086182] + ], + "expected_updated_weight": [ + [1.0442354679107666, 2.2182188034057617, 0.5482292175292969], + [-0.5594375133514404, 0.9558579921722412, 1.2270264625549316], + [1.044668197631836, -0.20597714185714722, 0.5400885939598083] ] + } + ], + "expand": [ + { + "test_name": "expand_1D_expand", + "input": [-0.5965784788131714], + "expand_shape": [3], + "expected_output": [-0.5965784788131714, -0.5965784788131714, -0.5965784788131714], + "expected_grad": [3.0] + }, + { + "test_name": "expand_prepend_2D", + "input": [-0.6017999053001404, 0.8372399806976318, -0.5020561218261719], + "expand_shape": [2, 3], + "expected_output": [ + [-0.6017999053001404, 0.8372399806976318, -0.5020561218261719], + [-0.6017999053001404, 0.8372399806976318, -0.5020561218261719] + ], + "expected_grad": [2.0, 2.0, 2.0] }, { "test_name": "expand_expand_dim_0", "input": [ - [ - -0.10574329644441605, - -0.16421273350715637, - -0.7310932874679565 - ] - ], - "expand_shape": [ - 4, - 3 + [-0.10574329644441605, -0.16421273350715637, -0.7310932874679565] ], + "expand_shape": [4, 3], "expected_output": [ - [ - -0.10574329644441605, - -0.16421273350715637, - -0.7310932874679565 - ], - [ - -0.10574329644441605, - -0.16421273350715637, - -0.7310932874679565 - ], - [ - -0.10574329644441605, - -0.16421273350715637, - -0.7310932874679565 - ], - [ - -0.10574329644441605, - -0.16421273350715637, - -0.7310932874679565 - ] + [-0.10574329644441605, -0.16421273350715637, -0.7310932874679565], + [-0.10574329644441605, -0.16421273350715637, -0.7310932874679565], + [-0.10574329644441605, -0.16421273350715637, -0.7310932874679565], + [-0.10574329644441605, -0.16421273350715637, -0.7310932874679565] ], "expected_grad": [ - [ - 4.0, - 4.0, - 4.0 - ] + [4.0, 4.0, 4.0] ] }, { "test_name": "expand_expand_middle_dim", "input": [ [ - [ - 0.3742406666278839, - 0.07989589124917984, - 0.8226869702339172, - 0.528905987739563 - ] + [0.3742406666278839, 0.07989589124917984, 0.8226869702339172, 0.528905987739563] ], [ - [ - 0.3527827858924866, - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 - ] + [0.3527827858924866, -0.4038589298725128, 0.4434446096420288, -0.6249487400054932] ] ], - "expand_shape": [ - 2, - 5, - 4 - ], + "expand_shape": [2, 5, 4], "expected_output": [ [ - [ - 0.3742406666278839, - 0.07989589124917984, - 0.8226869702339172, - 0.528905987739563 - ], - [ - 0.3742406666278839, - 0.07989589124917984, - 0.8226869702339172, - 0.528905987739563 - ], - [ - 0.3742406666278839, - 0.07989589124917984, - 0.8226869702339172, - 0.528905987739563 - ], - [ - 0.3742406666278839, - 0.07989589124917984, - 0.8226869702339172, - 0.528905987739563 - ], - [ - 0.3742406666278839, - 0.07989589124917984, - 0.8226869702339172, - 0.528905987739563 - ] + [0.3742406666278839, 0.07989589124917984, 0.8226869702339172, 0.528905987739563], + [0.3742406666278839, 0.07989589124917984, 0.8226869702339172, 0.528905987739563], + [0.3742406666278839, 0.07989589124917984, 0.8226869702339172, 0.528905987739563], + [0.3742406666278839, 0.07989589124917984, 0.8226869702339172, 0.528905987739563], + [0.3742406666278839, 0.07989589124917984, 0.8226869702339172, 0.528905987739563] ], [ - [ - 0.3527827858924866, - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 - ], - [ - 0.3527827858924866, - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 - ], - [ - 0.3527827858924866, - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 - ], - [ - 0.3527827858924866, - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 - ], - [ - 0.3527827858924866, - -0.4038589298725128, - 0.4434446096420288, - -0.6249487400054932 - ] + [0.3527827858924866, -0.4038589298725128, 0.4434446096420288, -0.6249487400054932], + [0.3527827858924866, -0.4038589298725128, 0.4434446096420288, -0.6249487400054932], + [0.3527827858924866, -0.4038589298725128, 0.4434446096420288, -0.6249487400054932], + [0.3527827858924866, -0.4038589298725128, 0.4434446096420288, -0.6249487400054932], + [0.3527827858924866, -0.4038589298725128, 0.4434446096420288, -0.6249487400054932] ] ], "expected_grad": [ [ - [ - 5.0, - 5.0, - 5.0, - 5.0 - ] + [5.0, 5.0, 5.0, 5.0] ], [ - [ - 5.0, - 5.0, - 5.0, - 5.0 - ] + [5.0, 5.0, 5.0, 5.0] ] ] }, @@ -13738,75 +4113,29 @@ export const testData = { "test_name": "expand_preserve_with_negative_one", "input": [ [ - [ - -1.4255669116973877 - ], - [ - 0.8732106685638428 - ], - [ - -2.0518009662628174 - ] + [-1.4255669116973877], + [0.8732106685638428], + [-2.0518009662628174] ] ], - "expand_shape": [ - 2, - -1, - 4 - ], + "expand_shape": [2, -1, 4], "expected_output": [ [ - [ - -1.4255669116973877, - -1.4255669116973877, - -1.4255669116973877, - -1.4255669116973877 - ], - [ - 0.8732106685638428, - 0.8732106685638428, - 0.8732106685638428, - 0.8732106685638428 - ], - [ - -2.0518009662628174, - -2.0518009662628174, - -2.0518009662628174, - -2.0518009662628174 - ] + [-1.4255669116973877, -1.4255669116973877, -1.4255669116973877, -1.4255669116973877], + [0.8732106685638428, 0.8732106685638428, 0.8732106685638428, 0.8732106685638428], + [-2.0518009662628174, -2.0518009662628174, -2.0518009662628174, -2.0518009662628174] ], [ - [ - -1.4255669116973877, - -1.4255669116973877, - -1.4255669116973877, - -1.4255669116973877 - ], - [ - 0.8732106685638428, - 0.8732106685638428, - 0.8732106685638428, - 0.8732106685638428 - ], - [ - -2.0518009662628174, - -2.0518009662628174, - -2.0518009662628174, - -2.0518009662628174 - ] + [-1.4255669116973877, -1.4255669116973877, -1.4255669116973877, -1.4255669116973877], + [0.8732106685638428, 0.8732106685638428, 0.8732106685638428, 0.8732106685638428], + [-2.0518009662628174, -2.0518009662628174, -2.0518009662628174, -2.0518009662628174] ] ], "expected_grad": [ [ - [ - 8.0 - ], - [ - 8.0 - ], - [ - 8.0 - ] + [8.0], + [8.0], + [8.0] ] ] } @@ -13825,59 +4154,31 @@ export const testData = { "has_bias": true, "input": [ [ - [ - -0.9301124811172485, - -0.16888298094272614, - -0.7453446984291077, - -1.6509697437286377, - 0.06193928048014641 - ] + [-0.9301124811172485, -0.16888298094272614, -0.7453446984291077, -1.6509697437286377, 0.06193928048014641] ] ], "weight": [ [ - [ - -0.144717276096344, - 0.425019770860672, - -0.10819941759109497 - ] + [-0.144717276096344, 0.425019770860672, -0.10819941759109497] ] ], "expected_output": [ [ - [ - -0.2816556394100189, - -0.5388382077217102, - -1.0256586074829102 - ] + [-0.2816556394100189, -0.5388382077217102, -1.0256586074829102] ] ], "expected_grad_input": [ [ - [ - -0.144717276096344, - 0.280302494764328, - 0.17210307717323303, - 0.316820353269577, - -0.10819941759109497 - ] + [-0.144717276096344, 0.280302494764328, 0.17210307717323303, 0.316820353269577, -0.10819941759109497] ] ], "expected_grad_weight": [ [ - [ - -1.8443400859832764, - -2.565197467803955, - -2.3343751430511475 - ] + [-1.8443400859832764, -2.565197467803955, -2.3343751430511475] ] ], - "bias": [ - -0.42512625455856323 - ], - "expected_grad_bias": [ - 3.0 - ] + "bias": [-0.42512625455856323], + "expected_grad_bias": [3.0] }, { "test_name": "conv1d_stride_padding", @@ -13892,196 +4193,66 @@ export const testData = { "has_bias": true, "input": [ [ - [ - 0.5684458613395691, - 0.5110347270965576, - 0.9753285646438599, - 1.9773973226547241, - -1.2740811109542847, - -0.7873809337615967 - ], - [ - 2.1380560398101807, - 0.3426303565502167, - 0.6963862776756287, - -1.3928022384643555, - 0.9271320104598999, - 0.5793041586875916 - ] + [0.5684458613395691, 0.5110347270965576, 0.9753285646438599, 1.9773973226547241, -1.2740811109542847, -0.7873809337615967], + [2.1380560398101807, 0.3426303565502167, 0.6963862776756287, -1.3928022384643555, 0.9271320104598999, 0.5793041586875916] ], [ - [ - -0.9904320240020752, - 1.2730960845947266, - 0.5620912313461304, - -0.7692673802375793, - 0.3543089032173157, - -0.041875794529914856 - ], - [ - 0.5964854955673218, - 0.18470343947410583, - 0.4074154198169708, - -0.3804090619087219, - -0.09747593849897385, - -1.6269235610961914 - ] + [-0.9904320240020752, 1.2730960845947266, 0.5620912313461304, -0.7692673802375793, 0.3543089032173157, -0.041875794529914856], + [0.5964854955673218, 0.18470343947410583, 0.4074154198169708, -0.3804090619087219, -0.09747593849897385, -1.6269235610961914] ] ], "weight": [ [ - [ - -0.0565146803855896, - 0.19237661361694336 - ], - [ - -0.3971105217933655, - 0.2664335370063782 - ] + [-0.0565146803855896, 0.19237661361694336], + [-0.3971105217933655, 0.2664335370063782] ], [ - [ - 0.4777756929397583, - 0.2603725790977478 - ], - [ - -0.19769030809402466, - 0.40765953063964844 - ] + [0.4777756929397583, 0.2603725790977478], + [-0.19769030809402466, 0.40765953063964844] ], [ - [ - -0.4735388159751892, - -0.05999833345413208 - ], - [ - -0.12388789653778076, - -0.4987332224845886 - ] + [-0.4735388159751892, -0.05999833345413208], + [-0.12388789653778076, -0.4987332224845886] ] ], "expected_output": [ [ - [ - 0.3937676250934601, - -0.0770099014043808, - 0.1580221951007843, - -0.4707871079444885 - ], - [ - 0.6553137302398682, - 0.34996968507766724, - 0.9020213484764099, - -0.8550072312355042 - ], - [ - -0.9660398960113525, - -0.5558861494064331, - -1.0153863430023193, - 0.43547213077545166 - ] + [0.3937676250934601, -0.0770099014043808, 0.1580221951007843, -0.4707871079444885], + [0.6553137302398682, 0.34996968507766724, 0.9020213484764099, -0.8550072312355042], + [-0.9660398960113525, -0.5558861494064331, -1.0153863430023193, 0.43547213077545166] ], [ - [ - -0.31685012578964233, - -0.21385188400745392, - -0.04850868135690689, - 0.3631971478462219 - ], - [ - -0.37901127338409424, - 0.5198872685432434, - -0.6041116714477539, - -0.06267312169075012 - ], - [ - -0.10367739945650101, - -0.7282735705375671, - 0.5731480717658997, - 0.35577142238616943 - ] + [-0.31685012578964233, -0.21385188400745392, -0.04850868135690689, 0.3631971478462219], + [-0.37901127338409424, 0.5198872685432434, -0.6041116714477539, -0.06267312169075012], + [-0.10367739945650101, -0.7282735705375671, 0.5731480717658997, 0.35577142238616943] ] ], "expected_grad_input": [ [ - [ - 0.3927508592605591, - -0.05227780342102051, - 0.3927508592605591, - -0.05227780342102051, - 0.3927508592605591, - -0.05227780342102051 - ], - [ - 0.175359845161438, - -0.7186887264251709, - 0.175359845161438, - -0.7186887264251709, - 0.175359845161438, - -0.7186887264251709 - ] + [0.3927508592605591, -0.05227780342102051, 0.3927508592605591, -0.05227780342102051, 0.3927508592605591, -0.05227780342102051], + [0.175359845161438, -0.7186887264251709, 0.175359845161438, -0.7186887264251709, 0.175359845161438, -0.7186887264251709] ], [ - [ - 0.3927508592605591, - -0.05227780342102051, - 0.3927508592605591, - -0.05227780342102051, - 0.3927508592605591, - -0.05227780342102051 - ], - [ - 0.175359845161438, - -0.7186887264251709, - 0.175359845161438, - -0.7186887264251709, - 0.175359845161438, - -0.7186887264251709 - ] + [0.3927508592605591, -0.05227780342102051, 0.3927508592605591, -0.05227780342102051, 0.3927508592605591, -0.05227780342102051], + [0.175359845161438, -0.7186887264251709, 0.175359845161438, -0.7186887264251709, 0.175359845161438, -0.7186887264251709] ] ], "expected_grad_weight": [ [ - [ - 2.163003921508789, - 0.19566136598587036 - ], - [ - -2.29349684715271, - 4.667999267578125 - ] + [2.163003921508789, 0.19566136598587036], + [-2.29349684715271, 4.667999267578125] ], [ - [ - 2.163003921508789, - 0.19566136598587036 - ], - [ - -2.29349684715271, - 4.667999267578125 - ] + [2.163003921508789, 0.19566136598587036], + [-2.29349684715271, 4.667999267578125] ], [ - [ - 2.163003921508789, - 0.19566136598587036 - ], - [ - -2.29349684715271, - 4.667999267578125 - ] + [2.163003921508789, 0.19566136598587036], + [-2.29349684715271, 4.667999267578125] ] ], - "bias": [ - -0.2852379083633423, - -0.3642929196357727, - 0.13438546657562256 - ], - "expected_grad_bias": [ - 8.0, - 8.0, - 8.0 - ] + "bias": [-0.2852379083633423, -0.3642929196357727, 0.13438546657562256], + "expected_grad_bias": [8.0, 8.0, 8.0] }, { "test_name": "conv1d_dilation_no_bias", @@ -14096,96 +4267,40 @@ export const testData = { "has_bias": false, "input": [ [ - [ - -0.5552166700363159, - 2.030524492263794, - 1.191868543624878, - -0.06635937094688416, - 0.1066870242357254 - ], - [ - -0.5176211595535278, - 0.5926820039749146, - -0.25894099473953247, - 0.2768661379814148, - -1.449656367301941 - ] + [-0.5552166700363159, 2.030524492263794, 1.191868543624878, -0.06635937094688416, 0.1066870242357254], + [-0.5176211595535278, 0.5926820039749146, -0.25894099473953247, 0.2768661379814148, -1.449656367301941] ] ], "weight": [ [ - [ - 0.3875494599342346, - -0.2733243703842163 - ], - [ - 0.28149646520614624, - 0.30508261919021606 - ] + [0.3875494599342346, -0.2733243703842163], + [0.28149646520614624, 0.30508261919021606] ], [ - [ - -0.47784996032714844, - -0.3831656575202942 - ], - [ - 0.21601104736328125, - 0.046203017234802246 - ] + [-0.47784996032714844, -0.3831656575202942], + [0.21601104736328125, 0.046203017234802246] ] ], "expected_output": [ [ - [ - -0.7656475305557251, - 1.0563712120056152, - -0.08240810036659241 - ], - [ - -0.31514859199523926, - -0.8040415644645691, - -0.7333257794380188 - ] + [-0.7656475305557251, 1.0563712120056152, -0.08240810036659241], + [-0.31514859199523926, -0.8040415644645691, -0.7333257794380188] ] ], "expected_grad_input": [ [ - [ - -0.09030050039291382, - -0.09030050039291382, - -0.7467905282974243, - -0.6564900279045105, - -0.6564900279045105 - ], - [ - 0.4975075125694275, - 0.4975075125694275, - 0.8487931489944458, - 0.3512856364250183, - 0.3512856364250183 - ] + [-0.09030050039291382, -0.09030050039291382, -0.7467905282974243, -0.6564900279045105, -0.6564900279045105], + [0.4975075125694275, 0.4975075125694275, 0.8487931489944458, 0.3512856364250183, 0.3512856364250183] ] ], "expected_grad_weight": [ [ - [ - 2.6671762466430664, - 1.2321962118148804 - ], - [ - -0.18388015031814575, - -1.4317312240600586 - ] + [2.6671762466430664, 1.2321962118148804], + [-0.18388015031814575, -1.4317312240600586] ], [ - [ - 2.6671762466430664, - 1.2321962118148804 - ], - [ - -0.18388015031814575, - -1.4317312240600586 - ] + [2.6671762466430664, 1.2321962118148804], + [-0.18388015031814575, -1.4317312240600586] ] ], "bias": null, @@ -14204,224 +4319,66 @@ export const testData = { "has_bias": true, "input": [ [ - [ - -0.3783835768699646, - 0.23239530622959137, - -0.7321792840957642, - -0.40373992919921875, - 1.2062691450119019, - -0.6938396096229553 - ], - [ - -1.5164529085159302, - 2.0242106914520264, - -0.1935255229473114, - 1.383492350578308, - -0.2420232743024826, - -0.30263814330101013 - ], - [ - 0.1517062932252884, - 1.0345447063446045, - -0.9610977172851562, - -1.2026211023330688, - 1.1932176351547241, - -0.8363521695137024 - ], - [ - 0.07792648673057556, - 0.6653022766113281, - -1.825669527053833, - 0.6015728712081909, - 0.6289637684822083, - -0.39405086636543274 - ] + [-0.3783835768699646, 0.23239530622959137, -0.7321792840957642, -0.40373992919921875, 1.2062691450119019, -0.6938396096229553], + [-1.5164529085159302, 2.0242106914520264, -0.1935255229473114, 1.383492350578308, -0.2420232743024826, -0.30263814330101013], + [0.1517062932252884, 1.0345447063446045, -0.9610977172851562, -1.2026211023330688, 1.1932176351547241, -0.8363521695137024], + [0.07792648673057556, 0.6653022766113281, -1.825669527053833, 0.6015728712081909, 0.6289637684822083, -0.39405086636543274] ] ], "weight": [ [ - [ - 0.06892253458499908, - -0.380085289478302, - 0.36482012271881104 - ], - [ - -0.2025740146636963, - 0.35292473435401917, - -0.1281263679265976 - ] + [0.06892253458499908, -0.380085289478302, 0.36482012271881104], + [-0.2025740146636963, 0.35292473435401917, -0.1281263679265976] ], [ - [ - 0.3980580270290375, - 0.12043391168117523, - -0.019721616059541702 - ], - [ - 0.1558418720960617, - -0.012695319950580597, - -0.20248451828956604 - ] + [0.3980580270290375, 0.12043391168117523, -0.019721616059541702], + [0.1558418720960617, -0.012695319950580597, -0.20248451828956604] ], [ - [ - 0.2233155369758606, - 0.2647979259490967, - -0.05114482343196869 - ], - [ - 0.38400641083717346, - 0.025926170870661736, - -0.21590395271778107 - ] + [0.2233155369758606, 0.2647979259490967, -0.05114482343196869], + [0.38400641083717346, 0.025926170870661736, -0.21590395271778107] ], [ - [ - -0.2224746197462082, - 0.27468135952949524, - -0.16537627577781677 - ], - [ - 0.25785261392593384, - -0.39656978845596313, - 0.01406295970082283 - ] + [-0.2224746197462082, 0.27468135952949524, -0.16537627577781677], + [0.25785261392593384, -0.39656978845596313, 0.01406295970082283] ] ], "expected_output": [ [ - [ - -0.848025381565094, - 0.3827834129333496, - -0.7906762361526489, - 0.8194673657417297, - -1.3484156131744385, - 0.006999105215072632 - ], - [ - -0.2959577143192291, - -0.18621432781219482, - 0.1948830783367157, - -0.21776551008224487, - 0.42302078008651733, - 0.5075432062149048 - ], - [ - 0.17718645930290222, - 1.129868745803833, - 0.4478544592857361, - -1.083827018737793, - 0.7541118860244751, - 0.6078572273254395 - ], - [ - 0.009685128927230835, - 0.30059313774108887, - 0.7693951725959778, - -0.8536713719367981, - 0.7944182753562927, - -0.016091808676719666 - ] + [-0.848025381565094, 0.3827834129333496, -0.7906762361526489, 0.8194673657417297, -1.3484156131744385, 0.006999105215072632], + [-0.2959577143192291, -0.18621432781219482, 0.1948830783367157, -0.21776551008224487, 0.42302078008651733, 0.5075432062149048], + [0.17718645930290222, 1.129868745803833, 0.4478544592857361, -1.083827018737793, 0.7541118860244751, 0.6078572273254395], + [0.009685128927230835, 0.30059313774108887, 0.7693951725959778, -0.8536713719367981, 0.7944182753562927, -0.016091808676719666] ] ], "expected_grad_input": [ [ - [ - 0.20732921361923218, - 0.5524277091026306, - 0.5524277091026306, - 0.5524277091026306, - 0.5524277091026306, - 0.08544713258743286 - ], - [ - 0.2934972643852234, - -0.03711360692977905, - -0.03711360692977905, - -0.03711360692977905, - -0.03711360692977905, - 0.009618550539016724 - ], - [ - 0.5403201580047607, - 0.3237990736961365, - 0.3237990736961365, - 0.3237990736961365, - 0.3237990736961365, - 0.32295817136764526 - ], - [ - 0.27121543884277344, - 0.0693744421005249, - 0.0693744421005249, - 0.0693744421005249, - 0.0693744421005249, - -0.5724846124649048 - ] + [0.20732921361923218, 0.5524277091026306, 0.5524277091026306, 0.5524277091026306, 0.5524277091026306, 0.08544713258743286], + [0.2934972643852234, -0.03711360692977905, -0.03711360692977905, -0.03711360692977905, -0.03711360692977905, 0.009618550539016724], + [0.5403201580047607, 0.3237990736961365, 0.3237990736961365, 0.3237990736961365, 0.3237990736961365, 0.32295817136764526], + [0.27121543884277344, 0.0693744421005249, 0.0693744421005249, 0.0693744421005249, 0.0693744421005249, -0.5724846124649048] ] ], "expected_grad_weight": [ [ - [ - -0.07563827931880951, - -0.769477903842926, - -0.3910943865776062 - ], - [ - 1.455701231956482, - 1.153063178062439, - 2.669516086578369 - ] + [-0.07563827931880951, -0.769477903842926, -0.3910943865776062], + [1.455701231956482, 1.153063178062439, 2.669516086578369] ], [ - [ - -0.07563827931880951, - -0.769477903842926, - -0.3910943865776062 - ], - [ - 1.455701231956482, - 1.153063178062439, - 2.669516086578369 - ] + [-0.07563827931880951, -0.769477903842926, -0.3910943865776062], + [1.455701231956482, 1.153063178062439, 2.669516086578369] ], [ - [ - 0.2157498002052307, - -0.6206024289131165, - -0.7723087072372437 - ], - [ - 0.148095965385437, - -0.24595487117767334, - -0.32388150691986084 - ] + [0.2157498002052307, -0.6206024289131165, -0.7723087072372437], + [0.148095965385437, -0.24595487117767334, -0.32388150691986084] ], [ - [ - 0.2157498002052307, - -0.6206024289131165, - -0.7723087072372437 - ], - [ - 0.148095965385437, - -0.24595487117767334, - -0.32388150691986084 - ] + [0.2157498002052307, -0.6206024289131165, -0.7723087072372437], + [0.148095965385437, -0.24595487117767334, -0.32388150691986084] ] ], - "bias": [ - -0.2820773720741272, - 0.14481520652770996, - 0.3315476179122925, - 0.1606505662202835 - ], - "expected_grad_bias": [ - 6.0, - 6.0, - 6.0, - 6.0 - ] + "bias": [-0.2820773720741272, 0.14481520652770996, 0.3315476179122925, 0.1606505662202835], + "expected_grad_bias": [6.0, 6.0, 6.0, 6.0] }, { "test_name": "conv2d_basic", @@ -14437,154 +4394,54 @@ export const testData = { "input": [ [ [ - [ - -1.467360258102417, - 1.7191014289855957, - -0.3673190176486969, - 2.3575830459594727, - -0.459722101688385 - ], - [ - -0.058640673756599426, - 1.1636638641357422, - 0.5507457852363586, - -2.0428922176361084, - 1.0865724086761475 - ], - [ - -0.172266885638237, - 0.5808969140052795, - 0.053119998425245285, - 0.6127946376800537, - 0.6289454698562622 - ], - [ - -0.0685209259390831, - -1.2115036249160767, - 1.2690211534500122, - -0.5605306625366211, - -2.0018928050994873 - ], - [ - 0.8131555318832397, - 1.2148545980453491, - 0.9846591353416443, - 1.6213051080703735, - 0.5066256523132324 - ] + [-1.467360258102417, 1.7191014289855957, -0.3673190176486969, 2.3575830459594727, -0.459722101688385], + [-0.058640673756599426, 1.1636638641357422, 0.5507457852363586, -2.0428922176361084, 1.0865724086761475], + [-0.172266885638237, 0.5808969140052795, 0.053119998425245285, 0.6127946376800537, 0.6289454698562622], + [-0.0685209259390831, -1.2115036249160767, 1.2690211534500122, -0.5605306625366211, -2.0018928050994873], + [0.8131555318832397, 1.2148545980453491, 0.9846591353416443, 1.6213051080703735, 0.5066256523132324] ] ] ], "weight": [ [ [ - [ - -0.10344748198986053, - 0.18141815066337585, - -0.28466638922691345 - ], - [ - -0.09609787166118622, - -0.14009928703308105, - 0.30844438076019287 - ], - [ - 0.13302838802337646, - -0.2486542910337448, - 0.12918822467327118 - ] + [-0.10344748198986053, 0.18141815066337585, -0.28466638922691345], + [-0.09609787166118622, -0.14009928703308105, 0.30844438076019287], + [0.13302838802337646, -0.2486542910337448, 0.12918822467327118] ] ] ], "expected_output": [ [ [ - [ - 0.4131501019001007, - -1.5985389947891235, - 1.093879222869873 - ], - [ - 0.4609568417072296, - 0.13063298165798187, - -0.5913594961166382 - ], - [ - 0.6020535826683044, - -0.34000104665756226, - -0.9480313062667847 - ] + [0.4131501019001007, -1.5985389947891235, 1.093879222869873], + [0.4609568417072296, 0.13063298165798187, -0.5913594961166382], + [0.6020535826683044, -0.34000104665756226, -0.9480313062667847] ] ] ], "expected_grad_input": [ [ [ - [ - -0.10344748198986053, - 0.07797066867351532, - -0.20669572055339813, - -0.1032482385635376, - -0.28466638922691345 - ], - [ - -0.19954535365104675, - -0.15822649002075195, - -0.13444849848747253, - 0.06509685516357422, - 0.02377799153327942 - ], - [ - -0.06651696562767029, - -0.2738524079322815, - -0.12088616192340851, - -0.054369211196899414, - 0.1529662162065506 - ], - [ - 0.03693051636219025, - -0.3518230617046356, - 0.08580954372882843, - 0.048879027366638184, - 0.43763262033462524 - ], - [ - 0.13302838802337646, - -0.11562590301036835, - 0.013562321662902832, - -0.11946606636047363, - 0.12918822467327118 - ] + [-0.10344748198986053, 0.07797066867351532, -0.20669572055339813, -0.1032482385635376, -0.28466638922691345], + [-0.19954535365104675, -0.15822649002075195, -0.13444849848747253, 0.06509685516357422, 0.02377799153327942], + [-0.06651696562767029, -0.2738524079322815, -0.12088616192340851, -0.054369211196899414, 0.1529662162065506], + [0.03693051636219025, -0.3518230617046356, 0.08580954372882843, 0.048879027366638184, 0.43763262033462524], + [0.13302838802337646, -0.11562590301036835, 0.013562321662902832, -0.11946606636047363, 0.12918822467327118] ] ] ], "expected_grad_weight": [ [ [ - [ - 2.001941204071045, - 4.627694606781006, - 2.419827938079834 - ], - [ - 2.106515884399414, - 0.41531574726104736, - -0.4041163921356201 - ], - [ - 3.4634158611297607, - 4.564617156982422, - 3.1140480041503906 - ] + [2.001941204071045, 4.627694606781006, 2.419827938079834], + [2.106515884399414, 0.41531574726104736, -0.4041163921356201], + [3.4634158611297607, 4.564617156982422, 3.1140480041503906] ] ] ], - "bias": [ - -0.007069031707942486 - ], - "expected_grad_bias": [ - 9.0 - ] + "bias": [-0.007069031707942486], + "expected_grad_bias": [9.0] }, { "test_name": "conv2d_stride_padding", @@ -14600,723 +4457,187 @@ export const testData = { "input": [ [ [ - [ - -0.8043005466461182, - -0.28731220960617065, - 1.8125576972961426, - -0.2427283376455307, - -0.49898141622543335, - -0.9646658897399902 - ], - [ - 1.1177937984466553, - -2.260744571685791, - 0.731488823890686, - -0.4989534318447113, - 0.7293177843093872, - 0.1701146513223648 - ], - [ - 0.739496648311615, - -1.1954078674316406, - 2.1079015731811523, - -1.823443055152893, - -0.15365807712078094, - 1.032126545906067 - ], - [ - 0.36852389574050903, - 2.4601800441741943, - 0.13030865788459778, - -0.9205528497695923, - 1.5234228372573853, - 1.3897676467895508 - ], - [ - -1.6782877445220947, - 1.8284801244735718, - -0.968523383140564, - 0.4811331629753113, - 0.19745779037475586, - 0.1997281163930893 - ], - [ - 0.13673236966133118, - 0.21775121986865997, - 0.3381371796131134, - 1.025931715965271, - -0.6230042576789856, - -0.6034882664680481 - ] + [-0.8043005466461182, -0.28731220960617065, 1.8125576972961426, -0.2427283376455307, -0.49898141622543335, -0.9646658897399902], + [1.1177937984466553, -2.260744571685791, 0.731488823890686, -0.4989534318447113, 0.7293177843093872, 0.1701146513223648], + [0.739496648311615, -1.1954078674316406, 2.1079015731811523, -1.823443055152893, -0.15365807712078094, 1.032126545906067], + [0.36852389574050903, 2.4601800441741943, 0.13030865788459778, -0.9205528497695923, 1.5234228372573853, 1.3897676467895508], + [-1.6782877445220947, 1.8284801244735718, -0.968523383140564, 0.4811331629753113, 0.19745779037475586, 0.1997281163930893], + [0.13673236966133118, 0.21775121986865997, 0.3381371796131134, 1.025931715965271, -0.6230042576789856, -0.6034882664680481] ], - [ - [ - 1.0356813669204712, - -0.316057026386261, - -0.21146954596042633, - 0.3081285357475281, - 0.03471093624830246, - -1.8955014944076538 - ], - [ - 1.2220596075057983, - 0.6842809319496155, - 0.482809454202652, - -0.1810940057039261, - 0.10777772217988968, - 0.4828875958919525 - ], - [ - 1.6506794691085815, - 0.7990935444831848, - 0.25144144892692566, - 0.5849565863609314, - 1.04137122631073, - -0.6260819435119629 - ], - [ - 1.1246347427368164, - 0.8956797122955322, - -0.8433935046195984, - -2.1094107627868652, - 0.4968266487121582, - 1.6480950117111206 - ], - [ - 0.03010670095682144, - -0.9876852631568909, - 1.1092876195907593, - 0.49909794330596924, - -0.2840602993965149, - -0.10638472437858582 - ], - [ - 0.2790530323982239, - -2.164227247238159, - 0.7445889115333557, - -2.1047589778900146, - 0.7448800802230835, - -0.7210500240325928 - ] + [ + [1.0356813669204712, -0.316057026386261, -0.21146954596042633, 0.3081285357475281, 0.03471093624830246, -1.8955014944076538], + [1.2220596075057983, 0.6842809319496155, 0.482809454202652, -0.1810940057039261, 0.10777772217988968, 0.4828875958919525], + [1.6506794691085815, 0.7990935444831848, 0.25144144892692566, 0.5849565863609314, 1.04137122631073, -0.6260819435119629], + [1.1246347427368164, 0.8956797122955322, -0.8433935046195984, -2.1094107627868652, 0.4968266487121582, 1.6480950117111206], + [0.03010670095682144, -0.9876852631568909, 1.1092876195907593, 0.49909794330596924, -0.2840602993965149, -0.10638472437858582], + [0.2790530323982239, -2.164227247238159, 0.7445889115333557, -2.1047589778900146, 0.7448800802230835, -0.7210500240325928] ] ], [ [ - [ - 0.5612776279449463, - -0.006535662803798914, - 0.34217989444732666, - -1.073784351348877, - 1.5708034038543701, - -1.1401112079620361 - ], - [ - -0.2012692391872406, - -0.4230685234069824, - -0.7898051142692566, - -0.5088178515434265, - -0.9016579985618591, - 0.6364835500717163 - ], - [ - 0.7696021795272827, - 0.582319974899292, - 0.2216803878545761, - -0.1759732961654663, - 1.837676763534546, - -0.2276618480682373 - ], - [ - 0.556129515171051, - 0.1394495666027069, - -0.7639250159263611, - -0.6143314838409424, - 0.6616799235343933, - -0.05819060653448105 - ], - [ - 0.926749587059021, - -0.16234397888183594, - -0.18278858065605164, - 1.7139904499053955, - -1.0269054174423218, - 0.5982120633125305 - ], - [ - 0.8188145160675049, - -1.2973971366882324, - -1.6458345651626587, - 0.15697401762008667, - 0.29413074254989624, - 0.2593991756439209 - ] + [0.5612776279449463, -0.006535662803798914, 0.34217989444732666, -1.073784351348877, 1.5708034038543701, -1.1401112079620361], + [-0.2012692391872406, -0.4230685234069824, -0.7898051142692566, -0.5088178515434265, -0.9016579985618591, 0.6364835500717163], + [0.7696021795272827, 0.582319974899292, 0.2216803878545761, -0.1759732961654663, 1.837676763534546, -0.2276618480682373], + [0.556129515171051, 0.1394495666027069, -0.7639250159263611, -0.6143314838409424, 0.6616799235343933, -0.05819060653448105], + [0.926749587059021, -0.16234397888183594, -0.18278858065605164, 1.7139904499053955, -1.0269054174423218, 0.5982120633125305], + [0.8188145160675049, -1.2973971366882324, -1.6458345651626587, 0.15697401762008667, 0.29413074254989624, 0.2593991756439209] ], [ - [ - 0.5408645272254944, - -1.3398406505584717, - 0.14272356033325195, - 0.3211787939071655, - -1.402301549911499, - -0.8660640120506287 - ], - [ - -0.8508381843566895, - 0.1697680652141571, - 0.3121674954891205, - 1.2302255630493164, - 0.12507683038711548, - 1.026518702507019 - ], - [ - 1.4250038862228394, - 0.3661484718322754, - 0.18309427797794342, - -0.9111728668212891, - 0.7800946235656738, - 0.3574816882610321 - ], - [ - 0.14799346029758453, - 1.138214111328125, - -0.7696079015731812, - -1.0346392393112183, - -0.42179074883461, - -0.14516009390354156 - ], - [ - -0.3307901918888092, - 0.752140462398529, - -1.1388487815856934, - 0.601990818977356, - -0.025565603747963905, - -1.8534711599349976 - ], - [ - 0.2496940791606903, - -0.663693368434906, - -0.29064902663230896, - -0.08062736690044403, - 0.18424205482006073, - -0.26781368255615234 - ] + [0.5408645272254944, -1.3398406505584717, 0.14272356033325195, 0.3211787939071655, -1.402301549911499, -0.8660640120506287], + [-0.8508381843566895, 0.1697680652141571, 0.3121674954891205, 1.2302255630493164, 0.12507683038711548, 1.026518702507019], + [1.4250038862228394, 0.3661484718322754, 0.18309427797794342, -0.9111728668212891, 0.7800946235656738, 0.3574816882610321], + [0.14799346029758453, 1.138214111328125, -0.7696079015731812, -1.0346392393112183, -0.42179074883461, -0.14516009390354156], + [-0.3307901918888092, 0.752140462398529, -1.1388487815856934, 0.601990818977356, -0.025565603747963905, -1.8534711599349976], + [0.2496940791606903, -0.663693368434906, -0.29064902663230896, -0.08062736690044403, 0.18424205482006073, -0.26781368255615234] ] ] ], "weight": [ [ [ - [ - 0.02643534541130066, - -0.002493660431355238 - ], - [ - -0.09351104497909546, - 0.21940048038959503 - ] + [0.02643534541130066, -0.002493660431355238], + [-0.09351104497909546, 0.21940048038959503] ], [ - [ - 0.018684372305870056, - -0.20529168844223022 - ], - [ - -0.09356790035963058, - -0.2078663557767868 - ] + [0.018684372305870056, -0.20529168844223022], + [-0.09356790035963058, -0.2078663557767868] ] ], [ [ - [ - -0.12472891807556152, - -0.33350855112075806 - ], - [ - 0.06177648901939392, - -0.2739461660385132 - ] + [-0.12472891807556152, -0.33350855112075806], + [0.06177648901939392, -0.2739461660385132] ], [ - [ - 0.1367422491312027, - 0.2421981245279312 - ], - [ - -0.2630181312561035, - -0.18658122420310974 - ] + [0.1367422491312027, 0.2421981245279312], + [-0.2630181312561035, -0.18658122420310974] ] ], [ [ - [ - -0.2793554663658142, - 0.09435301274061203 - ], - [ - 0.06841082125902176, - -0.18248572945594788 - ] + [-0.2793554663658142, 0.09435301274061203], + [0.06841082125902176, -0.18248572945594788] ], [ - [ - 0.21357481181621552, - 0.14670585095882416 - ], - [ - -0.3194490969181061, - -0.0192315224558115 - ] + [0.21357481181621552, 0.14670585095882416], + [-0.3194490969181061, -0.0192315224558115] ] ] ], "expected_output": [ [ [ - [ - -0.5439481735229492, - 0.345872163772583, - -0.2750261127948761, - 0.11536405980587006 - ], - [ - -0.5867418646812439, - 0.1471027433872223, - -0.3271189033985138, - -0.17661553621292114 - ], - [ - -0.7584733963012695, - -0.41925880312919617, - -0.31106430292129517, - -0.09339094161987305 - ], - [ - -0.209829181432724, - -0.3405829668045044, - -0.31577032804489136, - -0.18162673711776733 - ] + [-0.5439481735229492, 0.345872163772583, -0.2750261127948761, 0.11536405980587006], + [-0.5867418646812439, 0.1471027433872223, -0.3271189033985138, -0.17661553621292114], + [-0.7584733963012695, -0.41925880312919617, -0.31106430292129517, -0.09339094161987305], + [-0.209829181432724, -0.3405829668045044, -0.31577032804489136, -0.18162673711776733] ], [ - [ - -0.034206323325634, - -0.45301008224487305, - -0.027123337611556053, - 0.37765491008758545 - ], - [ - -0.6486839652061462, - -0.7211645841598511, - -0.6596684455871582, - 0.21194230020046234 - ], - [ - 0.5423190593719482, - -0.06232115626335144, - -0.7253143787384033, - 0.031036945059895515 - ], - [ - -0.03931796923279762, - -0.31683745980262756, - -0.0888896957039833, - -0.08462823927402496 - ] + [-0.034206323325634, -0.45301008224487305, -0.027123337611556053, 0.37765491008758545], + [-0.6486839652061462, -0.7211645841598511, -0.6596684455871582, 0.21194230020046234], + [0.5423190593719482, -0.06232115626335144, -0.7253143787384033, 0.031036945059895515], + [-0.03931796923279762, -0.31683745980262756, -0.0888896957039833, -0.08462823927402496] ], [ - [ - 0.32371586561203003, - -0.048529937863349915, - 0.17221303284168243, - 0.7363828420639038 - ], - [ - 0.31491804122924805, - 0.3878597319126129, - 0.07859956473112106, - 0.5230802893638611 - ], - [ - 0.7023065686225891, - 0.1854657530784607, - 0.06303960084915161, - 0.2082606554031372 - ], - [ - 0.2507000267505646, - -0.18505442142486572, - -0.48876702785491943, - 0.21144984662532806 - ] + [0.32371586561203003, -0.048529937863349915, 0.17221303284168243, 0.7363828420639038], + [0.31491804122924805, 0.3878597319126129, 0.07859956473112106, 0.5230802893638611], + [0.7023065686225891, 0.1854657530784607, 0.06303960084915161, 0.2082606554031372], + [0.2507000267505646, -0.18505442142486572, -0.48876702785491943, 0.21144984662532806] ] ], [ [ - [ - -0.14148390293121338, - 0.019183289259672165, - 0.5542840361595154, - 0.03544783219695091 - ], - [ - -0.10438832640647888, - -0.3004642426967621, - 0.17664918303489685, - -0.12835535407066345 - ], - [ - 0.08811988681554794, - 0.17408053576946259, - -0.5394258499145508, - -0.03896549344062805 - ], - [ - -0.20550291240215302, - -0.13512679934501648, - -0.18811459839344025, - -0.15034757554531097 - ] + [-0.14148390293121338, 0.019183289259672165, 0.5542840361595154, 0.03544783219695091], + [-0.10438832640647888, -0.3004642426967621, 0.17664918303489685, -0.12835535407066345], + [0.08811988681554794, 0.17408053576946259, -0.5394258499145508, -0.03896549344062805], + [-0.20550291240215302, -0.13512679934501648, -0.18811459839344025, -0.15034757554531097] ], [ - [ - -0.31597769260406494, - 0.1703275591135025, - -0.3807855546474457, - 0.09605579078197479 - ], - [ - -0.6769576072692871, - 0.19847336411476135, - 0.08119788765907288, - -0.10841041803359985 - ], - [ - -0.4030931293964386, - 0.20003023743629456, - -0.2153528332710266, - 0.4505578279495239 - ], - [ - -0.2739088833332062, - 0.4882705807685852, - -0.14537908136844635, - -0.13027870655059814 - ] + [-0.31597769260406494, 0.1703275591135025, -0.3807855546474457, 0.09605579078197479], + [-0.6769576072692871, 0.19847336411476135, 0.08119788765907288, -0.10841041803359985], + [-0.4030931293964386, 0.20003023743629456, -0.2153528332710266, 0.4505578279495239], + [-0.2739088833332062, 0.4882705807685852, -0.14537908136844635, -0.13027870655059814] ], [ - [ - 0.08403339982032776, - 0.5592362284660339, - -0.23887935280799866, - 0.3955276310443878 - ], - [ - -0.11479949206113815, - 0.20147770643234253, - 0.46370449662208557, - 0.10852185636758804 - ], - [ - 0.10828724503517151, - 0.019894912838935852, - 0.260893851518631, - 0.815127432346344 - ], - [ - 0.3107494115829468, - 0.21961763501167297, - 0.1905701756477356, - 0.06719737499952316 - ] + [0.08403339982032776, 0.5592362284660339, -0.23887935280799866, 0.3955276310443878], + [-0.11479949206113815, 0.20147770643234253, 0.46370449662208557, 0.10852185636758804], + [0.10828724503517151, 0.019894912838935852, 0.260893851518631, 0.815127432346344], + [0.3107494115829468, 0.21961763501167297, 0.1905701756477356, 0.06719737499952316] ] ] ], "expected_grad_input": [ [ [ - [ - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022 - ], - [ - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751 - ], - [ - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022 - ], - [ - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751 - ], - [ - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022 - ], - [ - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751 - ] + [-0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022], + [-0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751], + [-0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022], + [-0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751], + [-0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022], + [-0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751] ], [ - [ - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432 - ], - [ - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946 - ], - [ - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432 - ], - [ - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946 - ], - [ - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432 - ], - [ - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946 - ] + [-0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432], + [0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946], + [-0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432], + [0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946], + [-0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432], + [0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946] ] ], [ [ - [ - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022 - ], - [ - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751 - ], - [ - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022 - ], - [ - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751 - ], - [ - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022, - -0.23703141510486603, - 0.03667626529932022 - ], - [ - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751, - -0.24164918065071106, - -0.3776490390300751 - ] + [-0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022], + [-0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751], + [-0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022], + [-0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751], + [-0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022, -0.23703141510486603, 0.03667626529932022], + [-0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751, -0.24164918065071106, -0.3776490390300751] ], [ - [ - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432 - ], - [ - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946 - ], - [ - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432 - ], - [ - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946 - ], - [ - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432, - -0.4136790931224823, - -0.6760351657867432 - ], - [ - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946, - 0.18361228704452515, - 0.36900144815444946 - ] + [-0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432], + [0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946], + [-0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432], + [0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946], + [-0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432, -0.4136790931224823, -0.6760351657867432], + [0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946, 0.18361228704452515, 0.36900144815444946] ] ] ], "expected_grad_weight": [ [ [ - [ - -0.7294929623603821, - 2.4809837341308594 - ], - [ - -0.8639777302742004, - 5.7739386558532715 - ] + [-0.7294929623603821, 2.4809837341308594], + [-0.8639777302742004, 5.7739386558532715] ], [ - [ - -2.196805477142334, - 3.045524835586548 - ], - [ - -4.312042236328125, - 4.832023620605469 - ] + [-2.196805477142334, 3.045524835586548], + [-4.312042236328125, 4.832023620605469] ] ], [ [ - [ - -0.7294929623603821, - 2.4809837341308594 - ], - [ - -0.8639777302742004, - 5.7739386558532715 - ] + [-0.7294929623603821, 2.4809837341308594], + [-0.8639777302742004, 5.7739386558532715] ], [ - [ - -2.196805477142334, - 3.045524835586548 - ], - [ - -4.312042236328125, - 4.832023620605469 - ] + [-2.196805477142334, 3.045524835586548], + [-4.312042236328125, 4.832023620605469] ] ], [ [ - [ - -0.7294929623603821, - 2.4809837341308594 - ], - [ - -0.8639777302742004, - 5.7739386558532715 - ] + [-0.7294929623603821, 2.4809837341308594], + [-0.8639777302742004, 5.7739386558532715] ], [ - [ - -2.196805477142334, - 3.045524835586548 - ], - [ - -4.312042236328125, - 4.832023620605469 - ] + [-2.196805477142334, 3.045524835586548], + [-4.312042236328125, 4.832023620605469] ] ] ], - "bias": [ - -0.15220095217227936, - -0.06130267307162285, - 0.196860209107399 - ], - "expected_grad_bias": [ - 32.0, - 32.0, - 32.0 - ] + "bias": [-0.15220095217227936, -0.06130267307162285, 0.196860209107399], + "expected_grad_bias": [32.0, 32.0, 32.0] }, { "test_name": "conv2d_dilation_no_bias", @@ -15332,286 +4653,94 @@ export const testData = { "input": [ [ [ - [ - 0.9263717532157898, - 0.06930986046791077, - 0.6712534427642822, - -0.02775866538286209, - -0.9041587114334106 - ], - [ - 0.8335179090499878, - 0.8654338121414185, - -0.4001701772212982, - 1.4326399564743042, - 0.34999290108680725 - ], - [ - 0.6649242639541626, - -1.9941226243972778, - -1.0177124738693237, - 1.7738550901412964, - -0.23209598660469055 - ], - [ - -0.4985274374485016, - 0.6896741390228271, - 0.7225849628448486, - -1.5831043720245361, - -0.3734499514102936 - ], - [ - 0.6056780219078064, - -0.019913967698812485, - -1.0039576292037964, - -0.8306655287742615, - -1.3570464849472046 - ] + [0.9263717532157898, 0.06930986046791077, 0.6712534427642822, -0.02775866538286209, -0.9041587114334106], + [0.8335179090499878, 0.8654338121414185, -0.4001701772212982, 1.4326399564743042, 0.34999290108680725], + [0.6649242639541626, -1.9941226243972778, -1.0177124738693237, 1.7738550901412964, -0.23209598660469055], + [-0.4985274374485016, 0.6896741390228271, 0.7225849628448486, -1.5831043720245361, -0.3734499514102936], + [0.6056780219078064, -0.019913967698812485, -1.0039576292037964, -0.8306655287742615, -1.3570464849472046] ], [ - [ - 0.4011816382408142, - 1.1124663352966309, - 0.4233713448047638, - 1.905303955078125, - 0.7196555137634277 - ], - [ - 1.2182841300964355, - -0.2805838882923126, - 1.9091075658798218, - -0.4942598342895508, - -1.0949782133102417 - ], - [ - 0.5647533535957336, - -0.7126783132553101, - 2.1329596042633057, - -0.21151213347911835, - 0.760424017906189 - ], - [ - 0.5244688391685486, - -0.921648383140564, - -0.2014247626066208, - 0.5469425320625305, - -0.8171257972717285 - ], - [ - 1.0141600370407104, - 0.7154613733291626, - -1.0755102634429932, - -0.1033744290471077, - 0.23104271292686462 - ] + [0.4011816382408142, 1.1124663352966309, 0.4233713448047638, 1.905303955078125, 0.7196555137634277], + [1.2182841300964355, -0.2805838882923126, 1.9091075658798218, -0.4942598342895508, -1.0949782133102417], + [0.5647533535957336, -0.7126783132553101, 2.1329596042633057, -0.21151213347911835, 0.760424017906189], + [0.5244688391685486, -0.921648383140564, -0.2014247626066208, 0.5469425320625305, -0.8171257972717285], + [1.0141600370407104, 0.7154613733291626, -1.0755102634429932, -0.1033744290471077, 0.23104271292686462] ] ] ], "weight": [ [ [ - [ - 0.26463213562965393, - 0.16901569068431854 - ], - [ - 0.2000877410173416, - -0.23677533864974976 - ] + [0.26463213562965393, 0.16901569068431854], + [0.2000877410173416, -0.23677533864974976] ], [ - [ - -0.23679085075855255, - 0.15098260343074799 - ], - [ - 0.12837570905685425, - 0.31905919313430786 - ] + [-0.23679085075855255, 0.15098260343074799], + [0.12837570905685425, 0.31905919313430786] ] ], [ [ - [ - -0.04603291302919388, - -0.06499334424734116 - ], - [ - 0.24237388372421265, - 0.011418171226978302 - ] + [-0.04603291302919388, -0.06499334424734116], + [0.24237388372421265, 0.011418171226978302] ], [ - [ - 0.33192384243011475, - -0.18033814430236816 - ], - [ - -0.11600156873464584, - 0.01527633611112833 - ] + [0.33192384243011475, -0.18033814430236816], + [-0.11600156873464584, 0.01527633611112833] ] ] ], "expected_output": [ [ [ - [ - 1.4545789957046509, - -0.9400842189788818, - 0.4009864926338196 - ], - [ - -0.11507278680801392, - 1.0320004224777222, - -0.7176908254623413 - ], - [ - 0.3382055163383484, - 0.16048336029052734, - -0.6427193284034729 - ] + [1.4545789957046509, -0.9400842189788818, 0.4009864926338196], + [-0.11507278680801392, 1.0320004224777222, -0.7176908254623413], + [0.3382055163383484, 0.16048336029052734, -0.6427193284034729] ], [ - [ - 0.08715254068374634, - -0.3593597114086151, - -0.4465169608592987 - ], - [ - -0.12876389920711517, - 0.1274016946554184, - 1.008573055267334 - ], - [ - -0.16039958596229553, - -0.3207898437976837, - 0.5022419095039368 - ] + [0.08715254068374634, -0.3593597114086151, -0.4465169608592987], + [-0.12876389920711517, 0.1274016946554184, 1.008573055267334], + [-0.16039958596229553, -0.3207898437976837, 0.5022419095039368] ] ] ], "expected_grad_input": [ [ [ - [ - 0.21859923005104065, - 0.21859923005104065, - 0.32262158393859863, - 0.10402234643697739, - 0.10402234643697739 - ], - [ - 0.21859923005104065, - 0.21859923005104065, - 0.32262158393859863, - 0.10402234643697739, - 0.10402234643697739 - ], - [ - 0.6610608100891113, - 0.6610608100891113, - 0.5397260189056396, - -0.12133482843637466, - -0.12133482843637466 - ], - [ - 0.44246160984039307, - 0.44246160984039307, - 0.21710443496704102, - -0.22535717487335205, - -0.22535717487335205 - ], - [ - 0.44246160984039307, - 0.44246160984039307, - 0.21710443496704102, - -0.22535717487335205, - -0.22535717487335205 - ] + [0.21859923005104065, 0.21859923005104065, 0.32262158393859863, 0.10402234643697739, 0.10402234643697739], + [0.21859923005104065, 0.21859923005104065, 0.32262158393859863, 0.10402234643697739, 0.10402234643697739], + [0.6610608100891113, 0.6610608100891113, 0.5397260189056396, -0.12133482843637466, -0.12133482843637466], + [0.44246160984039307, 0.44246160984039307, 0.21710443496704102, -0.22535717487335205, -0.22535717487335205], + [0.44246160984039307, 0.44246160984039307, 0.21710443496704102, -0.22535717487335205, -0.22535717487335205] ], [ - [ - 0.0951329916715622, - 0.0951329916715622, - 0.06577745079994202, - -0.029355540871620178, - -0.029355540871620178 - ], - [ - 0.0951329916715622, - 0.0951329916715622, - 0.06577745079994202, - -0.029355540871620178, - -0.029355540871620178 - ], - [ - 0.1075071319937706, - 0.1075071319937706, - 0.41248711943626404, - 0.30497997999191284, - 0.30497997999191284 - ], - [ - 0.012374140322208405, - 0.012374140322208405, - 0.346709668636322, - 0.3343355357646942, - 0.3343355357646942 - ], - [ - 0.012374140322208405, - 0.012374140322208405, - 0.346709668636322, - 0.3343355357646942, - 0.3343355357646942 - ] + [0.0951329916715622, 0.0951329916715622, 0.06577745079994202, -0.029355540871620178, -0.029355540871620178], + [0.0951329916715622, 0.0951329916715622, 0.06577745079994202, -0.029355540871620178, -0.029355540871620178], + [0.1075071319937706, 0.1075071319937706, 0.41248711943626404, 0.30497997999191284, 0.30497997999191284], + [0.012374140322208405, 0.012374140322208405, 0.346709668636322, 0.3343355357646942, 0.3343355357646942], + [0.012374140322208405, 0.012374140322208405, 0.346709668636322, 0.3343355357646942, 0.3343355357646942] ] ] ], "expected_grad_weight": [ [ [ - [ - 0.6188055276870728, - 1.6458454132080078 - ], - [ - -1.8513727188110352, - -3.90159273147583 - ] + [0.6188055276870728, 1.6458454132080078], + [-1.8513727188110352, -3.90159273147583] ], [ - [ - 6.768861770629883, - 6.050072193145752 - ], - [ - 2.040541410446167, - 1.2624212503433228 - ] + [6.768861770629883, 6.050072193145752], + [2.040541410446167, 1.2624212503433228] ] ], [ [ - [ - 0.6188055276870728, - 1.6458454132080078 - ], - [ - -1.8513727188110352, - -3.90159273147583 - ] + [0.6188055276870728, 1.6458454132080078], + [-1.8513727188110352, -3.90159273147583] ], - [ - [ - 6.768861770629883, - 6.050072193145752 - ], - [ - 2.040541410446167, - 1.2624212503433228 - ] + [ + [6.768861770629883, 6.050072193145752], + [2.040541410446167, 1.2624212503433228] ] ] ], @@ -15632,631 +4761,189 @@ export const testData = { "input": [ [ [ - [ - 0.88399738073349, - -1.1032230854034424, - 0.4613407552242279, - -0.6266279220581055 - ], - [ - 1.1519485712051392, - -0.7845342755317688, - -0.6696850061416626, - 1.264907717704773 - ], - [ - -1.381635308265686, - -0.36659157276153564, - -1.3767681121826172, - -0.6575090289115906 - ], - [ - -2.4963321685791016, - -0.03116716258227825, - -1.162872076034546, - -0.05399742349982262 - ] + [0.88399738073349, -1.1032230854034424, 0.4613407552242279, -0.6266279220581055], + [1.1519485712051392, -0.7845342755317688, -0.6696850061416626, 1.264907717704773], + [-1.381635308265686, -0.36659157276153564, -1.3767681121826172, -0.6575090289115906], + [-2.4963321685791016, -0.03116716258227825, -1.162872076034546, -0.05399742349982262] ], [ - [ - -0.30355918407440186, - 0.07046826928853989, - -1.5127924680709839, - 1.3581115007400513 - ], - [ - 0.23847708106040955, - 1.1590290069580078, - 0.13452637195587158, - -0.2990451753139496 - ], - [ - -0.8544708490371704, - -0.8357695937156677, - 1.2985942363739014, - -0.7110929489135742 - ], - [ - -0.004657623823732138, - -0.9602146744728088, - 0.03523630276322365, - 0.6553695797920227 - ] + [-0.30355918407440186, 0.07046826928853989, -1.5127924680709839, 1.3581115007400513], + [0.23847708106040955, 1.1590290069580078, 0.13452637195587158, -0.2990451753139496], + [-0.8544708490371704, -0.8357695937156677, 1.2985942363739014, -0.7110929489135742], + [-0.004657623823732138, -0.9602146744728088, 0.03523630276322365, 0.6553695797920227] ], [ - [ - -1.226547122001648, - 1.3209213018417358, - 1.0341976881027222, - -0.49460795521736145 - ], - [ - 1.004910945892334, - -0.7041428685188293, - -0.3250839412212372, - 2.8139994144439697 - ], - [ - 0.08612233400344849, - -1.7298319339752197, - 0.08109258860349655, - 1.2689827680587769 - ], - [ - -1.36784029006958, - 0.22102324664592743, - -0.5776031613349915, - 1.5733610391616821 - ] + [-1.226547122001648, 1.3209213018417358, 1.0341976881027222, -0.49460795521736145], + [1.004910945892334, -0.7041428685188293, -0.3250839412212372, 2.8139994144439697], + [0.08612233400344849, -1.7298319339752197, 0.08109258860349655, 1.2689827680587769], + [-1.36784029006958, 0.22102324664592743, -0.5776031613349915, 1.5733610391616821] ], [ - [ - -0.540728747844696, - 0.5175154209136963, - -1.1346107721328735, - 0.4711856544017792 - ], - [ - -0.6981925368309021, - -0.3024372160434723, - 0.3560723662376404, - 0.7634297609329224 - ], - [ - 2.888267755508423, - -0.5556330680847168, - 0.017246929928660393, - -0.3958292305469513 - ], - [ - 0.4055117070674896, - -0.2378912717103958, - -0.044524792581796646, - 0.6570231914520264 - ] + [-0.540728747844696, 0.5175154209136963, -1.1346107721328735, 0.4711856544017792], + [-0.6981925368309021, -0.3024372160434723, 0.3560723662376404, 0.7634297609329224], + [2.888267755508423, -0.5556330680847168, 0.017246929928660393, -0.3958292305469513], + [0.4055117070674896, -0.2378912717103958, -0.044524792581796646, 0.6570231914520264] ] ] ], "weight": [ [ [ - [ - -0.16846626996994019, - -0.19352877140045166, - -0.05792432650923729 - ], - [ - -0.12028075754642487, - 0.18736235797405243, - -0.16802482306957245 - ], - [ - 0.14187708497047424, - 0.0448138453066349, - -0.07168931514024734 - ] + [-0.16846626996994019, -0.19352877140045166, -0.05792432650923729], + [-0.12028075754642487, 0.18736235797405243, -0.16802482306957245], + [0.14187708497047424, 0.0448138453066349, -0.07168931514024734] ], [ - [ - 0.19213205575942993, - 0.1311657726764679, - -0.008243783377110958 - ], - [ - -0.15975381433963776, - -0.06937320530414581, - 0.07599683851003647 - ], - [ - 0.2042289674282074, - -0.07953961938619614, - -0.09795388579368591 - ] + [0.19213205575942993, 0.1311657726764679, -0.008243783377110958], + [-0.15975381433963776, -0.06937320530414581, 0.07599683851003647], + [0.2042289674282074, -0.07953961938619614, -0.09795388579368591] ] ], [ [ - [ - -0.23029308021068573, - 0.14487296342849731, - 0.23005151748657227 - ], - [ - 0.1622759848833084, - -0.1313360184431076, - 0.16885194182395935 - ], - [ - -0.07145748287439346, - 0.12322963029146194, - 0.13781873881816864 - ] + [-0.23029308021068573, 0.14487296342849731, 0.23005151748657227], + [0.1622759848833084, -0.1313360184431076, 0.16885194182395935], + [-0.07145748287439346, 0.12322963029146194, 0.13781873881816864] ], [ - [ - -0.19216682016849518, - 0.05832885205745697, - 0.09409772604703903 - ], - [ - -0.14169660210609436, - 0.21791832149028778, - 0.1840069591999054 - ], - [ - 0.1969916969537735, - -0.002126280451193452, - -0.12610980868339539 - ] + [-0.19216682016849518, 0.05832885205745697, 0.09409772604703903], + [-0.14169660210609436, 0.21791832149028778, 0.1840069591999054], + [0.1969916969537735, -0.002126280451193452, -0.12610980868339539] ] ], [ [ - [ - -0.12880636751651764, - 0.08330836147069931, - -0.04682663828134537 - ], - [ - 0.1873403787612915, - 0.1974017322063446, - 0.018188921734690666 - ], - [ - -0.19296586513519287, - 0.09355738013982773, - 0.2109287977218628 - ] + [-0.12880636751651764, 0.08330836147069931, -0.04682663828134537], + [0.1873403787612915, 0.1974017322063446, 0.018188921734690666], + [-0.19296586513519287, 0.09355738013982773, 0.2109287977218628] ], [ - [ - -0.059201207011938095, - -0.12335500121116638, - -0.055137068033218384 - ], - [ - 0.03376912325620651, - -0.17488259077072144, - 0.12587366998195648 - ], - [ - 0.10075010359287262, - -0.0901164561510086, - -0.08731470257043839 - ] + [-0.059201207011938095, -0.12335500121116638, -0.055137068033218384], + [0.03376912325620651, -0.17488259077072144, 0.12587366998195648], + [0.10075010359287262, -0.0901164561510086, -0.08731470257043839] ] ], [ [ - [ - -0.11183871328830719, - 0.18424758315086365, - 0.1397935152053833 - ], - [ - 0.06699356436729431, - -0.010571525432169437, - 0.058881621807813644 - ], - [ - 0.22740556299686432, - 0.07462751120328903, - -0.11755186319351196 - ] + [-0.11183871328830719, 0.18424758315086365, 0.1397935152053833], + [0.06699356436729431, -0.010571525432169437, 0.058881621807813644], + [0.22740556299686432, 0.07462751120328903, -0.11755186319351196] ], [ - [ - 0.09117675572633743, - -0.09353625029325485, - -0.00836957711726427 - ], - [ - -0.15181048214435577, - -0.006896039471030235, - 0.012296343222260475 - ], - [ - -0.14294812083244324, - 0.15153303742408752, - 0.21769195795059204 - ] + [0.09117675572633743, -0.09353625029325485, -0.00836957711726427], + [-0.15181048214435577, -0.006896039471030235, 0.012296343222260475], + [-0.14294812083244324, 0.15153303742408752, 0.21769195795059204] ] ] ], "expected_output": [ [ [ - [ - 0.15562714636325836, - -0.5394341349601746, - 0.34747612476348877, - -0.20965653657913208 - ], - [ - 0.18866421282291412, - -0.8261902332305908, - -0.9921233654022217, - 0.14765621721744537 - ], - [ - -0.5696333646774292, - 0.41791433095932007, - -0.19561073184013367, - -0.6705589294433594 - ], - [ - -0.548848569393158, - 0.4616500735282898, - 0.18045620620250702, - 0.39692628383636475 - ] + [0.15562714636325836, -0.5394341349601746, 0.34747612476348877, -0.20965653657913208], + [0.18866421282291412, -0.8261902332305908, -0.9921233654022217, 0.14765621721744537], + [-0.5696333646774292, 0.41791433095932007, -0.19561073184013367, -0.6705589294433594], + [-0.548848569393158, 0.4616500735282898, 0.18045620620250702, 0.39692628383636475] ], [ - [ - -0.4001096487045288, - -0.02919364720582962, - 0.04673450440168381, - 0.9666410088539124 - ], - [ - -0.2005985975265503, - -0.3149549961090088, - -0.056465305387973785, - 0.15684770047664642 - ], - [ - -0.2335754632949829, - -0.6499486565589905, - 0.06040894240140915, - -0.03156033903360367 - ], - [ - -0.1997881531715393, - -0.5451706051826477, - 0.37432679533958435, - -0.044711120426654816 - ] + [-0.4001096487045288, -0.02919364720582962, 0.04673450440168381, 0.9666410088539124], + [-0.2005985975265503, -0.3149549961090088, -0.056465305387973785, 0.15684770047664642], + [-0.2335754632949829, -0.6499486565589905, 0.06040894240140915, -0.03156033903360367], + [-0.1997881531715393, -0.5451706051826477, 0.37432679533958435, -0.044711120426654816] ], [ - [ - -0.18639610707759857, - -0.7671643495559692, - 1.1248012781143188, - 0.10564678907394409 - ], - [ - -0.5876757502555847, - 0.38320043683052063, - 0.324480265378952, - 0.1853906214237213 - ], - [ - -0.6299664974212646, - -0.17470739781856537, - -0.49781695008277893, - 0.5286859273910522 - ], - [ - -0.7671483755111694, - -0.5986586213111877, - 0.09837397933006287, - 0.06622444093227386 - ] + [-0.18639610707759857, -0.7671643495559692, 1.1248012781143188, 0.10564678907394409], + [-0.5876757502555847, 0.38320043683052063, 0.324480265378952, 0.1853906214237213], + [-0.6299664974212646, -0.17470739781856537, -0.49781695008277893, 0.5286859273910522], + [-0.7671483755111694, -0.5986586213111877, 0.09837397933006287, 0.06622444093227386] ], [ - [ - 0.040119193494319916, - 0.3281589150428772, - -0.31515181064605713, - 0.39752304553985596 - ], - [ - 0.43356120586395264, - -0.05420731008052826, - -0.2896234393119812, - -0.46131598949432373 - ], - [ - -0.14020667970180511, - -1.1087311506271362, - 0.3279479146003723, - 0.5531594157218933 - ], - [ - -0.5165536999702454, - -0.23714134097099304, - 0.44804590940475464, - 0.16338694095611572 - ] + [0.040119193494319916, 0.3281589150428772, -0.31515181064605713, 0.39752304553985596], + [0.43356120586395264, -0.05420731008052826, -0.2896234393119812, -0.46131598949432373], + [-0.14020667970180511, -1.1087311506271362, 0.3279479146003723, 0.5531594157218933], + [-0.5165536999702454, -0.23714134097099304, 0.44804590940475464, 0.16338694095611572] ] ] ], "expected_grad_input": [ [ [ - [ - -0.3493936061859131, - -0.1764393001794815, - -0.1764393001794815, - 0.18032483756542206 - ], - [ - -0.11093051731586456, - 0.12815320491790771, - 0.12815320491790771, - 0.4144977331161499 - ], - [ - -0.11093051731586456, - 0.12815320491790771, - 0.12815320491790771, - 0.4144977331161499 - ], - [ - 0.3364846706390381, - 0.4034411609172821, - 0.4034411609172821, - 0.29102635383605957 - ] + [-0.3493936061859131, -0.1764393001794815, -0.1764393001794815, 0.18032483756542206], + [-0.11093051731586456, 0.12815320491790771, 0.12815320491790771, 0.4144977331161499], + [-0.11093051731586456, 0.12815320491790771, 0.12815320491790771, 0.4144977331161499], + [0.3364846706390381, 0.4034411609172821, 0.4034411609172821, 0.29102635383605957] ], [ - [ - 0.036554545164108276, - 0.38241228461265564, - 0.38241228461265564, - 0.6838974952697754 - ], - [ - 0.3561093211174011, - 0.47790342569351196, - 0.47790342569351196, - 0.37816792726516724 - ], - [ - 0.3561093211174011, - 0.47790342569351196, - 0.47790342569351196, - 0.37816792726516724 - ], - [ - 0.1666494607925415, - 0.20258954167366028, - 0.20258954167366028, - 0.10281932353973389 - ] + [0.036554545164108276, 0.38241228461265564, 0.38241228461265564, 0.6838974952697754], + [0.3561093211174011, 0.47790342569351196, 0.47790342569351196, 0.37816792726516724], + [0.3561093211174011, 0.47790342569351196, 0.47790342569351196, 0.37816792726516724], + [0.1666494607925415, 0.20258954167366028, 0.20258954167366028, 0.10281932353973389] ], [ - [ - 0.4680750370025635, - 0.6381124258041382, - 0.6381124258041382, - 0.6244235634803772 - ], - [ - 0.6706995964050293, - 0.9341139197349548, - 0.9341139197349548, - 0.8859853744506836 - ], - [ - 0.6706995964050293, - 0.9341139197349548, - 0.9341139197349548, - 0.8859853744506836 - ], - [ - 0.6437886953353882, - 0.8142361640930176, - 0.8142361640930176, - 0.5254625678062439 - ] + [0.4680750370025635, 0.6381124258041382, 0.6381124258041382, 0.6244235634803772], + [0.6706995964050293, 0.9341139197349548, 0.9341139197349548, 0.8859853744506836], + [0.6706995964050293, 0.9341139197349548, 0.9341139197349548, 0.8859853744506836], + [0.6437886953353882, 0.8142361640930176, 0.8142361640930176, 0.5254625678062439] ], [ - [ - -0.4847356677055359, - -0.41007232666015625, - -0.41007232666015625, - -0.32400649785995483 - ], - [ - -0.4655171036720276, - -0.2604764997959137, - -0.2604764997959137, - -0.13221266865730286 - ], - [ - -0.4655171036720276, - -0.2604764997959137, - -0.2604764997959137, - -0.13221266865730286 - ], - [ - -0.280601441860199, - -0.01205413043498993, - -0.01205413043498993, - 0.14818523824214935 - ] + [-0.4847356677055359, -0.41007232666015625, -0.41007232666015625, -0.32400649785995483], + [-0.4655171036720276, -0.2604764997959137, -0.2604764997959137, -0.13221266865730286], + [-0.4655171036720276, -0.2604764997959137, -0.2604764997959137, -0.13221266865730286], + [-0.280601441860199, -0.01205413043498993, -0.01205413043498993, 0.14818523824214935] ] ] ], "expected_grad_weight": [ [ [ - [ - -3.185150384902954, - -3.2043797969818115, - -3.8586905002593994 - ], - [ - -6.875521659851074, - -6.948748588562012, - -5.106727600097656 - ], - [ - -7.117636680603027, - -6.564235687255859, - -3.838216781616211 - ] + [-3.185150384902954, -3.2043797969818115, -3.8586905002593994], + [-6.875521659851074, -6.948748588562012, -5.106727600097656], + [-7.117636680603027, -6.564235687255859, -3.838216781616211] ], [ - [ - -0.6054971814155579, - -0.257523775100708, - 0.6620292663574219 - ], - [ - -1.5351331233978271, - -0.5317901968955994, - 0.3924204707145691 - ], - [ - 0.2107502818107605, - -0.144018292427063, - 0.47663313150405884 - ] + [-0.6054971814155579, -0.257523775100708, 0.6620292663574219], + [-1.5351331233978271, -0.5317901968955994, 0.3924204707145691], + [0.2107502818107605, -0.144018292427063, 0.47663313150405884] ] ], [ [ - [ - -3.185150384902954, - -3.2043797969818115, - -3.8586905002593994 - ], - [ - -6.875521659851074, - -6.948748588562012, - -5.106727600097656 - ], - [ - -7.117636680603027, - -6.564235687255859, - -3.838216781616211 - ] + [-3.185150384902954, -3.2043797969818115, -3.8586905002593994], + [-6.875521659851074, -6.948748588562012, -5.106727600097656], + [-7.117636680603027, -6.564235687255859, -3.838216781616211] ], [ - [ - -0.6054971814155579, - -0.257523775100708, - 0.6620292663574219 - ], - [ - -1.5351331233978271, - -0.5317901968955994, - 0.3924204707145691 - ], - [ - 0.2107502818107605, - -0.144018292427063, - 0.47663313150405884 - ] + [-0.6054971814155579, -0.257523775100708, 0.6620292663574219], + [-1.5351331233978271, -0.5317901968955994, 0.3924204707145691], + [0.2107502818107605, -0.144018292427063, 0.47663313150405884] ] ], [ [ - [ - -0.45836102962493896, - 3.1300134658813477, - 3.2655272483825684 - ], - [ - -2.182781219482422, - 2.978954315185547, - 4.482308387756348 - ], - [ - -3.3113529682159424, - 2.3449902534484863, - 2.6217973232269287 - ] + [-0.45836102962493896, 3.1300134658813477, 3.2655272483825684], + [-2.182781219482422, 2.978954315185547, 4.482308387756348], + [-3.3113529682159424, 2.3449902534484863, 2.6217973232269287] ], [ - [ - 0.5475001335144043, - 1.3862863779067993, - -0.2630601227283478 - ], - [ - 0.6705957651138306, - 2.166405200958252, - 0.11154699325561523 - ], - [ - 1.8284196853637695, - 2.853043556213379, - 0.2574566900730133 - ] + [0.5475001335144043, 1.3862863779067993, -0.2630601227283478], + [0.6705957651138306, 2.166405200958252, 0.11154699325561523], + [1.8284196853637695, 2.853043556213379, 0.2574566900730133] ] ], [ [ - [ - -0.45836102962493896, - 3.1300134658813477, - 3.2655272483825684 - ], - [ - -2.182781219482422, - 2.978954315185547, - 4.482308387756348 - ], - [ - -3.3113529682159424, - 2.3449902534484863, - 2.6217973232269287 - ] + [-0.45836102962493896, 3.1300134658813477, 3.2655272483825684], + [-2.182781219482422, 2.978954315185547, 4.482308387756348], + [-3.3113529682159424, 2.3449902534484863, 2.6217973232269287] ], [ - [ - 0.5475001335144043, - 1.3862863779067993, - -0.2630601227283478 - ], - [ - 0.6705957651138306, - 2.166405200958252, - 0.11154699325561523 - ], - [ - 1.8284196853637695, - 2.853043556213379, - 0.2574566900730133 - ] + [0.5475001335144043, 1.3862863779067993, -0.2630601227283478], + [0.6705957651138306, 2.166405200958252, 0.11154699325561523], + [1.8284196853637695, 2.853043556213379, 0.2574566900730133] ] ] ], - "bias": [ - -0.19714997708797455, - 0.06829815357923508, - -0.16282400488853455, - -0.0468476265668869 - ], - "expected_grad_bias": [ - 16.0, - 16.0, - 16.0, - 16.0 - ] + "bias": [-0.19714997708797455, 0.06829815357923508, -0.16282400488853455, -0.0468476265668869], + "expected_grad_bias": [16.0, 16.0, 16.0, 16.0] }, { "test_name": "conv3d_basic", @@ -16273,189 +4960,39 @@ export const testData = { [ [ [ - [ - -0.6729629635810852, - 0.8545035123825073, - -1.1793856620788574, - -0.9540548324584961, - -0.969673752784729 - ], - [ - 0.3141362965106964, - 1.2000207901000977, - -0.1831716001033783, - -0.18045181035995483, - -0.1034746766090393 - ], - [ - -0.10869846493005753, - 0.5782245993614197, - 1.7499538660049438, - 0.002034955658018589, - 0.36500951647758484 - ], - [ - -0.8946718573570251, - -0.3625917434692383, - 1.179726004600525, - 0.8268131613731384, - 1.457729697227478 - ], - [ - -1.029435634613037, - -1.2957319021224976, - 0.2842133045196533, - -2.20194673538208, - 0.5491127967834473 - ] + [-0.6729629635810852, 0.8545035123825073, -1.1793856620788574, -0.9540548324584961, -0.969673752784729], + [0.3141362965106964, 1.2000207901000977, -0.1831716001033783, -0.18045181035995483, -0.1034746766090393], + [-0.10869846493005753, 0.5782245993614197, 1.7499538660049438, 0.002034955658018589, 0.36500951647758484], + [-0.8946718573570251, -0.3625917434692383, 1.179726004600525, 0.8268131613731384, 1.457729697227478], + [-1.029435634613037, -1.2957319021224976, 0.2842133045196533, -2.20194673538208, 0.5491127967834473] ], [ - [ - -1.2930694818496704, - 0.4510805904865265, - -0.3953653573989868, - 1.7161552906036377, - 0.15392881631851196 - ], - [ - -1.4651801586151123, - -0.5170696377754211, - -0.8793548941612244, - -0.8100994825363159, - 0.6788665652275085 - ], - [ - 0.33716168999671936, - -0.5290454030036926, - 0.9324967265129089, - 0.6762214303016663, - 0.14378660917282104 - ], - [ - 2.18232798576355, - 0.037647929042577744, - 0.21775013208389282, - 2.395190954208374, - 0.4023849368095398 - ], - [ - 1.6874338388442993, - -2.743908405303955, - -1.9040486812591553, - 0.9187806844711304, - 0.12344544380903244 - ] + [-1.2930694818496704, 0.4510805904865265, -0.3953653573989868, 1.7161552906036377, 0.15392881631851196], + [-1.4651801586151123, -0.5170696377754211, -0.8793548941612244, -0.8100994825363159, 0.6788665652275085], + [0.33716168999671936, -0.5290454030036926, 0.9324967265129089, 0.6762214303016663, 0.14378660917282104], + [2.18232798576355, 0.037647929042577744, 0.21775013208389282, 2.395190954208374, 0.4023849368095398], + [1.6874338388442993, -2.743908405303955, -1.9040486812591553, 0.9187806844711304, 0.12344544380903244] ], [ - [ - 2.8273682594299316, - 0.47407886385917664, - -1.9149128198623657, - -1.5384353399276733, - -0.6529980897903442 - ], - [ - 0.16414928436279297, - -0.19700200855731964, - 1.038715124130249, - -0.3908529281616211, - 1.0207839012145996 - ], - [ - -1.2268577814102173, - -2.0579991340637207, - 0.5987722277641296, - -0.13595744967460632, - -0.219259113073349 - ], - [ - -0.47011202573776245, - -0.9500816464424133, - -0.6808398962020874, - -0.9808987379074097, - -0.7519583702087402 - ], - [ - -1.0324863195419312, - -1.8080289363861084, - 0.21794334053993225, - 0.6857624053955078, - 0.43733805418014526 - ] + [2.8273682594299316, 0.47407886385917664, -1.9149128198623657, -1.5384353399276733, -0.6529980897903442], + [0.16414928436279297, -0.19700200855731964, 1.038715124130249, -0.3908529281616211, 1.0207839012145996], + [-1.2268577814102173, -2.0579991340637207, 0.5987722277641296, -0.13595744967460632, -0.219259113073349], + [-0.47011202573776245, -0.9500816464424133, -0.6808398962020874, -0.9808987379074097, -0.7519583702087402], + [-1.0324863195419312, -1.8080289363861084, 0.21794334053993225, 0.6857624053955078, 0.43733805418014526] ], [ - [ - -1.9561761617660522, - 1.2915894985198975, - -1.6977379322052002, - -1.2025177478790283, - -1.646543025970459 - ], - [ - -0.789655864238739, - -1.313944935798645, - 1.211775779724121, - 0.9332025647163391, - -0.2605237364768982 - ], - [ - 1.5151708126068115, - -1.521173357963562, - -1.1669979095458984, - -2.0334060192108154, - -0.08260460197925568 - ], - [ - 1.4479997158050537, - 0.1535591334104538, - -0.19014781713485718, - -0.9898110032081604, - 0.3790753483772278 - ], - [ - 1.921068549156189, - 0.03124547004699707, - 0.3133164942264557, - -1.2002359628677368, - -0.22739538550376892 - ] + [-1.9561761617660522, 1.2915894985198975, -1.6977379322052002, -1.2025177478790283, -1.646543025970459], + [-0.789655864238739, -1.313944935798645, 1.211775779724121, 0.9332025647163391, -0.2605237364768982], + [1.5151708126068115, -1.521173357963562, -1.1669979095458984, -2.0334060192108154, -0.08260460197925568], + [1.4479997158050537, 0.1535591334104538, -0.19014781713485718, -0.9898110032081604, 0.3790753483772278], + [1.921068549156189, 0.03124547004699707, 0.3133164942264557, -1.2002359628677368, -0.22739538550376892] ], [ - [ - -0.23840101063251495, - -0.682720422744751, - 0.46212872862815857, - -0.9165003299713135, - -1.665152907371521 - ], - [ - 0.7060098052024841, - 0.9033956527709961, - -0.3824882507324219, - 0.1978939324617386, - 0.6745620965957642 - ], - [ - 0.8720393776893616, - -0.5882147550582886, - -1.3370387554168701, - 1.169712781906128, - -0.5579738020896912 - ], - [ - 0.38680657744407654, - -0.4910755455493927, - 0.3231601417064667, - -1.1188082695007324, - 2.2093753814697266 - ], - [ - 0.6792762279510498, - 0.3959449231624603, - 0.66949063539505, - -0.19622361660003662, - -0.32004305720329285 - ] + [-0.23840101063251495, -0.682720422744751, 0.46212872862815857, -0.9165003299713135, -1.665152907371521], + [0.7060098052024841, 0.9033956527709961, -0.3824882507324219, 0.1978939324617386, 0.6745620965957642], + [0.8720393776893616, -0.5882147550582886, -1.3370387554168701, 1.169712781906128, -0.5579738020896912], + [0.38680657744407654, -0.4910755455493927, 0.3231601417064667, -1.1188082695007324, 2.2093753814697266], + [0.6792762279510498, 0.3959449231624603, 0.66949063539505, -0.19622361660003662, -0.32004305720329285] ] ] ] @@ -16464,55 +5001,19 @@ export const testData = { [ [ [ - [ - -0.0833703875541687, - 0.16452591121196747, - -0.04412245377898216 - ], - [ - -0.051829490810632706, - 0.015444858931005001, - -0.1033153161406517 - ], - [ - 0.013840604573488235, - -0.07998784631490707, - 0.061052776873111725 - ] + [-0.0833703875541687, 0.16452591121196747, -0.04412245377898216], + [-0.051829490810632706, 0.015444858931005001, -0.1033153161406517], + [0.013840604573488235, -0.07998784631490707, 0.061052776873111725] ], [ - [ - -0.040852438658475876, - -0.0645793005824089, - -0.0724971741437912 - ], - [ - 0.0500001534819603, - 0.09657912701368332, - -0.17594556510448456 - ], - [ - -0.1342204213142395, - -0.18469774723052979, - 0.08983496576547623 - ] + [-0.040852438658475876, -0.0645793005824089, -0.0724971741437912], + [0.0500001534819603, 0.09657912701368332, -0.17594556510448456], + [-0.1342204213142395, -0.18469774723052979, 0.08983496576547623] ], [ - [ - 0.14433297514915466, - -0.18490633368492126, - 0.05002942681312561 - ], - [ - 0.039029642939567566, - -0.10327497869729996, - 0.04157921299338341 - ], - [ - 0.14839382469654083, - 0.1887684017419815, - 0.08322030305862427 - ] + [0.14433297514915466, -0.18490633368492126, 0.05002942681312561], + [0.039029642939567566, -0.10327497869729996, 0.04157921299338341], + [0.14839382469654083, 0.1887684017419815, 0.08322030305862427] ] ] ] @@ -16521,55 +5022,19 @@ export const testData = { [ [ [ - [ - 0.28478875756263733, - -0.5549619197845459, - -0.4311979115009308 - ], - [ - -0.2621602416038513, - -0.7002687454223633, - -0.4942232072353363 - ], - [ - -0.04055577516555786, - -0.29789477586746216, - 0.3332073390483856 - ] + [0.28478875756263733, -0.5549619197845459, -0.4311979115009308], + [-0.2621602416038513, -0.7002687454223633, -0.4942232072353363], + [-0.04055577516555786, -0.29789477586746216, 0.3332073390483856] ], [ - [ - 0.2114555388689041, - 0.05554547160863876, - -0.5434311628341675 - ], - [ - 0.2842505872249603, - -0.37528324127197266, - -0.20882901549339294 - ], - [ - 1.2247246503829956, - 0.27538585662841797, - -0.11705755442380905 - ] + [0.2114555388689041, 0.05554547160863876, -0.5434311628341675], + [0.2842505872249603, -0.37528324127197266, -0.20882901549339294], + [1.2247246503829956, 0.27538585662841797, -0.11705755442380905] ], [ - [ - -0.392910361289978, - -0.46385008096694946, - 0.8468499183654785 - ], - [ - -0.2620808780193329, - 0.5499442219734192, - -0.5437593460083008 - ], - [ - 0.4071813225746155, - 0.9465052485466003, - -0.03718952089548111 - ] + [-0.392910361289978, -0.46385008096694946, 0.8468499183654785], + [-0.2620808780193329, 0.5499442219734192, -0.5437593460083008], + [0.4071813225746155, 0.9465052485466003, -0.03718952089548111] ] ] ] @@ -16578,189 +5043,39 @@ export const testData = { [ [ [ - [ - -0.0833703875541687, - 0.08115552365779877, - 0.037033069878816605, - 0.12040345370769501, - -0.04412245377898216 - ], - [ - -0.1351998746395111, - 0.04477089270949364, - -0.10266687721014023, - 0.03253299742937088, - -0.14743776619434357 - ], - [ - -0.12135927379131317, - -0.0213763490319252, - -0.10776134580373764, - 0.013597927987575531, - -0.08638498932123184 - ], - [ - -0.03798888623714447, - -0.10253187268972397, - -0.14479443430900574, - -0.10680552572011948, - -0.04226253926753998 - ], - [ - 0.013840604573488235, - -0.06614723801612854, - -0.005094461143016815, - -0.01893506944179535, - 0.061052776873111725 - ] + [-0.0833703875541687, 0.08115552365779877, 0.037033069878816605, 0.12040345370769501, -0.04412245377898216], + [-0.1351998746395111, 0.04477089270949364, -0.10266687721014023, 0.03253299742937088, -0.14743776619434357], + [-0.12135927379131317, -0.0213763490319252, -0.10776134580373764, 0.013597927987575531, -0.08638498932123184], + [-0.03798888623714447, -0.10253187268972397, -0.14479443430900574, -0.10680552572011948, -0.04226253926753998], + [0.013840604573488235, -0.06614723801612854, -0.005094461143016815, -0.01893506944179535, 0.061052776873111725] ], [ - [ - -0.12422282993793488, - -0.024276215583086014, - -0.14089584350585938, - -0.016673021018505096, - -0.11661963164806366 - ], - [ - -0.12605217099189758, - 0.08591843396425247, - -0.30996203422546387, - -0.18390992283821106, - -0.3958805203437805 - ], - [ - -0.24643197655677795, - -0.29914698004722595, - -0.5441396832466125, - -0.29770776629447937, - -0.24499276280403137 - ], - [ - -0.12220915406942368, - -0.27487075328826904, - -0.40324392914772034, - -0.2810347378253937, - -0.1283731460571289 - ], - [ - -0.12037982046604156, - -0.3850654065608978, - -0.23417767882347107, - -0.11379785090684891, - 0.15088774263858795 - ] + [-0.12422282993793488, -0.024276215583086014, -0.14089584350585938, -0.016673021018505096, -0.11661963164806366], + [-0.12605217099189758, 0.08591843396425247, -0.30996203422546387, -0.18390992283821106, -0.3958805203437805], + [-0.24643197655677795, -0.29914698004722595, -0.5441396832466125, -0.29770776629447937, -0.24499276280403137], + [-0.12220915406942368, -0.27487075328826904, -0.40324392914772034, -0.2810347378253937, -0.1283731460571289], + [-0.12037982046604156, -0.3850654065608978, -0.23417767882347107, -0.11379785090684891, 0.15088774263858795] ], [ - [ - 0.020110145211219788, - -0.06484957039356232, - -0.13143977522850037, - -0.15154993534088135, - -0.06659020483493805 - ], - [ - 0.057310447096824646, - -0.018900267779827118, - -0.32317209243774414, - -0.38048258423805237, - -0.3042718768119812 - ], - [ - 0.08532446622848511, - -0.06680344045162201, - -0.1369672268629074, - -0.2222917079925537, - -0.07016381621360779 - ], - [ - 0.06521431356668472, - -0.0019538700580596924, - -0.0055275410413742065, - -0.07074178755283356, - -0.0035736262798309326 - ], - [ - 0.028014004230499268, - -0.04790318012237549, - 0.18620485067367554, - 0.15819084644317627, - 0.23410804569721222 - ] + [0.020110145211219788, -0.06484957039356232, -0.13143977522850037, -0.15154993534088135, -0.06659020483493805], + [0.057310447096824646, -0.018900267779827118, -0.32317209243774414, -0.38048258423805237, -0.3042718768119812], + [0.08532446622848511, -0.06680344045162201, -0.1369672268629074, -0.2222917079925537, -0.07016381621360779], + [0.06521431356668472, -0.0019538700580596924, -0.0055275410413742065, -0.07074178755283356, -0.0035736262798309326], + [0.028014004230499268, -0.04790318012237549, 0.18620485067367554, 0.15819084644317627, 0.23410804569721222] ], [ - [ - 0.10348053276538849, - -0.14600509405136108, - -0.16847284138202667, - -0.27195337414741516, - -0.02246774733066559 - ], - [ - 0.19251033663749695, - -0.06367114931344986, - -0.2205052673816681, - -0.41301557421684265, - -0.15683409571647644 - ], - [ - 0.20668374001979828, - -0.04542708396911621, - -0.029205963015556335, - -0.235889732837677, - 0.016221165657043457 - ], - [ - 0.1032031998038292, - 0.10057801008224487, - 0.13926690816879272, - 0.03606371581554413, - 0.038688916712999344 - ], - [ - 0.01417340338230133, - 0.018244057893753052, - 0.19129931926727295, - 0.1771259307861328, - 0.1730552613735199 - ] + [0.10348053276538849, -0.14600509405136108, -0.16847284138202667, -0.27195337414741516, -0.02246774733066559], + [0.19251033663749695, -0.06367114931344986, -0.2205052673816681, -0.41301557421684265, -0.15683409571647644], + [0.20668374001979828, -0.04542708396911621, -0.029205963015556335, -0.235889732837677, 0.016221165657043457], + [0.1032031998038292, 0.10057801008224487, 0.13926690816879272, 0.03606371581554413, 0.038688916712999344], + [0.01417340338230133, 0.018244057893753052, 0.19129931926727295, 0.1771259307861328, 0.1730552613735199] ], [ - [ - 0.14433297514915466, - -0.0405733585357666, - 0.009456068277359009, - -0.13487690687179565, - 0.05002942681312561 - ], - [ - 0.18336261808872223, - -0.10481869429349899, - -0.013210054486989975, - -0.1965726613998413, - 0.09160864353179932 - ], - [ - 0.33175644278526306, - 0.23234352469444275, - 0.40717247128486633, - 0.07541604340076447, - 0.17482894659042358 - ], - [ - 0.1874234676361084, - 0.27291688323020935, - 0.3977164030075073, - 0.21029293537139893, - 0.12479951977729797 - ], - [ - 0.14839382469654083, - 0.33716222643852234, - 0.4203825294971466, - 0.2719886898994446, - 0.08322030305862427 - ] + [0.14433297514915466, -0.0405733585357666, 0.009456068277359009, -0.13487690687179565, 0.05002942681312561], + [0.18336261808872223, -0.10481869429349899, -0.013210054486989975, -0.1965726613998413, 0.09160864353179932], + [0.33175644278526306, 0.23234352469444275, 0.40717247128486633, 0.07541604340076447, 0.17482894659042358], + [0.1874234676361084, 0.27291688323020935, 0.3977164030075073, 0.21029293537139893, 0.12479951977729797], + [0.14839382469654083, 0.33716222643852234, 0.4203825294971466, 0.2719886898994446, 0.08322030305862427] ] ] ] @@ -16769,65 +5084,25 @@ export const testData = { [ [ [ - [ - -1.0994131565093994, - -1.5909004211425781, - -1.430722951889038 - ], - [ - 0.008406639099121094, - 2.578151226043701, - 8.369916915893555 - ], - [ - -7.090886116027832, - -4.349546909332275, - 7.289556503295898 - ] + [-1.0994131565093994, -1.5909004211425781, -1.430722951889038], + [0.008406639099121094, 2.578151226043701, 8.369916915893555], + [-7.090886116027832, -4.349546909332275, 7.289556503295898] ], [ - [ - -8.079184532165527, - -8.977784156799316, - -5.922861099243164 - ], - [ - -4.117936134338379, - -7.149350166320801, - 1.0563101768493652 - ], - [ - -4.687833786010742, - -11.71389389038086, - -2.1212964057922363 - ] + [-8.079184532165527, -8.977784156799316, -5.922861099243164], + [-4.117936134338379, -7.149350166320801, 1.0563101768493652], + [-4.687833786010742, -11.71389389038086, -2.1212964057922363] ], [ - [ - -5.006127834320068, - -10.796634674072266, - -10.494353294372559 - ], - [ - -4.042076110839844, - -9.996551513671875, - -1.5225372314453125 - ], - [ - -3.995260238647461, - -12.888031005859375, - -5.185653209686279 - ] + [-5.006127834320068, -10.796634674072266, -10.494353294372559], + [-4.042076110839844, -9.996551513671875, -1.5225372314453125], + [-3.995260238647461, -12.888031005859375, -5.185653209686279] ] ] ] ], - "bias": [ - -0.038159918040037155 - ], - "expected_grad_bias": [ - 27.0 - ] + "bias": [-0.038159918040037155], + "expected_grad_bias": [27.0] }, { "test_name": "conv3d_stride_padding", @@ -16844,428 +5119,108 @@ export const testData = { [ [ [ - [ - 1.5721423625946045, - 1.0094727277755737, - 0.4029425382614136, - 1.6145533323287964 - ], - [ - 0.4475519359111786, - 0.5499113202095032, - 0.21999366581439972, - -0.019641423597931862 - ], - [ - 0.20199595391750336, - -0.305207222700119, - -0.11879883706569672, - 0.8017854690551758 - ], - [ - -0.3870505392551422, - 1.560797929763794, - 0.04964430257678032, - -0.33324524760246277 - ] + [1.5721423625946045, 1.0094727277755737, 0.4029425382614136, 1.6145533323287964], + [0.4475519359111786, 0.5499113202095032, 0.21999366581439972, -0.019641423597931862], + [0.20199595391750336, -0.305207222700119, -0.11879883706569672, 0.8017854690551758], + [-0.3870505392551422, 1.560797929763794, 0.04964430257678032, -0.33324524760246277] ], [ - [ - 0.9817765355110168, - 1.0983757972717285, - -0.25671127438545227, - -2.2621774673461914 - ], - [ - 0.16864269971847534, - -1.6143133640289307, - -0.011093960143625736, - 1.2098065614700317 - ], - [ - -1.4476906061172485, - 1.3612878322601318, - -1.3062708377838135, - 1.6407432556152344 - ], - [ - -0.33931660652160645, - 0.13347899913787842, - -0.9141297936439514, - -0.15479597449302673 - ] + [0.9817765355110168, 1.0983757972717285, -0.25671127438545227, -2.2621774673461914], + [0.16864269971847534, -1.6143133640289307, -0.011093960143625736, 1.2098065614700317], + [-1.4476906061172485, 1.3612878322601318, -1.3062708377838135, 1.6407432556152344], + [-0.33931660652160645, 0.13347899913787842, -0.9141297936439514, -0.15479597449302673] ], [ - [ - 0.39503413438796997, - -0.09881415218114853, - -1.8138774633407593, - -0.6933608055114746 - ], - [ - 1.3770830631256104, - 1.0369852781295776, - 0.522045910358429, - -2.008735179901123 - ], - [ - -0.7871567606925964, - 0.07242458313703537, - -1.9583851099014282, - -0.1682676076889038 - ], - [ - -0.09407275170087814, - -1.5021157264709473, - 0.9083237051963806, - -0.627318799495697 - ] + [0.39503413438796997, -0.09881415218114853, -1.8138774633407593, -0.6933608055114746], + [1.3770830631256104, 1.0369852781295776, 0.522045910358429, -2.008735179901123], + [-0.7871567606925964, 0.07242458313703537, -1.9583851099014282, -0.1682676076889038], + [-0.09407275170087814, -1.5021157264709473, 0.9083237051963806, -0.627318799495697] ], [ - [ - 1.345549464225769, - 0.32771772146224976, - 1.3408823013305664, - 1.2158557176589966 - ], - [ - 0.95885169506073, - 0.5136737823486328, - 0.5763065814971924, - 0.0778578370809555 - ], - [ - -1.061161994934082, - 2.042306900024414, - 0.6509259343147278, - -1.0072094202041626 - ], - [ - 0.35781362652778625, - -1.0799492597579956, - 0.04710597172379494, - 2.201401472091675 - ] + [1.345549464225769, 0.32771772146224976, 1.3408823013305664, 1.2158557176589966], + [0.95885169506073, 0.5136737823486328, 0.5763065814971924, 0.0778578370809555], + [-1.061161994934082, 2.042306900024414, 0.6509259343147278, -1.0072094202041626], + [0.35781362652778625, -1.0799492597579956, 0.04710597172379494, 2.201401472091675] ] ], [ [ - [ - 0.7588040828704834, - -1.5863133668899536, - -0.6730678081512451, - -1.2264569997787476 - ], - [ - 1.3401838541030884, - -1.162084698677063, - 1.4780147075653076, - 1.5603762865066528 - ], - [ - -0.3231433033943176, - 2.119018793106079, - 0.7877871990203857, - -1.9625552892684937 - ], - [ - -0.526032567024231, - 2.639968156814575, - 1.171855092048645, - 1.2722933292388916 - ] + [0.7588040828704834, -1.5863133668899536, -0.6730678081512451, -1.2264569997787476], + [1.3401838541030884, -1.162084698677063, 1.4780147075653076, 1.5603762865066528], + [-0.3231433033943176, 2.119018793106079, 0.7877871990203857, -1.9625552892684937], + [-0.526032567024231, 2.639968156814575, 1.171855092048645, 1.2722933292388916] ], [ - [ - -0.699771523475647, - -1.096972107887268, - -0.55166095495224, - -0.3263216018676758 - ], - [ - 0.6205294132232666, - -1.4098610877990723, - -0.41539478302001953, - 3.068681478500366 - ], - [ - 0.3701395094394684, - -0.7284356355667114, - -0.9289583563804626, - 0.8983376026153564 - ], - [ - -0.48385927081108093, - 0.032833296805620193, - -0.10948953032493591, - 0.46667027473449707 - ] + [-0.699771523475647, -1.096972107887268, -0.55166095495224, -0.3263216018676758], + [0.6205294132232666, -1.4098610877990723, -0.41539478302001953, 3.068681478500366], + [0.3701395094394684, -0.7284356355667114, -0.9289583563804626, 0.8983376026153564], + [-0.48385927081108093, 0.032833296805620193, -0.10948953032493591, 0.46667027473449707] ], [ - [ - -1.1001535654067993, - 0.8703535795211792, - 0.9143402576446533, - -0.9333758354187012 - ], - [ - -1.9243427515029907, - 0.5441842079162598, - 1.674156904220581, - -0.1457550972700119 - ], - [ - -0.663499116897583, - 1.2121490240097046, - 0.9221742749214172, - 0.5710628032684326 - ], - [ - -0.7049512267112732, - 2.053586959838867, - 0.9570578932762146, - -1.0222344398498535 - ] + [-1.1001535654067993, 0.8703535795211792, 0.9143402576446533, -0.9333758354187012], + [-1.9243427515029907, 0.5441842079162598, 1.674156904220581, -0.1457550972700119], + [-0.663499116897583, 1.2121490240097046, 0.9221742749214172, 0.5710628032684326], + [-0.7049512267112732, 2.053586959838867, 0.9570578932762146, -1.0222344398498535] ], [ - [ - 0.2908516526222229, - -0.08251824229955673, - 1.5195056200027466, - -0.3584267199039459 - ], - [ - -0.6102548837661743, - -1.5060930252075195, - -0.7732543349266052, - 1.0847911834716797 - ], - [ - 1.4872429370880127, - 0.6041548848152161, - -1.1257244348526, - 0.3761575222015381 - ], - [ - 1.959293246269226, - -0.7958163619041443, - 0.4539487659931183, - -2.5069937705993652 - ] + [0.2908516526222229, -0.08251824229955673, 1.5195056200027466, -0.3584267199039459], + [-0.6102548837661743, -1.5060930252075195, -0.7732543349266052, 1.0847911834716797], + [1.4872429370880127, 0.6041548848152161, -1.1257244348526, 0.3761575222015381], + [1.959293246269226, -0.7958163619041443, 0.4539487659931183, -2.5069937705993652] ] ] ], [ [ [ - [ - 0.4042589068412781, - -1.5217982530593872, - -0.5133728981018066, - -1.3806458711624146 - ], - [ - -0.5332193970680237, - 1.0821458101272583, - 0.6407410502433777, - -1.729612946510315 - ], - [ - -2.14782977104187, - 0.4973359704017639, - -1.268904685974121, - -0.24232769012451172 - ], - [ - -1.0745846033096313, - -0.6819858551025391, - 1.0070197582244873, - -0.8279359936714172 - ] + [0.4042589068412781, -1.5217982530593872, -0.5133728981018066, -1.3806458711624146], + [-0.5332193970680237, 1.0821458101272583, 0.6407410502433777, -1.729612946510315], + [-2.14782977104187, 0.4973359704017639, -1.268904685974121, -0.24232769012451172], + [-1.0745846033096313, -0.6819858551025391, 1.0070197582244873, -0.8279359936714172] ], [ - [ - 0.6613953113555908, - -0.03297487273812294, - -0.13994985818862915, - 1.0257868766784668 - ], - [ - -1.9717178344726562, - 0.5998077988624573, - 1.361150860786438, - -0.173064723610878 - ], - [ - 0.7555463910102844, - -0.14636565744876862, - -0.09429822862148285, - 0.29657915234565735 - ], - [ - 0.11924134939908981, - 0.1167483851313591, - -0.5673035979270935, - -1.7532938718795776 - ] + [0.6613953113555908, -0.03297487273812294, -0.13994985818862915, 1.0257868766784668], + [-1.9717178344726562, 0.5998077988624573, 1.361150860786438, -0.173064723610878], + [0.7555463910102844, -0.14636565744876862, -0.09429822862148285, 0.29657915234565735], + [0.11924134939908981, 0.1167483851313591, -0.5673035979270935, -1.7532938718795776] ], [ - [ - -0.5004768371582031, - -0.8111429214477539, - 2.0269458293914795, - -2.568801164627075 - ], - [ - 1.0234973430633545, - -0.5307855606079102, - 2.509202480316162, - 0.9496951103210449 - ], - [ - 1.4498697519302368, - 1.9099774360656738, - -0.41487377882003784, - -2.154376745223999 - ], - [ - -1.1843920946121216, - -0.13271500170230865, - -0.6129738092422485, - 1.0654757022857666 - ] + [-0.5004768371582031, -0.8111429214477539, 2.0269458293914795, -2.568801164627075], + [1.0234973430633545, -0.5307855606079102, 2.509202480316162, 0.9496951103210449], + [1.4498697519302368, 1.9099774360656738, -0.41487377882003784, -2.154376745223999], + [-1.1843920946121216, -0.13271500170230865, -0.6129738092422485, 1.0654757022857666] ], [ - [ - -1.361000418663025, - 1.183761477470398, - -1.1673825979232788, - -0.25077250599861145 - ], - [ - 0.33264845609664917, - 1.1230510473251343, - 1.8761743307113647, - 0.273639976978302 - ], - [ - 0.2801147401332855, - 0.7281787991523743, - 0.02403142862021923, - 2.3937904834747314 - ], - [ - -1.3129955530166626, - -0.48624828457832336, - 0.4012764096260071, - 1.0767757892608643 - ] + [-1.361000418663025, 1.183761477470398, -1.1673825979232788, -0.25077250599861145], + [0.33264845609664917, 1.1230510473251343, 1.8761743307113647, 0.273639976978302], + [0.2801147401332855, 0.7281787991523743, 0.02403142862021923, 2.3937904834747314], + [-1.3129955530166626, -0.48624828457832336, 0.4012764096260071, 1.0767757892608643] ] ], [ [ - [ - 2.587069511413574, - -0.7386665940284729, - 0.3296529948711395, - 2.8114237785339355 - ], - [ - -0.879487931728363, - -0.33060166239738464, - 0.6457027792930603, - 0.17840361595153809 - ], - [ - -1.1289931535720825, - -0.3602311313152313, - -2.383305549621582, - 1.3506853580474854 - ], - [ - -0.4065081775188446, - -0.30150434374809265, - -1.5348396301269531, - 1.6021355390548706 - ] + [2.587069511413574, -0.7386665940284729, 0.3296529948711395, 2.8114237785339355], + [-0.879487931728363, -0.33060166239738464, 0.6457027792930603, 0.17840361595153809], + [-1.1289931535720825, -0.3602311313152313, -2.383305549621582, 1.3506853580474854], + [-0.4065081775188446, -0.30150434374809265, -1.5348396301269531, 1.6021355390548706] ], [ - [ - -1.0694472789764404, - 0.08452916890382767, - 0.33887022733688354, - -1.223060965538025 - ], - [ - 0.19821691513061523, - 0.38515371084213257, - -0.07315804064273834, - 0.8780375719070435 - ], - [ - 0.12963341176509857, - -0.6663824319839478, - 0.4921484887599945, - -0.9834228754043579 - ], - [ - -1.2953417301177979, - -1.5002580881118774, - 1.1558160781860352, - -0.7528656125068665 - ] + [-1.0694472789764404, 0.08452916890382767, 0.33887022733688354, -1.223060965538025], + [0.19821691513061523, 0.38515371084213257, -0.07315804064273834, 0.8780375719070435], + [0.12963341176509857, -0.6663824319839478, 0.4921484887599945, -0.9834228754043579], + [-1.2953417301177979, -1.5002580881118774, 1.1558160781860352, -0.7528656125068665] ], [ - [ - 0.589937686920166, - -1.330565333366394, - 1.276455044746399, - -1.1509960889816284 - ], - [ - 1.4542961120605469, - 0.21978320181369781, - -0.26515746116638184, - 0.7749262452125549 - ], - [ - 0.12985540926456451, - 1.0439496040344238, - -1.7788974046707153, - 0.3559875190258026 - ], - [ - -0.05403977632522583, - 0.07127834856510162, - -0.8058504462242126, - -0.35074129700660706 - ] + [0.589937686920166, -1.330565333366394, 1.276455044746399, -1.1509960889816284], + [1.4542961120605469, 0.21978320181369781, -0.26515746116638184, 0.7749262452125549], + [0.12985540926456451, 1.0439496040344238, -1.7788974046707153, 0.3559875190258026], + [-0.05403977632522583, 0.07127834856510162, -0.8058504462242126, -0.35074129700660706] ], [ - [ - 1.1279785633087158, - 0.02586616761982441, - -0.14947263896465302, - 0.39506977796554565 - ], - [ - 1.9742354154586792, - -0.4404173791408539, - 2.3815414905548096, - -0.34589144587516785 - ], - [ - 2.694831609725952, - -0.8544124364852905, - -0.27781322598457336, - 0.7772916555404663 - ], - [ - -0.43923330307006836, - 1.1729096174240112, - 1.397361159324646, - -0.41255858540534973 - ] + [1.1279785633087158, 0.02586616761982441, -0.14947263896465302, 0.39506977796554565], + [1.9742354154586792, -0.4404173791408539, 2.3815414905548096, -0.34589144587516785], + [2.694831609725952, -0.8544124364852905, -0.27781322598457336, 0.7772916555404663], + [-0.43923330307006836, 1.1729096174240112, 1.397361159324646, -0.41255858540534973] ] ] ] @@ -17274,138 +5229,66 @@ export const testData = { [ [ [ - [ - -0.04464086890220642, - 0.13030219078063965 - ], - [ - 0.19273826479911804, - 0.19454172253608704 - ] + [-0.04464086890220642, 0.13030219078063965], + [0.19273826479911804, 0.19454172253608704] ], [ - [ - -0.18497413396835327, - 0.017949223518371582 - ], - [ - -0.20529252290725708, - -0.17236840724945068 - ] + [-0.18497413396835327, 0.017949223518371582], + [-0.20529252290725708, -0.17236840724945068] ] ], [ [ - [ - 0.1919710338115692, - -0.19917979836463928 - ], - [ - -0.12260425090789795, - 0.11989259719848633 - ] + [0.1919710338115692, -0.19917979836463928], + [-0.12260425090789795, 0.11989259719848633] ], [ - [ - 0.24324333667755127, - -0.2428540289402008 - ], - [ - -0.1613200604915619, - -0.0980333685874939 - ] + [0.24324333667755127, -0.2428540289402008], + [-0.1613200604915619, -0.0980333685874939] ] ] ], [ [ [ - [ - 0.19366449117660522, - 0.14569279551506042 - ], - [ - 0.1558559536933899, - 0.16019022464752197 - ] + [0.19366449117660522, 0.14569279551506042], + [0.1558559536933899, 0.16019022464752197] ], [ - [ - -0.06256577372550964, - 0.18433409929275513 - ], - [ - -0.007025092840194702, - 0.023488402366638184 - ] + [-0.06256577372550964, 0.18433409929275513], + [-0.007025092840194702, 0.023488402366638184] ] ], [ [ - [ - -0.06629806756973267, - 0.10605272650718689 - ], - [ - 0.11164060235023499, - -0.02650010585784912 - ] + [-0.06629806756973267, 0.10605272650718689], + [0.11164060235023499, -0.02650010585784912] ], [ - [ - 0.22008481621742249, - -0.06474655866622925 - ], - [ - 0.06327742338180542, - 0.22706493735313416 - ] + [0.22008481621742249, -0.06474655866622925], + [0.06327742338180542, 0.22706493735313416] ] ] ], [ [ [ - [ - 0.14085400104522705, - -0.09103536605834961 - ], - [ - -0.11324527859687805, - 0.048248857259750366 - ] + [0.14085400104522705, -0.09103536605834961], + [-0.11324527859687805, 0.048248857259750366] ], [ - [ - -0.0018947124481201172, - 0.017594724893569946 - ], - [ - 0.1610410511493683, - 0.08738741278648376 - ] + [-0.0018947124481201172, 0.017594724893569946], + [0.1610410511493683, 0.08738741278648376] ] ], [ [ - [ - -0.14021095633506775, - -0.2041163444519043 - ], - [ - 0.23635441064834595, - -0.027522504329681396 - ] + [-0.14021095633506775, -0.2041163444519043], + [0.23635441064834595, -0.027522504329681396] ], [ - [ - -0.09849092364311218, - -0.18361523747444153 - ], - [ - 0.24006971716880798, - 0.1261514127254486 - ] + [-0.09849092364311218, -0.18361523747444153], + [0.24006971716880798, 0.1261514127254486] ] ] ] @@ -17414,322 +5297,106 @@ export const testData = { [ [ [ - [ - -0.5038596987724304, - -0.11328840255737305, - -0.29208752512931824 - ], - [ - -0.4790585935115814, - -1.2338014841079712, - 0.3766993582248688 - ], - [ - -0.037682030349969864, - -0.08873514086008072, - 0.21263472735881805 - ] + [-0.5038596987724304, -0.11328840255737305, -0.29208752512931824], + [-0.4790585935115814, -1.2338014841079712, 0.3766993582248688], + [-0.037682030349969864, -0.08873514086008072, 0.21263472735881805] ], [ - [ - -0.011624469421803951, - 0.1745271384716034, - -0.261569619178772 - ], - [ - 0.19541247189044952, - -0.7095012068748474, - 0.8612315058708191 - ], - [ - 0.06318911164999008, - 0.3058077394962311, - -0.19460046291351318 - ] + [-0.011624469421803951, 0.1745271384716034, -0.261569619178772], + [0.19541247189044952, -0.7095012068748474, 0.8612315058708191], + [0.06318911164999008, 0.3058077394962311, -0.19460046291351318] ], [ - [ - 0.1381525844335556, - 0.3578319549560547, - 0.11980266869068146 - ], - [ - 0.05987616628408432, - 0.06979464739561081, - -0.1939573585987091 - ], - [ - -0.5021116137504578, - -0.3473271131515503, - -0.7380265593528748 - ] + [0.1381525844335556, 0.3578319549560547, 0.11980266869068146], + [0.05987616628408432, 0.06979464739561081, -0.1939573585987091], + [-0.5021116137504578, -0.3473271131515503, -0.7380265593528748] ] ], [ [ - [ - -0.006691743154078722, - -0.46675175428390503, - -0.30486610531806946 - ], - [ - -0.288819819688797, - -0.24890491366386414, - -0.0010907119140028954 - ], - [ - -0.25320446491241455, - 0.200725257396698, - 0.08494552969932556 - ] + [-0.006691743154078722, -0.46675175428390503, -0.30486610531806946], + [-0.288819819688797, -0.24890491366386414, -0.0010907119140028954], + [-0.25320446491241455, 0.200725257396698, 0.08494552969932556] ], [ - [ - -0.2806292176246643, - 0.02707899920642376, - -0.6591119170188904 - ], - [ - -0.1579609364271164, - -0.25223442912101746, - 0.30185988545417786 - ], - [ - -0.28836485743522644, - 0.31437602639198303, - -0.462564080953598 - ] + [-0.2806292176246643, 0.02707899920642376, -0.6591119170188904], + [-0.1579609364271164, -0.25223442912101746, 0.30185988545417786], + [-0.28836485743522644, 0.31437602639198303, -0.462564080953598] ], [ - [ - -0.008080392144620419, - 0.0004768797953147441, - -0.06643328815698624 - ], - [ - -0.3503379225730896, - 0.5052304267883301, - -0.3877430558204651 - ], - [ - 0.04400258883833885, - -0.31729790568351746, - 0.3766254782676697 - ] + [-0.008080392144620419, 0.0004768797953147441, -0.06643328815698624], + [-0.3503379225730896, 0.5052304267883301, -0.3877430558204651], + [0.04400258883833885, -0.31729790568351746, 0.3766254782676697] ] ], [ [ - [ - 0.4502900540828705, - -0.050775207579135895, - 0.18275459110736847 - ], - [ - -0.04413630813360214, - 0.6116383075714111, - -0.27849501371383667 - ], - [ - 0.3069579303264618, - -0.2600867450237274, - 0.09250245988368988 - ] + [0.4502900540828705, -0.050775207579135895, 0.18275459110736847], + [-0.04413630813360214, 0.6116383075714111, -0.27849501371383667], + [0.3069579303264618, -0.2600867450237274, 0.09250245988368988] ], [ - [ - 0.17954453825950623, - -0.013814925216138363, - 0.06049893796443939 - ], - [ - 0.2202102690935135, - -0.1964309960603714, - 0.11200179904699326 - ], - [ - 0.47461840510368347, - -0.022217681631445885, - 0.23181389272212982 - ] + [0.17954453825950623, -0.013814925216138363, 0.06049893796443939], + [0.2202102690935135, -0.1964309960603714, 0.11200179904699326], + [0.47461840510368347, -0.022217681631445885, 0.23181389272212982] ], [ - [ - 0.27409666776657104, - 0.18343980610370636, - -0.005225253291428089 - ], - [ - 0.16232147812843323, - 0.5799760222434998, - 0.27901557087898254 - ], - [ - -0.21531707048416138, - 0.07970071583986282, - 0.8787646293640137 - ] + [0.27409666776657104, 0.18343980610370636, -0.005225253291428089], + [0.16232147812843323, 0.5799760222434998, 0.27901557087898254], + [-0.21531707048416138, 0.07970071583986282, 0.8787646293640137] ] ] ], [ [ [ - [ - -0.48178449273109436, - 0.32926392555236816, - -0.3285866677761078 - ], - [ - 0.5264294147491455, - -0.1760045886039734, - 0.036700669676065445 - ], - [ - -0.07904969900846481, - 0.2851441204547882, - 0.38437163829803467 - ] + [-0.48178449273109436, 0.32926392555236816, -0.3285866677761078], + [0.5264294147491455, -0.1760045886039734, 0.036700669676065445], + [-0.07904969900846481, 0.2851441204547882, 0.38437163829803467] ], [ - [ - -0.1296009123325348, - -0.2551492750644684, - 0.9022114276885986 - ], - [ - -0.8898090720176697, - 0.12122566252946854, - 0.5932097434997559 - ], - [ - 0.10692428052425385, - -0.529249370098114, - -0.5071446299552917 - ] + [-0.1296009123325348, -0.2551492750644684, 0.9022114276885986], + [-0.8898090720176697, 0.12122566252946854, 0.5932097434997559], + [0.10692428052425385, -0.529249370098114, -0.5071446299552917] ], [ - [ - -0.28801897168159485, - -0.17852434515953064, - -0.2552545666694641 - ], - [ - -0.13078252971172333, - -0.30658066272735596, - 0.12897521257400513 - ], - [ - -0.24208368360996246, - -0.13765157759189606, - -0.2857514023780823 - ] + [-0.28801897168159485, -0.17852434515953064, -0.2552545666694641], + [-0.13078252971172333, -0.30658066272735596, 0.12897521257400513], + [-0.24208368360996246, -0.13765157759189606, -0.2857514023780823] ] ], [ [ - [ - 0.3810115158557892, - -0.18917249143123627, - -0.02831784449517727 - ], - [ - -0.5640672445297241, - -0.8773369789123535, - 0.01873210072517395 - ], - [ - -0.38767924904823303, - 0.045399442315101624, - 0.18848949670791626 - ] + [0.3810115158557892, -0.18917249143123627, -0.02831784449517727], + [-0.5640672445297241, -0.8773369789123535, 0.01873210072517395], + [-0.38767924904823303, 0.045399442315101624, 0.18848949670791626] ], [ - [ - 0.040571633726358414, - 0.01593371294438839, - -0.24737092852592468 - ], - [ - -0.20651893317699432, - 0.14015652239322662, - -0.2224198579788208 - ], - [ - -0.5507435202598572, - -0.09074224531650543, - -0.6494090557098389 - ] + [0.040571633726358414, 0.01593371294438839, -0.24737092852592468], + [-0.20651893317699432, 0.14015652239322662, -0.2224198579788208], + [-0.5507435202598572, -0.09074224531650543, -0.6494090557098389] ], [ - [ - -0.4638271629810333, - -0.21157491207122803, - -0.21089521050453186 - ], - [ - 0.015379182994365692, - 0.5860069394111633, - 0.3198734223842621 - ], - [ - -0.453792542219162, - -0.18119028210639954, - 0.019968409091234207 - ] + [-0.4638271629810333, -0.21157491207122803, -0.21089521050453186], + [0.015379182994365692, 0.5860069394111633, 0.3198734223842621], + [-0.453792542219162, -0.18119028210639954, 0.019968409091234207] ] ], [ [ - [ - 0.5788699984550476, - -0.20849919319152832, - 0.6697774529457092 - ], - [ - 0.0391685776412487, - -0.27752864360809326, - 0.48812031745910645 - ], - [ - 0.27291446924209595, - 0.5477061867713928, - 0.0609532967209816 - ] + [0.5788699984550476, -0.20849919319152832, 0.6697774529457092], + [0.0391685776412487, -0.27752864360809326, 0.48812031745910645], + [0.27291446924209595, 0.5477061867713928, 0.0609532967209816] ], [ - [ - 0.30921193957328796, - 0.11291491240262985, - -0.8780627250671387 - ], - [ - 0.28316259384155273, - 0.3493956923484802, - -0.5359333753585815 - ], - [ - 0.4598090946674347, - 0.3901137113571167, - 0.10830800980329514 - ] + [0.30921193957328796, 0.11291491240262985, -0.8780627250671387], + [0.28316259384155273, 0.3493956923484802, -0.5359333753585815], + [0.4598090946674347, 0.3901137113571167, 0.10830800980329514] ], [ - [ - 0.12046888470649719, - 0.037027567625045776, - 0.33895567059516907 - ], - [ - -0.27672937512397766, - -0.49539312720298767, - 0.21685229241847992 - ], - [ - 0.42636412382125854, - -0.33751899003982544, - 0.4266938269138336 - ] + [0.12046888470649719, 0.037027567625045776, 0.33895567059516907], + [-0.27672937512397766, -0.49539312720298767, 0.21685229241847992], + [0.42636412382125854, -0.33751899003982544, 0.4266938269138336] ] ] ] @@ -17738,428 +5405,108 @@ export const testData = { [ [ [ - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ], - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ] + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303], + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303] ], [ - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ], - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ] + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585], + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585] ], [ - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ], - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ] + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303], + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303] ], [ - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ], - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ] + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585], + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585] ] ], [ [ - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ], - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ] + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616], + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616] ], [ - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ], - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ] + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201], + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201] ], [ - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ], - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ] + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616], + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616] ], [ - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ], - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ] + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201], + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201] ] ] ], [ [ [ - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ], - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ] + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303], + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303] ], [ - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ], - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ] + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585], + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585] ], [ - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ], - [ - -0.061492592096328735, - -0.051276564598083496, - -0.061492592096328735, - -0.051276564598083496 - ], - [ - 0.21987804770469666, - -0.24943462014198303, - 0.21987804770469666, - -0.24943462014198303 - ] + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303], + [-0.061492592096328735, -0.051276564598083496, -0.061492592096328735, -0.051276564598083496], + [0.21987804770469666, -0.24943462014198303, 0.21987804770469666, -0.24943462014198303] ], [ - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ], - [ - 0.4029808044433594, - 0.23534893989562988, - 0.4029808044433594, - 0.23534893989562988 - ], - [ - 0.18495962023735046, - 0.28987762331962585, - 0.18495962023735046, - 0.28987762331962585 - ] + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585], + [0.4029808044433594, 0.23534893989562988, 0.4029808044433594, 0.23534893989562988], + [0.18495962023735046, 0.28987762331962585, 0.18495962023735046, 0.28987762331962585] ] ], [ [ - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ], - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ] + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616], + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616] ], [ - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ], - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ] + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201], + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201] ], [ - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ], - [ - 0.25518298149108887, - 0.1420270800590515, - 0.25518298149108887, - 0.1420270800590515 - ], - [ - -0.4912158250808716, - 0.3648372292518616, - -0.4912158250808716, - 0.3648372292518616 - ] + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616], + [0.25518298149108887, 0.1420270800590515, 0.25518298149108887, 0.1420270800590515], + [-0.4912158250808716, 0.3648372292518616, -0.4912158250808716, 0.3648372292518616] ], [ - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ], - [ - 0.06586998701095581, - 0.22539076209068298, - 0.06586998701095581, - 0.22539076209068298 - ], - [ - -0.2972434163093567, - -0.014537990093231201, - -0.2972434163093567, - -0.014537990093231201 - ] + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201], + [0.06586998701095581, 0.22539076209068298, 0.06586998701095581, 0.22539076209068298], + [-0.2972434163093567, -0.014537990093231201, -0.2972434163093567, -0.014537990093231201] ] ] ] @@ -18168,152 +5515,72 @@ export const testData = { [ [ [ - [ - 2.0645761489868164, - 1.082654595375061 - ], - [ - 9.614883422851562, - -0.7942436933517456 - ] + [2.0645761489868164, 1.082654595375061], + [9.614883422851562, -0.7942436933517456] ], [ - [ - -2.149080514907837, - 4.818809986114502 - ], - [ - -4.0391926765441895, - -3.070486307144165 - ] + [-2.149080514907837, 4.818809986114502], + [-4.0391926765441895, -3.070486307144165] ] ], [ [ - [ - -2.5816783905029297, - 5.9409565925598145 - ], - [ - -3.1585464477539062, - 3.6483538150787354 - ] + [-2.5816783905029297, 5.9409565925598145], + [-3.1585464477539062, 3.6483538150787354] ], [ - [ - 7.604015350341797, - 1.6200573444366455 - ], - [ - 1.0454699993133545, - 0.24501657485961914 - ] + [7.604015350341797, 1.6200573444366455], + [1.0454699993133545, 0.24501657485961914] ] ] ], [ [ [ - [ - 2.0645761489868164, - 1.082654595375061 - ], - [ - 9.614883422851562, - -0.7942436933517456 - ] + [2.0645761489868164, 1.082654595375061], + [9.614883422851562, -0.7942436933517456] ], [ - [ - -2.149080514907837, - 4.818809986114502 - ], - [ - -4.0391926765441895, - -3.070486307144165 - ] + [-2.149080514907837, 4.818809986114502], + [-4.0391926765441895, -3.070486307144165] ] ], [ [ - [ - -2.5816783905029297, - 5.9409565925598145 - ], - [ - -3.1585464477539062, - 3.6483538150787354 - ] + [-2.5816783905029297, 5.9409565925598145], + [-3.1585464477539062, 3.6483538150787354] ], [ - [ - 7.604015350341797, - 1.6200573444366455 - ], - [ - 1.0454699993133545, - 0.24501657485961914 - ] + [7.604015350341797, 1.6200573444366455], + [1.0454699993133545, 0.24501657485961914] ] ] ], [ [ [ - [ - 2.0645761489868164, - 1.082654595375061 - ], - [ - 9.614883422851562, - -0.7942436933517456 - ] + [2.0645761489868164, 1.082654595375061], + [9.614883422851562, -0.7942436933517456] ], [ - [ - -2.149080514907837, - 4.818809986114502 - ], - [ - -4.0391926765441895, - -3.070486307144165 - ] + [-2.149080514907837, 4.818809986114502], + [-4.0391926765441895, -3.070486307144165] ] ], [ [ - [ - -2.5816783905029297, - 5.9409565925598145 - ], - [ - -3.1585464477539062, - 3.6483538150787354 - ] + [-2.5816783905029297, 5.9409565925598145], + [-3.1585464477539062, 3.6483538150787354] ], [ - [ - 7.604015350341797, - 1.6200573444366455 - ], - [ - 1.0454699993133545, - 0.24501657485961914 - ] + [7.604015350341797, 1.6200573444366455], + [1.0454699993133545, 0.24501657485961914] ] ] ] ], - "bias": [ - -0.15848389267921448, - -0.21591666340827942, - 0.21718040108680725 - ], - "expected_grad_bias": [ - 54.0, - 54.0, - 54.0 - ] + "bias": [-0.15848389267921448, -0.21591666340827942, 0.21718040108680725], + "expected_grad_bias": [54.0, 54.0, 54.0] }, { "test_name": "conv3d_dilation_no_bias", @@ -18330,376 +5597,76 @@ export const testData = { [ [ [ - [ - -0.17826782166957855, - -0.2625838816165924, - 0.7513576745986938, - 0.18278615176677704, - -0.9977543950080872 - ], - [ - 0.45807182788848877, - 0.7924372553825378, - -0.9643475413322449, - 0.46591266989707947, - 1.3539252281188965 - ], - [ - -1.459295630455017, - 0.37469375133514404, - 0.7460726499557495, - 0.26590028405189514, - -1.0854178667068481 - ], - [ - -1.5084643363952637, - -0.4339471161365509, - 0.9574882388114929, - 1.254128336906433, - -1.0384563207626343 - ], - [ - 0.5251074433326721, - -0.8383287787437439, - 1.7227904796600342, - -1.1731188297271729, - 0.7272883057594299 - ] + [-0.17826782166957855, -0.2625838816165924, 0.7513576745986938, 0.18278615176677704, -0.9977543950080872], + [0.45807182788848877, 0.7924372553825378, -0.9643475413322449, 0.46591266989707947, 1.3539252281188965], + [-1.459295630455017, 0.37469375133514404, 0.7460726499557495, 0.26590028405189514, -1.0854178667068481], + [-1.5084643363952637, -0.4339471161365509, 0.9574882388114929, 1.254128336906433, -1.0384563207626343], + [0.5251074433326721, -0.8383287787437439, 1.7227904796600342, -1.1731188297271729, 0.7272883057594299] ], [ - [ - -1.7194626331329346, - 2.383774995803833, - -1.1649107933044434, - -0.20503655076026917, - -0.5375787019729614 - ], - [ - 1.2967820167541504, - -1.6138769388198853, - -0.8155969977378845, - -0.1509992778301239, - -0.5020706653594971 - ], - [ - 0.8036778569221497, - -1.1333380937576294, - -0.7435185313224792, - -0.7013434171676636, - -0.42178988456726074 - ], - [ - -1.5332636833190918, - -1.9342981576919556, - 0.3510490953922272, - -0.6404718160629272, - 0.019135747104883194 - ], - [ - -0.7149955034255981, - -0.7025302648544312, - 0.7700265645980835, - 0.9396787285804749, - 1.0826958417892456 - ] + [-1.7194626331329346, 2.383774995803833, -1.1649107933044434, -0.20503655076026917, -0.5375787019729614], + [1.2967820167541504, -1.6138769388198853, -0.8155969977378845, -0.1509992778301239, -0.5020706653594971], + [0.8036778569221497, -1.1333380937576294, -0.7435185313224792, -0.7013434171676636, -0.42178988456726074], + [-1.5332636833190918, -1.9342981576919556, 0.3510490953922272, -0.6404718160629272, 0.019135747104883194], + [-0.7149955034255981, -0.7025302648544312, 0.7700265645980835, 0.9396787285804749, 1.0826958417892456] ], [ - [ - -0.6519155502319336, - 0.2863307297229767, - 0.10145679116249084, - 0.09791278839111328, - -0.8082833886146545 - ], - [ - 1.441809892654419, - -0.6460452675819397, - 0.04811352491378784, - 1.382570505142212, - -0.6665758490562439 - ], - [ - 0.7876792550086975, - -0.15957334637641907, - -0.10303135216236115, - 0.27407389879226685, - 1.1576530933380127 - ], - [ - -0.21968594193458557, - 0.4215473532676697, - -0.32665783166885376, - 2.3412764072418213, - -0.5351880192756653 - ], - [ - 1.0548261404037476, - -0.4031357765197754, - 0.6454427242279053, - -0.6314883828163147, - -1.2809436321258545 - ] + [-0.6519155502319336, 0.2863307297229767, 0.10145679116249084, 0.09791278839111328, -0.8082833886146545], + [1.441809892654419, -0.6460452675819397, 0.04811352491378784, 1.382570505142212, -0.6665758490562439], + [0.7876792550086975, -0.15957334637641907, -0.10303135216236115, 0.27407389879226685, 1.1576530933380127], + [-0.21968594193458557, 0.4215473532676697, -0.32665783166885376, 2.3412764072418213, -0.5351880192756653], + [1.0548261404037476, -0.4031357765197754, 0.6454427242279053, -0.6314883828163147, -1.2809436321258545] ], [ - [ - 0.009232764132320881, - 1.2330046892166138, - 0.6238497495651245, - 1.5213422775268555, - -0.4976206421852112 - ], - [ - 0.7535606026649475, - -0.38888975977897644, - 2.5921998023986816, - 0.08543383330106735, - -2.0308878421783447 - ], - [ - 0.6461803913116455, - 1.217452883720398, - 0.03121299482882023, - 1.082465648651123, - -1.8998514413833618 - ], - [ - -2.7074427604675293, - -0.7867730259895325, - -0.6195639967918396, - 1.8281400203704834, - 0.4877544343471527 - ], - [ - 0.1366790533065796, - -0.7571792006492615, - -1.0642281770706177, - 1.9611531496047974, - -0.4390997588634491 - ] + [0.009232764132320881, 1.2330046892166138, 0.6238497495651245, 1.5213422775268555, -0.4976206421852112], + [0.7535606026649475, -0.38888975977897644, 2.5921998023986816, 0.08543383330106735, -2.0308878421783447], + [0.6461803913116455, 1.217452883720398, 0.03121299482882023, 1.082465648651123, -1.8998514413833618], + [-2.7074427604675293, -0.7867730259895325, -0.6195639967918396, 1.8281400203704834, 0.4877544343471527], + [0.1366790533065796, -0.7571792006492615, -1.0642281770706177, 1.9611531496047974, -0.4390997588634491] ], [ - [ - 0.8920031785964966, - 1.8720558881759644, - 0.24501417577266693, - 0.7017510533332825, - 0.9099079370498657 - ], - [ - -0.7323962450027466, - -0.6663155555725098, - -0.3277064561843872, - -1.439155101776123, - -1.2797472476959229 - ], - [ - -0.19622953236103058, - 0.19903564453125, - -0.5971476435661316, - -1.0348221063613892, - 0.42101818323135376 - ], - [ - -0.548947811126709, - -1.2540193796157837, - -1.2696188688278198, - 0.6492337584495544, - 0.2340298593044281 - ], - [ - -0.1553155928850174, - -0.4344737231731415, - -1.0962450504302979, - -1.122981309890747, - -1.865479826927185 - ] + [0.8920031785964966, 1.8720558881759644, 0.24501417577266693, 0.7017510533332825, 0.9099079370498657], + [-0.7323962450027466, -0.6663155555725098, -0.3277064561843872, -1.439155101776123, -1.2797472476959229], + [-0.19622953236103058, 0.19903564453125, -0.5971476435661316, -1.0348221063613892, 0.42101818323135376], + [-0.548947811126709, -1.2540193796157837, -1.2696188688278198, 0.6492337584495544, 0.2340298593044281], + [-0.1553155928850174, -0.4344737231731415, -1.0962450504302979, -1.122981309890747, -1.865479826927185] ] ], [ [ - [ - -2.1207547187805176, - -0.6719433665275574, - -0.7559810280799866, - -1.0449823141098022, - -0.27992430329322815 - ], - [ - 1.2101659774780273, - -0.9885204434394836, - 0.350207656621933, - -0.2644238770008087, - -1.0631657838821411 - ], - [ - -0.7474985122680664, - 0.3266002833843231, - -0.49929699301719666, - -1.4715039730072021, - 0.5023646950721741 - ], - [ - 0.4279913902282715, - 1.0040385723114014, - 1.708235263824463, - -0.2667044997215271, - -0.5910199284553528 - ], - [ - 2.3618080615997314, - 1.2076122760772705, - -0.5487976670265198, - 1.5311497449874878, - 0.44362834095954895 - ] + [-2.1207547187805176, -0.6719433665275574, -0.7559810280799866, -1.0449823141098022, -0.27992430329322815], + [1.2101659774780273, -0.9885204434394836, 0.350207656621933, -0.2644238770008087, -1.0631657838821411], + [-0.7474985122680664, 0.3266002833843231, -0.49929699301719666, -1.4715039730072021, 0.5023646950721741], + [0.4279913902282715, 1.0040385723114014, 1.708235263824463, -0.2667044997215271, -0.5910199284553528], + [2.3618080615997314, 1.2076122760772705, -0.5487976670265198, 1.5311497449874878, 0.44362834095954895] ], [ - [ - -2.4579336643218994, - 0.6496618390083313, - 0.02449978142976761, - 0.25982725620269775, - 0.7348682284355164 - ], - [ - -0.006029692944139242, - -0.7884382605552673, - 1.1371253728866577, - -1.7366209030151367, - 0.9614791870117188 - ], - [ - -0.48808231949806213, - -0.6568363904953003, - -0.4720822274684906, - 0.35971710085868835, - 0.5307507514953613 - ], - [ - 1.0079243183135986, - 1.6095112562179565, - 1.6016820669174194, - 0.020138248801231384, - 0.573236346244812 - ], - [ - 0.37203314900398254, - 0.22609540820121765, - -0.754463255405426, - -0.3379971385002136, - 0.41659975051879883 - ] + [-2.4579336643218994, 0.6496618390083313, 0.02449978142976761, 0.25982725620269775, 0.7348682284355164], + [-0.006029692944139242, -0.7884382605552673, 1.1371253728866577, -1.7366209030151367, 0.9614791870117188], + [-0.48808231949806213, -0.6568363904953003, -0.4720822274684906, 0.35971710085868835, 0.5307507514953613], + [1.0079243183135986, 1.6095112562179565, 1.6016820669174194, 0.020138248801231384, 0.573236346244812], + [0.37203314900398254, 0.22609540820121765, -0.754463255405426, -0.3379971385002136, 0.41659975051879883] ], [ - [ - 0.22890278697013855, - 0.1943359375, - 1.0423648357391357, - -1.1257092952728271, - -0.04083564877510071 - ], - [ - 0.7159355282783508, - 0.3418067395687103, - -0.6778577566146851, - 0.17783714830875397, - -0.16209769248962402 - ], - [ - -0.026765741407871246, - -0.33800795674324036, - 0.6160297393798828, - -1.5755101442337036, - -1.1856271028518677 - ], - [ - 0.3281179666519165, - -0.03522142022848129, - 0.18906556069850922, - 1.0375696420669556, - 0.7793638706207275 - ], - [ - -0.6498270630836487, - -0.48095330595970154, - 0.13058727979660034, - 0.8354679346084595, - 1.6123450994491577 - ] + [0.22890278697013855, 0.1943359375, 1.0423648357391357, -1.1257092952728271, -0.04083564877510071], + [0.7159355282783508, 0.3418067395687103, -0.6778577566146851, 0.17783714830875397, -0.16209769248962402], + [-0.026765741407871246, -0.33800795674324036, 0.6160297393798828, -1.5755101442337036, -1.1856271028518677], + [0.3281179666519165, -0.03522142022848129, 0.18906556069850922, 1.0375696420669556, 0.7793638706207275], + [-0.6498270630836487, -0.48095330595970154, 0.13058727979660034, 0.8354679346084595, 1.6123450994491577] ], [ - [ - -0.4939593970775604, - 0.30456098914146423, - 2.1306238174438477, - 0.026654772460460663, - 0.7856671810150146 - ], - [ - 0.8128212690353394, - 0.04477962106466293, - -1.7439521551132202, - -1.3104760646820068, - -1.4218922853469849 - ], - [ - -0.3201002776622772, - 0.011662798002362251, - 0.7528783082962036, - -0.8849666118621826, - 0.8982152342796326 - ], - [ - -1.6744109392166138, - -1.1447242498397827, - 0.22346419095993042, - -0.9369489550590515, - -0.17544429004192352 - ], - [ - 0.8354768753051758, - -1.2516489028930664, - 0.26434803009033203, - 1.2949540615081787, - -0.5443984270095825 - ] + [-0.4939593970775604, 0.30456098914146423, 2.1306238174438477, 0.026654772460460663, 0.7856671810150146], + [0.8128212690353394, 0.04477962106466293, -1.7439521551132202, -1.3104760646820068, -1.4218922853469849], + [-0.3201002776622772, 0.011662798002362251, 0.7528783082962036, -0.8849666118621826, 0.8982152342796326], + [-1.6744109392166138, -1.1447242498397827, 0.22346419095993042, -0.9369489550590515, -0.17544429004192352], + [0.8354768753051758, -1.2516489028930664, 0.26434803009033203, 1.2949540615081787, -0.5443984270095825] ], [ - [ - 2.050001859664917, - 0.06459449976682663, - 1.448185920715332, - -0.20686893165111542, - 1.5211719274520874 - ], - [ - -1.2341058254241943, - -0.7871248126029968, - -0.7268313765525818, - -0.26047298312187195, - 2.041553020477295 - ], - [ - -0.4606938660144806, - -0.6203854084014893, - 1.3424702882766724, - -1.7992236614227295, - -1.2398992776870728 - ], - [ - -1.1074808835983276, - -0.6043308973312378, - 0.0955897644162178, - 1.1224497556686401, - -0.06249626725912094 - ], - [ - -0.4906177818775177, - -1.3847423791885376, - 0.8051268458366394, - 1.1163915395736694, - 0.4140532910823822 - ] + [2.050001859664917, 0.06459449976682663, 1.448185920715332, -0.20686893165111542, 1.5211719274520874], + [-1.2341058254241943, -0.7871248126029968, -0.7268313765525818, -0.26047298312187195, 2.041553020477295], + [-0.4606938660144806, -0.6203854084014893, 1.3424702882766724, -1.7992236614227295, -1.2398992776870728], + [-1.1074808835983276, -0.6043308973312378, 0.0955897644162178, 1.1224497556686401, -0.06249626725912094], + [-0.4906177818775177, -1.3847423791885376, 0.8051268458366394, 1.1163915395736694, 0.4140532910823822] ] ] ] @@ -18708,92 +5675,44 @@ export const testData = { [ [ [ - [ - -0.1400585174560547, - -0.1189696192741394 - ], - [ - -0.1396593451499939, - 0.06799721717834473 - ] + [-0.1400585174560547, -0.1189696192741394], + [-0.1396593451499939, 0.06799721717834473] ], [ - [ - 0.11712342500686646, - 0.16814139485359192 - ], - [ - -0.14146676659584045, - -0.05842772126197815 - ] + [0.11712342500686646, 0.16814139485359192], + [-0.14146676659584045, -0.05842772126197815] ] ], [ [ - [ - 0.23335561156272888, - -0.12842318415641785 - ], - [ - -0.0903659462928772, - -0.048071324825286865 - ] + [0.23335561156272888, -0.12842318415641785], + [-0.0903659462928772, -0.048071324825286865] ], [ - [ - -0.22137033939361572, - -0.1847814917564392 - ], - [ - 0.22272253036499023, - 0.046148449182510376 - ] + [-0.22137033939361572, -0.1847814917564392], + [0.22272253036499023, 0.046148449182510376] ] ] ], [ [ [ - [ - 0.046710461378097534, - 0.09910747408866882 - ], - [ - 0.15203699469566345, - 0.1679282784461975 - ] + [0.046710461378097534, 0.09910747408866882], + [0.15203699469566345, 0.1679282784461975] ], [ - [ - 0.17905914783477783, - 0.10090303421020508 - ], - [ - 0.18846681714057922, - 0.16334408521652222 - ] + [0.17905914783477783, 0.10090303421020508], + [0.18846681714057922, 0.16334408521652222] ] ], [ [ - [ - -0.04180261492729187, - 0.02251899242401123 - ], - [ - -0.13095378875732422, - -0.18811622262001038 - ] + [-0.04180261492729187, 0.02251899242401123], + [-0.13095378875732422, -0.18811622262001038] ], [ - [ - 0.23712044954299927, - -0.18616604804992676 - ], - [ - -0.15629222989082336, - -0.2414878010749817 - ] + [0.23712044954299927, -0.18616604804992676], + [-0.15629222989082336, -0.2414878010749817] ] ] ] @@ -18802,108 +5721,36 @@ export const testData = { [ [ [ - [ - -0.5016605257987976, - 0.0729646384716034, - -0.601827085018158 - ], - [ - 0.7186769247055054, - -0.40328311920166016, - 0.09108078479766846 - ], - [ - -0.49653488397598267, - 0.4543629586696625, - 0.03304469585418701 - ] + [-0.5016605257987976, 0.0729646384716034, -0.601827085018158], + [0.7186769247055054, -0.40328311920166016, 0.09108078479766846], + [-0.49653488397598267, 0.4543629586696625, 0.03304469585418701] ], [ - [ - -0.6014649868011475, - 0.01556580513715744, - -0.08095501363277435 - ], - [ - 0.5609210729598999, - 0.2705661654472351, - 0.8075739145278931 - ], - [ - 0.33128559589385986, - 0.4595896899700165, - -0.4482420086860657 - ] + [-0.6014649868011475, 0.01556580513715744, -0.08095501363277435], + [0.5609210729598999, 0.2705661654472351, 0.8075739145278931], + [0.33128559589385986, 0.4595896899700165, -0.4482420086860657] ], [ - [ - -0.6991593837738037, - 0.45764970779418945, - 0.3065469264984131 - ], - [ - 0.19239531457424164, - -0.004418909549713135, - -0.39568382501602173 - ], - [ - -0.489966481924057, - 0.31915783882141113, - 0.3014536499977112 - ] + [-0.6991593837738037, 0.45764970779418945, 0.3065469264984131], + [0.19239531457424164, -0.004418909549713135, -0.39568382501602173], + [-0.489966481924057, 0.31915783882141113, 0.3014536499977112] ] ], [ [ - [ - -0.026227392256259918, - 1.1108590364456177, - 0.4146382510662079 - ], - [ - -0.1955452859401703, - 0.4704682230949402, - -0.646715521812439 - ], - [ - 0.5727429389953613, - -0.8670409917831421, - 0.29973188042640686 - ] + [-0.026227392256259918, 1.1108590364456177, 0.4146382510662079], + [-0.1955452859401703, 0.4704682230949402, -0.646715521812439], + [0.5727429389953613, -0.8670409917831421, 0.29973188042640686] ], [ - [ - -0.39649078249931335, - 0.8576757907867432, - -0.5326414108276367 - ], - [ - -0.09169283509254456, - 0.03638267517089844, - -0.2939724922180176 - ], - [ - -0.3522647023200989, - 0.5533568859100342, - -0.08248010277748108 - ] + [-0.39649078249931335, 0.8576757907867432, -0.5326414108276367], + [-0.09169283509254456, 0.03638267517089844, -0.2939724922180176], + [-0.3522647023200989, 0.5533568859100342, -0.08248010277748108] ], [ - [ - -0.0021897554397583008, - 1.2117888927459717, - 0.4429609775543213 - ], - [ - -0.62223219871521, - -0.34632712602615356, - -1.2911615371704102 - ], - [ - -0.40977323055267334, - -0.46257489919662476, - -0.6323492527008057 - ] + [-0.0021897554397583008, 1.2117888927459717, 0.4429609775543213], + [-0.62223219871521, -0.34632712602615356, -1.2911615371704102], + [-0.40977323055267334, -0.46257489919662476, -0.6323492527008057] ] ] ] @@ -18912,376 +5759,76 @@ export const testData = { [ [ [ - [ - -0.09334805607795715, - -0.09334805607795715, - -0.11321020126342773, - -0.01986214518547058, - -0.01986214518547058 - ], - [ - -0.09334805607795715, - -0.09334805607795715, - -0.11321020126342773, - -0.01986214518547058, - -0.01986214518547058 - ], - [ - -0.0809704065322876, - -0.0809704065322876, - 0.13509294390678406, - 0.21606335043907166, - 0.21606335043907166 - ], - [ - 0.012377649545669556, - 0.012377649545669556, - 0.2483031451702118, - 0.23592549562454224, - 0.23592549562454224 - ], - [ - 0.012377649545669556, - 0.012377649545669556, - 0.2483031451702118, - 0.23592549562454224, - 0.23592549562454224 - ] + [-0.09334805607795715, -0.09334805607795715, -0.11321020126342773, -0.01986214518547058, -0.01986214518547058], + [-0.09334805607795715, -0.09334805607795715, -0.11321020126342773, -0.01986214518547058, -0.01986214518547058], + [-0.0809704065322876, -0.0809704065322876, 0.13509294390678406, 0.21606335043907166, 0.21606335043907166], + [0.012377649545669556, 0.012377649545669556, 0.2483031451702118, 0.23592549562454224, 0.23592549562454224], + [0.012377649545669556, 0.012377649545669556, 0.2483031451702118, 0.23592549562454224, 0.23592549562454224] ], [ - [ - -0.09334805607795715, - -0.09334805607795715, - -0.11321020126342773, - -0.01986214518547058, - -0.01986214518547058 - ], - [ - -0.09334805607795715, - -0.09334805607795715, - -0.11321020126342773, - -0.01986214518547058, - -0.01986214518547058 - ], - [ - -0.0809704065322876, - -0.0809704065322876, - 0.13509294390678406, - 0.21606335043907166, - 0.21606335043907166 - ], - [ - 0.012377649545669556, - 0.012377649545669556, - 0.2483031451702118, - 0.23592549562454224, - 0.23592549562454224 - ], - [ - 0.012377649545669556, - 0.012377649545669556, - 0.2483031451702118, - 0.23592549562454224, - 0.23592549562454224 - ] + [-0.09334805607795715, -0.09334805607795715, -0.11321020126342773, -0.01986214518547058, -0.01986214518547058], + [-0.09334805607795715, -0.09334805607795715, -0.11321020126342773, -0.01986214518547058, -0.01986214518547058], + [-0.0809704065322876, -0.0809704065322876, 0.13509294390678406, 0.21606335043907166, 0.21606335043907166], + [0.012377649545669556, 0.012377649545669556, 0.2483031451702118, 0.23592549562454224, 0.23592549562454224], + [0.012377649545669556, 0.012377649545669556, 0.2483031451702118, 0.23592549562454224, 0.23592549562454224] ], [ - [ - 0.20283451676368713, - 0.20283451676368713, - 0.45201680064201355, - 0.24918228387832642, - 0.24918228387832642 - ], - [ - 0.20283451676368713, - 0.20283451676368713, - 0.45201680064201355, - 0.24918228387832642, - 0.24918228387832642 - ], - [ - 0.26221221685409546, - 0.26221221685409546, - 0.8522363901138306, - 0.5900241136550903, - 0.5900241136550903 - ], - [ - 0.059377700090408325, - 0.059377700090408325, - 0.40021955966949463, - 0.3408418595790863, - 0.3408418595790863 - ], - [ - 0.059377700090408325, - 0.059377700090408325, - 0.40021955966949463, - 0.3408418595790863, - 0.3408418595790863 - ] + [0.20283451676368713, 0.20283451676368713, 0.45201680064201355, 0.24918228387832642, 0.24918228387832642], + [0.20283451676368713, 0.20283451676368713, 0.45201680064201355, 0.24918228387832642, 0.24918228387832642], + [0.26221221685409546, 0.26221221685409546, 0.8522363901138306, 0.5900241136550903, 0.5900241136550903], + [0.059377700090408325, 0.059377700090408325, 0.40021955966949463, 0.3408418595790863, 0.3408418595790863], + [0.059377700090408325, 0.059377700090408325, 0.40021955966949463, 0.3408418595790863, 0.3408418595790863] ], [ - [ - 0.2961825728416443, - 0.2961825728416443, - 0.5652270317077637, - 0.269044429063797, - 0.269044429063797 - ], - [ - 0.2961825728416443, - 0.2961825728416443, - 0.5652270317077637, - 0.269044429063797, - 0.269044429063797 - ], - [ - 0.34318262338638306, - 0.34318262338638306, - 0.7171434164047241, - 0.37396079301834106, - 0.37396079301834106 - ], - [ - 0.04700005054473877, - 0.04700005054473877, - 0.15191641449928284, - 0.10491636395454407, - 0.10491636395454407 - ], - [ - 0.04700005054473877, - 0.04700005054473877, - 0.15191641449928284, - 0.10491636395454407, - 0.10491636395454407 - ] + [0.2961825728416443, 0.2961825728416443, 0.5652270317077637, 0.269044429063797, 0.269044429063797], + [0.2961825728416443, 0.2961825728416443, 0.5652270317077637, 0.269044429063797, 0.269044429063797], + [0.34318262338638306, 0.34318262338638306, 0.7171434164047241, 0.37396079301834106, 0.37396079301834106], + [0.04700005054473877, 0.04700005054473877, 0.15191641449928284, 0.10491636395454407, 0.10491636395454407], + [0.04700005054473877, 0.04700005054473877, 0.15191641449928284, 0.10491636395454407, 0.10491636395454407] ], [ - [ - 0.2961825728416443, - 0.2961825728416443, - 0.5652270317077637, - 0.269044429063797, - 0.269044429063797 - ], - [ - 0.2961825728416443, - 0.2961825728416443, - 0.5652270317077637, - 0.269044429063797, - 0.269044429063797 - ], - [ - 0.34318262338638306, - 0.34318262338638306, - 0.7171434164047241, - 0.37396079301834106, - 0.37396079301834106 - ], - [ - 0.04700005054473877, - 0.04700005054473877, - 0.15191641449928284, - 0.10491636395454407, - 0.10491636395454407 - ], - [ - 0.04700005054473877, - 0.04700005054473877, - 0.15191641449928284, - 0.10491636395454407, - 0.10491636395454407 - ] + [0.2961825728416443, 0.2961825728416443, 0.5652270317077637, 0.269044429063797, 0.269044429063797], + [0.2961825728416443, 0.2961825728416443, 0.5652270317077637, 0.269044429063797, 0.269044429063797], + [0.34318262338638306, 0.34318262338638306, 0.7171434164047241, 0.37396079301834106, 0.37396079301834106], + [0.04700005054473877, 0.04700005054473877, 0.15191641449928284, 0.10491636395454407, 0.10491636395454407], + [0.04700005054473877, 0.04700005054473877, 0.15191641449928284, 0.10491636395454407, 0.10491636395454407] ] ], [ [ - [ - 0.191552996635437, - 0.191552996635437, - 0.0856488049030304, - -0.10590419173240662, - -0.10590419173240662 - ], - [ - 0.191552996635437, - 0.191552996635437, - 0.0856488049030304, - -0.10590419173240662, - -0.10590419173240662 - ], - [ - -0.029766738414764404, - -0.029766738414764404, - -0.37185847759246826, - -0.34209173917770386, - -0.34209173917770386 - ], - [ - -0.22131973505020142, - -0.22131973505020142, - -0.45750728249549866, - -0.23618754744529724, - -0.23618754744529724 - ], - [ - -0.22131973505020142, - -0.22131973505020142, - -0.45750728249549866, - -0.23618754744529724, - -0.23618754744529724 - ] + [0.191552996635437, 0.191552996635437, 0.0856488049030304, -0.10590419173240662, -0.10590419173240662], + [0.191552996635437, 0.191552996635437, 0.0856488049030304, -0.10590419173240662, -0.10590419173240662], + [-0.029766738414764404, -0.029766738414764404, -0.37185847759246826, -0.34209173917770386, -0.34209173917770386], + [-0.22131973505020142, -0.22131973505020142, -0.45750728249549866, -0.23618754744529724, -0.23618754744529724], + [-0.22131973505020142, -0.22131973505020142, -0.45750728249549866, -0.23618754744529724, -0.23618754744529724] ], [ - [ - 0.191552996635437, - 0.191552996635437, - 0.0856488049030304, - -0.10590419173240662, - -0.10590419173240662 - ], - [ - 0.191552996635437, - 0.191552996635437, - 0.0856488049030304, - -0.10590419173240662, - -0.10590419173240662 - ], - [ - -0.029766738414764404, - -0.029766738414764404, - -0.37185847759246826, - -0.34209173917770386, - -0.34209173917770386 - ], - [ - -0.22131973505020142, - -0.22131973505020142, - -0.45750728249549866, - -0.23618754744529724, - -0.23618754744529724 - ], - [ - -0.22131973505020142, - -0.22131973505020142, - -0.45750728249549866, - -0.23618754744529724, - -0.23618754744529724 - ] + [0.191552996635437, 0.191552996635437, 0.0856488049030304, -0.10590419173240662, -0.10590419173240662], + [0.191552996635437, 0.191552996635437, 0.0856488049030304, -0.10590419173240662, -0.10590419173240662], + [-0.029766738414764404, -0.029766738414764404, -0.37185847759246826, -0.34209173917770386, -0.34209173917770386], + [-0.22131973505020142, -0.22131973505020142, -0.45750728249549866, -0.23618754744529724, -0.23618754744529724], + [-0.22131973505020142, -0.22131973505020142, -0.45750728249549866, -0.23618754744529724, -0.23618754744529724] ], [ - [ - 0.20730310678482056, - 0.20730310678482056, - -0.269548624753952, - -0.4768517315387726, - -0.4768517315387726 - ], - [ - 0.20730310678482056, - 0.20730310678482056, - -0.269548624753952, - -0.4768517315387726, - -0.4768517315387726 - ], - [ - 0.05241367220878601, - 0.05241367220878601, - -0.8559648990631104, - -0.9083786010742188, - -0.9083786010742188 - ], - [ - -0.15488943457603455, - -0.15488943457603455, - -0.5864163637161255, - -0.43152689933776855, - -0.43152689933776855 - ], - [ - -0.15488943457603455, - -0.15488943457603455, - -0.5864163637161255, - -0.43152689933776855, - -0.43152689933776855 - ] + [0.20730310678482056, 0.20730310678482056, -0.269548624753952, -0.4768517315387726, -0.4768517315387726], + [0.20730310678482056, 0.20730310678482056, -0.269548624753952, -0.4768517315387726, -0.4768517315387726], + [0.05241367220878601, 0.05241367220878601, -0.8559648990631104, -0.9083786010742188, -0.9083786010742188], + [-0.15488943457603455, -0.15488943457603455, -0.5864163637161255, -0.43152689933776855, -0.43152689933776855], + [-0.15488943457603455, -0.15488943457603455, -0.5864163637161255, -0.43152689933776855, -0.43152689933776855] ], [ - [ - 0.015750110149383545, - 0.015750110149383545, - -0.3551974296569824, - -0.37094753980636597, - -0.37094753980636597 - ], - [ - 0.015750110149383545, - 0.015750110149383545, - -0.3551974296569824, - -0.37094753980636597, - -0.37094753980636597 - ], - [ - 0.08218041062355042, - 0.08218041062355042, - -0.48410648107528687, - -0.5662869215011597, - -0.5662869215011597 - ], - [ - 0.06643030047416687, - 0.06643030047416687, - -0.12890905141830444, - -0.1953393518924713, - -0.1953393518924713 - ], - [ - 0.06643030047416687, - 0.06643030047416687, - -0.12890905141830444, - -0.1953393518924713, - -0.1953393518924713 - ] + [0.015750110149383545, 0.015750110149383545, -0.3551974296569824, -0.37094753980636597, -0.37094753980636597], + [0.015750110149383545, 0.015750110149383545, -0.3551974296569824, -0.37094753980636597, -0.37094753980636597], + [0.08218041062355042, 0.08218041062355042, -0.48410648107528687, -0.5662869215011597, -0.5662869215011597], + [0.06643030047416687, 0.06643030047416687, -0.12890905141830444, -0.1953393518924713, -0.1953393518924713], + [0.06643030047416687, 0.06643030047416687, -0.12890905141830444, -0.1953393518924713, -0.1953393518924713] ], [ - [ - 0.015750110149383545, - 0.015750110149383545, - -0.3551974296569824, - -0.37094753980636597, - -0.37094753980636597 - ], - [ - 0.015750110149383545, - 0.015750110149383545, - -0.3551974296569824, - -0.37094753980636597, - -0.37094753980636597 - ], - [ - 0.08218041062355042, - 0.08218041062355042, - -0.48410648107528687, - -0.5662869215011597, - -0.5662869215011597 - ], - [ - 0.06643030047416687, - 0.06643030047416687, - -0.12890905141830444, - -0.1953393518924713, - -0.1953393518924713 - ], - [ - 0.06643030047416687, - 0.06643030047416687, - -0.12890905141830444, - -0.1953393518924713, - -0.1953393518924713 - ] + [0.015750110149383545, 0.015750110149383545, -0.3551974296569824, -0.37094753980636597, -0.37094753980636597], + [0.015750110149383545, 0.015750110149383545, -0.3551974296569824, -0.37094753980636597, -0.37094753980636597], + [0.08218041062355042, 0.08218041062355042, -0.48410648107528687, -0.5662869215011597, -0.5662869215011597], + [0.06643030047416687, 0.06643030047416687, -0.12890905141830444, -0.1953393518924713, -0.1953393518924713], + [0.06643030047416687, 0.06643030047416687, -0.12890905141830444, -0.1953393518924713, -0.1953393518924713] ] ] ] @@ -19290,92 +5837,44 @@ export const testData = { [ [ [ - [ - -1.343505859375, - -3.040519952774048 - ], - [ - -3.0536627769470215, - 4.573274612426758 - ] + [-1.343505859375, -3.040519952774048], + [-3.0536627769470215, 4.573274612426758] ], [ - [ - 8.510942459106445, - 0.5911479592323303 - ], - [ - -7.559212684631348, - -2.7728934288024902 - ] + [8.510942459106445, 0.5911479592323303], + [-7.559212684631348, -2.7728934288024902] ] ], [ [ - [ - -4.858392715454102, - -5.658546447753906 - ], - [ - 7.419499397277832, - 5.1849284172058105 - ] + [-4.858392715454102, -5.658546447753906], + [7.419499397277832, 5.1849284172058105] ], [ - [ - 4.672170639038086, - -1.5785690546035767 - ], - [ - -4.995093822479248, - 5.125855922698975 - ] + [4.672170639038086, -1.5785690546035767], + [-4.995093822479248, 5.125855922698975] ] ] ], [ [ [ - [ - -1.343505859375, - -3.040519952774048 - ], - [ - -3.0536627769470215, - 4.573274612426758 - ] + [-1.343505859375, -3.040519952774048], + [-3.0536627769470215, 4.573274612426758] ], [ - [ - 8.510942459106445, - 0.5911479592323303 - ], - [ - -7.559212684631348, - -2.7728934288024902 - ] + [8.510942459106445, 0.5911479592323303], + [-7.559212684631348, -2.7728934288024902] ] ], [ [ - [ - -4.858392715454102, - -5.658546447753906 - ], - [ - 7.419499397277832, - 5.1849284172058105 - ] + [-4.858392715454102, -5.658546447753906], + [7.419499397277832, 5.1849284172058105] ], [ - [ - 4.672170639038086, - -1.5785690546035767 - ], - [ - -4.995093822479248, - 5.125855922698975 - ] + [4.672170639038086, -1.5785690546035767], + [-4.995093822479248, 5.125855922698975] ] ] ] @@ -19398,426 +5897,106 @@ export const testData = { [ [ [ - [ - -1.3928337097167969, - -0.4097520112991333, - 0.703314483165741, - 0.9964529871940613 - ], - [ - 0.7671750783920288, - -0.737683117389679, - 0.8915963768959045, - 0.4381142258644104 - ], - [ - -1.9372137784957886, - -1.2051048278808594, - -0.6557903289794922, - 0.08431144803762436 - ], - [ - -0.653298556804657, - 0.5411866903305054, - 0.06401552259922028, - -0.8354001641273499 - ] + [-1.3928337097167969, -0.4097520112991333, 0.703314483165741, 0.9964529871940613], + [0.7671750783920288, -0.737683117389679, 0.8915963768959045, 0.4381142258644104], + [-1.9372137784957886, -1.2051048278808594, -0.6557903289794922, 0.08431144803762436], + [-0.653298556804657, 0.5411866903305054, 0.06401552259922028, -0.8354001641273499] ], [ - [ - 0.2550857663154602, - -0.4017896056175232, - -1.2750170230865479, - -0.7951065897941589 - ], - [ - 1.8864071369171143, - 0.1899632215499878, - 1.6621514558792114, - 1.6152663230895996 - ], - [ - -0.6503500938415527, - 0.6934462189674377, - -0.7531406283378601, - -1.054457426071167 - ], - [ - -0.34221795201301575, - 0.5399923920631409, - 0.43685466051101685, - 0.5002582669258118 - ] + [0.2550857663154602, -0.4017896056175232, -1.2750170230865479, -0.7951065897941589], + [1.8864071369171143, 0.1899632215499878, 1.6621514558792114, 1.6152663230895996], + [-0.6503500938415527, 0.6934462189674377, -0.7531406283378601, -1.054457426071167], + [-0.34221795201301575, 0.5399923920631409, 0.43685466051101685, 0.5002582669258118] ], [ - [ - 0.19359846413135529, - -0.40304437279701233, - 1.0216805934906006, - -0.5625430345535278 - ], - [ - -0.5148502588272095, - 0.008906678296625614, - 1.1446433067321777, - -0.07024435698986053 - ], - [ - 1.2778736352920532, - -0.30529654026031494, - 0.05272906273603439, - -0.5502418875694275 - ], - [ - 1.2332603931427002, - 0.5611109733581543, - -1.4120334386825562, - 0.1129438579082489 - ] + [0.19359846413135529, -0.40304437279701233, 1.0216805934906006, -0.5625430345535278], + [-0.5148502588272095, 0.008906678296625614, 1.1446433067321777, -0.07024435698986053], + [1.2778736352920532, -0.30529654026031494, 0.05272906273603439, -0.5502418875694275], + [1.2332603931427002, 0.5611109733581543, -1.4120334386825562, 0.1129438579082489] ], [ - [ - -0.8788067102432251, - -0.2609003186225891, - 0.12875856459140778, - -0.5114356875419617 - ], - [ - 2.786404848098755, - 0.48124057054519653, - 0.06012781709432602, - -0.3161824643611908 - ], - [ - -1.073968529701233, - -0.8155962824821472, - -1.6220977306365967, - -2.4403839111328125 - ], - [ - -0.23850013315677643, - 0.45670533180236816, - 0.048488546162843704, - 0.4753035008907318 - ] + [-0.8788067102432251, -0.2609003186225891, 0.12875856459140778, -0.5114356875419617], + [2.786404848098755, 0.48124057054519653, 0.06012781709432602, -0.3161824643611908], + [-1.073968529701233, -0.8155962824821472, -1.6220977306365967, -2.4403839111328125], + [-0.23850013315677643, 0.45670533180236816, 0.048488546162843704, 0.4753035008907318] ] ], [ [ - [ - -1.501094937324524, - -0.11335238814353943, - -0.47884872555732727, - 1.1839776039123535 - ], - [ - -1.8148568868637085, - -2.413346529006958, - -2.5672242641448975, - -1.2153066396713257 - ], - [ - 1.458335041999817, - 0.4836253225803375, - -1.981804370880127, - -0.590317964553833 - ], - [ - -0.14224699139595032, - 2.219874620437622, - 1.4296598434448242, - 2.5194058418273926 - ] + [-1.501094937324524, -0.11335238814353943, -0.47884872555732727, 1.1839776039123535], + [-1.8148568868637085, -2.413346529006958, -2.5672242641448975, -1.2153066396713257], + [1.458335041999817, 0.4836253225803375, -1.981804370880127, -0.590317964553833], + [-0.14224699139595032, 2.219874620437622, 1.4296598434448242, 2.5194058418273926] ], [ - [ - -1.5602378845214844, - -0.055706802755594254, - -0.3643185794353485, - -0.9861663579940796 - ], - [ - -0.6010674834251404, - -0.1635483205318451, - 0.540489673614502, - -0.3672035038471222 - ], - [ - -0.5103265047073364, - 0.048219867050647736, - 2.249467372894287, - 0.584500253200531 - ], - [ - 0.27795618772506714, - -0.8656967282295227, - 0.370025634765625, - 0.027097342535853386 - ] + [-1.5602378845214844, -0.055706802755594254, -0.3643185794353485, -0.9861663579940796], + [-0.6010674834251404, -0.1635483205318451, 0.540489673614502, -0.3672035038471222], + [-0.5103265047073364, 0.048219867050647736, 2.249467372894287, 0.584500253200531], + [0.27795618772506714, -0.8656967282295227, 0.370025634765625, 0.027097342535853386] ], [ - [ - 0.830817461013794, - -0.4116531312465668, - 2.1705524921417236, - 0.2617567777633667 - ], - [ - -1.1645411252975464, - 1.4430084228515625, - 0.34732240438461304, - -0.6022811532020569 - ], - [ - 0.8178791999816895, - 0.14809109270572662, - 1.33113694190979, - 0.7360257506370544 - ], - [ - -1.7843447923660278, - -1.4876283407211304, - 1.1491626501083374, - 1.937359094619751 - ] + [0.830817461013794, -0.4116531312465668, 2.1705524921417236, 0.2617567777633667], + [-1.1645411252975464, 1.4430084228515625, 0.34732240438461304, -0.6022811532020569], + [0.8178791999816895, 0.14809109270572662, 1.33113694190979, 0.7360257506370544], + [-1.7843447923660278, -1.4876283407211304, 1.1491626501083374, 1.937359094619751] ], [ - [ - 0.35567042231559753, - 0.7510744333267212, - 0.22924625873565674, - -0.4690351188182831 - ], - [ - -0.9391453862190247, - 1.2694876194000244, - 0.15634684264659882, - 0.6024797558784485 - ], - [ - -0.6078834533691406, - -0.8096639513969421, - -0.3527470827102661, - -0.013718712143599987 - ], - [ - 0.33257901668548584, - -2.500622034072876, - -1.3190810680389404, - -0.5720829367637634 - ] + [0.35567042231559753, 0.7510744333267212, 0.22924625873565674, -0.4690351188182831], + [-0.9391453862190247, 1.2694876194000244, 0.15634684264659882, 0.6024797558784485], + [-0.6078834533691406, -0.8096639513969421, -0.3527470827102661, -0.013718712143599987], + [0.33257901668548584, -2.500622034072876, -1.3190810680389404, -0.5720829367637634] ] ], [ [ - [ - 1.5485637187957764, - -0.08855976164340973, - -0.7727481722831726, - -1.0038365125656128 - ], - [ - 0.12993256747722626, - 2.3204126358032227, - -2.147797107696533, - -1.3236184120178223 - ], - [ - -1.239241361618042, - 0.9374039173126221, - 2.1315672397613525, - 0.9022464156150818 - ], - [ - 3.494849681854248, - -2.554791212081909, - -0.6495603322982788, - 1.3511242866516113 - ] + [1.5485637187957764, -0.08855976164340973, -0.7727481722831726, -1.0038365125656128], + [0.12993256747722626, 2.3204126358032227, -2.147797107696533, -1.3236184120178223], + [-1.239241361618042, 0.9374039173126221, 2.1315672397613525, 0.9022464156150818], + [3.494849681854248, -2.554791212081909, -0.6495603322982788, 1.3511242866516113] ], [ - [ - -0.8003812432289124, - 0.22974559664726257, - 0.8345783352851868, - 1.4143918752670288 - ], - [ - 0.5880279541015625, - -0.649803102016449, - 0.29551762342453003, - 0.1007673516869545 - ], - [ - 0.07260560989379883, - 0.24500113725662231, - -0.9157967567443848, - 1.9000908136367798 - ], - [ - 1.7842795848846436, - -2.0273475646972656, - -1.8968849182128906, - 1.5710992813110352 - ] + [-0.8003812432289124, 0.22974559664726257, 0.8345783352851868, 1.4143918752670288], + [0.5880279541015625, -0.649803102016449, 0.29551762342453003, 0.1007673516869545], + [0.07260560989379883, 0.24500113725662231, -0.9157967567443848, 1.9000908136367798], + [1.7842795848846436, -2.0273475646972656, -1.8968849182128906, 1.5710992813110352] ], [ - [ - -1.4176050424575806, - -0.0560019314289093, - 1.3802173137664795, - -1.265958309173584 - ], - [ - -1.1206839084625244, - -0.48504650592803955, - 0.5147204995155334, - -0.3676562011241913 - ], - [ - -1.1750401258468628, - 0.24909113347530365, - -0.16031959652900696, - 0.9739231467247009 - ], - [ - 0.7357478141784668, - -0.5081192851066589, - -0.29886385798454285, - 2.1124520301818848 - ] + [-1.4176050424575806, -0.0560019314289093, 1.3802173137664795, -1.265958309173584], + [-1.1206839084625244, -0.48504650592803955, 0.5147204995155334, -0.3676562011241913], + [-1.1750401258468628, 0.24909113347530365, -0.16031959652900696, 0.9739231467247009], + [0.7357478141784668, -0.5081192851066589, -0.29886385798454285, 2.1124520301818848] ], [ - [ - 0.9135115742683411, - -0.7519399523735046, - -0.7679979801177979, - -0.7598804831504822 - ], - [ - 1.1353410482406616, - 1.1538640260696411, - -0.44356340169906616, - -1.7530438899993896 - ], - [ - -0.7495994567871094, - 0.2814400792121887, - 0.22202011942863464, - -0.7438408732414246 - ], - [ - 0.30860263109207153, - -1.2615443468093872, - 0.2716897130012512, - -0.2226782888174057 - ] + [0.9135115742683411, -0.7519399523735046, -0.7679979801177979, -0.7598804831504822], + [1.1353410482406616, 1.1538640260696411, -0.44356340169906616, -1.7530438899993896], + [-0.7495994567871094, 0.2814400792121887, 0.22202011942863464, -0.7438408732414246], + [0.30860263109207153, -1.2615443468093872, 0.2716897130012512, -0.2226782888174057] ] ], [ [ - [ - -1.5529402494430542, - 0.13943159580230713, - 0.1643831729888916, - 0.29162532091140747 - ], - [ - 0.16704672574996948, - 0.19502827525138855, - 0.6036193370819092, - -0.22532868385314941 - ], - [ - 0.5098334550857544, - 1.5633010864257812, - -0.7737565040588379, - -0.44698092341423035 - ], - [ - -0.08777227252721786, - 0.36624786257743835, - 0.8002102971076965, - -0.43177542090415955 - ] + [-1.5529402494430542, 0.13943159580230713, 0.1643831729888916, 0.29162532091140747], + [0.16704672574996948, 0.19502827525138855, 0.6036193370819092, -0.22532868385314941], + [0.5098334550857544, 1.5633010864257812, -0.7737565040588379, -0.44698092341423035], + [-0.08777227252721786, 0.36624786257743835, 0.8002102971076965, -0.43177542090415955] ], [ - [ - 0.3932536244392395, - 0.45422324538230896, - 0.21926040947437286, - 0.45671015977859497 - ], - [ - -0.5347977876663208, - -0.41083934903144836, - 0.1554419845342636, - 0.7992386817932129 - ], - [ - 0.9056950807571411, - -2.0051839351654053, - -0.19047869741916656, - -2.534075975418091 - ], - [ - -0.21575696766376495, - 0.19951215386390686, - 1.077291488647461, - -0.11855955421924591 - ] + [0.3932536244392395, 0.45422324538230896, 0.21926040947437286, 0.45671015977859497], + [-0.5347977876663208, -0.41083934903144836, 0.1554419845342636, 0.7992386817932129], + [0.9056950807571411, -2.0051839351654053, -0.19047869741916656, -2.534075975418091], + [-0.21575696766376495, 0.19951215386390686, 1.077291488647461, -0.11855955421924591] ], [ - [ - 0.2259528934955597, - 0.27357611060142517, - -2.2692863941192627, - 0.5441847443580627 - ], - [ - -1.8895906209945679, - 0.870172917842865, - -0.40558135509490967, - 0.4322058856487274 - ], - [ - -0.682377278804779, - -0.22877585887908936, - 0.0997343435883522, - -0.9669718146324158 - ], - [ - -0.21153147518634796, - 0.23635204136371613, - -2.0590813159942627, - 0.36353930830955505 - ] + [0.2259528934955597, 0.27357611060142517, -2.2692863941192627, 0.5441847443580627], + [-1.8895906209945679, 0.870172917842865, -0.40558135509490967, 0.4322058856487274], + [-0.682377278804779, -0.22877585887908936, 0.0997343435883522, -0.9669718146324158], + [-0.21153147518634796, 0.23635204136371613, -2.0590813159942627, 0.36353930830955505] ], [ - [ - 1.0479241609573364, - 0.32106152176856995, - 0.18448585271835327, - -0.7088321447372437 - ], - [ - 0.8131258487701416, - 0.07307689636945724, - 0.5557780861854553, - 0.22815753519535065 - ], - [ - 0.5933053493499756, - 0.0023419519420713186, - 0.7572504878044128, - 0.6018804311752319 - ], - [ - -0.2617298364639282, - 0.09828201681375504, - 0.5204787254333496, - 0.150835320353508 - ] + [1.0479241609573364, 0.32106152176856995, 0.18448585271835327, -0.7088321447372437], + [0.8131258487701416, 0.07307689636945724, 0.5557780861854553, 0.22815753519535065], + [0.5933053493499756, 0.0023419519420713186, 0.7572504878044128, 0.6018804311752319], + [-0.2617298364639282, 0.09828201681375504, 0.5204787254333496, 0.150835320353508] ] ] ] @@ -19826,432 +6005,144 @@ export const testData = { [ [ [ - [ - -0.07317566871643066, - -0.05697118490934372, - 0.025281300768256187 - ], - [ - 0.09215686470270157, - 0.11558420211076736, - 0.05240511894226074 - ], - [ - -0.09402935951948166, - 0.12580211460590363, - 0.13140276074409485 - ] + [-0.07317566871643066, -0.05697118490934372, 0.025281300768256187], + [0.09215686470270157, 0.11558420211076736, 0.05240511894226074], + [-0.09402935951948166, 0.12580211460590363, 0.13140276074409485] ], [ - [ - -0.04044036939740181, - 0.004691822454333305, - 0.12318181246519089 - ], - [ - -0.04785345494747162, - 0.06451239436864853, - 0.022634774446487427 - ], - [ - 0.07585608959197998, - 0.04741308465600014, - 0.13501256704330444 - ] + [-0.04044036939740181, 0.004691822454333305, 0.12318181246519089], + [-0.04785345494747162, 0.06451239436864853, 0.022634774446487427], + [0.07585608959197998, 0.04741308465600014, 0.13501256704330444] ], [ - [ - 0.11532974988222122, - -0.0928543284535408, - 0.08189363032579422 - ], - [ - -0.026923909783363342, - -0.07120232284069061, - 0.02282446250319481 - ], - [ - -0.01852257549762726, - -0.08868129551410675, - -0.12011746317148209 - ] + [0.11532974988222122, -0.0928543284535408, 0.08189363032579422], + [-0.026923909783363342, -0.07120232284069061, 0.02282446250319481], + [-0.01852257549762726, -0.08868129551410675, -0.12011746317148209] ] ], [ [ - [ - -0.07584045082330704, - 0.014010561630129814, - 0.08293341845273972 - ], - [ - 0.0801883116364479, - 0.036289919167757034, - 0.12909185886383057 - ], - [ - -0.11655238270759583, - -0.08565417677164078, - 0.058578088879585266 - ] + [-0.07584045082330704, 0.014010561630129814, 0.08293341845273972], + [0.0801883116364479, 0.036289919167757034, 0.12909185886383057], + [-0.11655238270759583, -0.08565417677164078, 0.058578088879585266] ], [ - [ - -0.12395086884498596, - 0.12834252417087555, - 0.018763039261102676 - ], - [ - -0.05015324801206589, - 0.12142548710107803, - 0.06344791501760483 - ], - [ - 0.11444719135761261, - 0.1025216206908226, - -0.023683840408921242 - ] + [-0.12395086884498596, 0.12834252417087555, 0.018763039261102676], + [-0.05015324801206589, 0.12142548710107803, 0.06344791501760483], + [0.11444719135761261, 0.1025216206908226, -0.023683840408921242] ], [ - [ - 0.12353374063968658, - 0.017971260473132133, - 0.013177122920751572 - ], - [ - 0.04728586971759796, - -0.10653594881296158, - -0.08136706799268723 - ], - [ - 0.12876833975315094, - -0.0890536978840828, - 0.07353045046329498 - ] + [0.12353374063968658, 0.017971260473132133, 0.013177122920751572], + [0.04728586971759796, -0.10653594881296158, -0.08136706799268723], + [0.12876833975315094, -0.0890536978840828, 0.07353045046329498] ] ] ], [ [ [ - [ - 0.08224423229694366, - -0.11047881841659546, - -0.015596115961670876 - ], - [ - -0.0014560514828190207, - 0.10095883160829544, - -0.03723892569541931 - ], - [ - 0.12291000783443451, - -0.1141892746090889, - 0.05685015022754669 - ] + [0.08224423229694366, -0.11047881841659546, -0.015596115961670876], + [-0.0014560514828190207, 0.10095883160829544, -0.03723892569541931], + [0.12291000783443451, -0.1141892746090889, 0.05685015022754669] ], [ - [ - 0.07430146634578705, - -0.049023281782865524, - -0.044752590358257294 - ], - [ - -0.0866771936416626, - 0.03610346093773842, - 0.04560322314500809 - ], - [ - -0.04783155769109726, - 0.11004998534917831, - -0.020851340144872665 - ] + [0.07430146634578705, -0.049023281782865524, -0.044752590358257294], + [-0.0866771936416626, 0.03610346093773842, 0.04560322314500809], + [-0.04783155769109726, 0.11004998534917831, -0.020851340144872665] ], [ - [ - -0.02120385132730007, - 0.10628344863653183, - 0.023843467235565186 - ], - [ - 0.07284656912088394, - 0.08021114766597748, - -0.08907522261142731 - ], - [ - -0.0017236550338566303, - 0.12018252909183502, - -0.08414741605520248 - ] + [-0.02120385132730007, 0.10628344863653183, 0.023843467235565186], + [0.07284656912088394, 0.08021114766597748, -0.08907522261142731], + [-0.0017236550338566303, 0.12018252909183502, -0.08414741605520248] ] ], [ [ - [ - 0.01782277598977089, - 0.10108597576618195, - 0.0150253651663661 - ], - [ - -0.030513359233736992, - 0.049209609627723694, - -0.11256053298711777 - ], - [ - 0.11180425435304642, - 0.10690176486968994, - -0.03810763359069824 - ] + [0.01782277598977089, 0.10108597576618195, 0.0150253651663661], + [-0.030513359233736992, 0.049209609627723694, -0.11256053298711777], + [0.11180425435304642, 0.10690176486968994, -0.03810763359069824] ], [ - [ - -0.0492289662361145, - -0.026618685573339462, - 0.13539858162403107 - ], - [ - -0.052236780524253845, - 0.04074903205037117, - -0.1291959285736084 - ], - [ - 0.04113350436091423, - 0.08245334774255753, - 0.044047243893146515 - ] + [-0.0492289662361145, -0.026618685573339462, 0.13539858162403107], + [-0.052236780524253845, 0.04074903205037117, -0.1291959285736084], + [0.04113350436091423, 0.08245334774255753, 0.044047243893146515] ], [ - [ - -0.006466334220021963, - 0.009931002743542194, - 0.11784464865922928 - ], - [ - 0.059138908982276917, - -0.03144518658518791, - -0.10930255800485611 - ], - [ - 0.09917846322059631, - -0.050664398819208145, - 0.08484464883804321 - ] + [-0.006466334220021963, 0.009931002743542194, 0.11784464865922928], + [0.059138908982276917, -0.03144518658518791, -0.10930255800485611], + [0.09917846322059631, -0.050664398819208145, 0.08484464883804321] ] ] ], [ [ [ - [ - -0.027349485084414482, - 0.0022585864644497633, - -0.10731968283653259 - ], - [ - -0.051842495799064636, - 0.011228075250983238, - -0.1315104365348816 - ], - [ - -0.028004510328173637, - 0.0790708139538765, - 0.09564515203237534 - ] + [-0.027349485084414482, 0.0022585864644497633, -0.10731968283653259], + [-0.051842495799064636, 0.011228075250983238, -0.1315104365348816], + [-0.028004510328173637, 0.0790708139538765, 0.09564515203237534] ], [ - [ - 0.10023753345012665, - -0.04150017723441124, - 0.010712042450904846 - ], - [ - -0.1091998890042305, - 0.07049248367547989, - 0.024094296619296074 - ], - [ - 0.11390487849712372, - -0.021170107647776604, - 0.13014858961105347 - ] + [0.10023753345012665, -0.04150017723441124, 0.010712042450904846], + [-0.1091998890042305, 0.07049248367547989, 0.024094296619296074], + [0.11390487849712372, -0.021170107647776604, 0.13014858961105347] ], [ - [ - 0.06742006540298462, - 0.1161346584558487, - -0.00885622389614582 - ], - [ - -0.10677414387464523, - -0.10672265291213989, - -0.1283109188079834 - ], - [ - 0.022619053721427917, - -0.1052321121096611, - -0.04445267096161842 - ] + [0.06742006540298462, 0.1161346584558487, -0.00885622389614582], + [-0.10677414387464523, -0.10672265291213989, -0.1283109188079834], + [0.022619053721427917, -0.1052321121096611, -0.04445267096161842] ] ], [ [ - [ - 0.06914974004030228, - 0.12371136248111725, - -0.03412988409399986 - ], - [ - 0.09421706944704056, - -0.01031185407191515, - -0.027232328429818153 - ], - [ - -0.016104474663734436, - -0.06170425936579704, - 0.037245430052280426 - ] + [0.06914974004030228, 0.12371136248111725, -0.03412988409399986], + [0.09421706944704056, -0.01031185407191515, -0.027232328429818153], + [-0.016104474663734436, -0.06170425936579704, 0.037245430052280426] ], [ - [ - -0.0007366397767327726, - -0.0663040354847908, - 0.086556576192379 - ], - [ - -0.06079341098666191, - -0.09216593950986862, - 0.047240495681762695 - ], - [ - -0.008356397971510887, - -0.07491207867860794, - -0.11108863353729248 - ] + [-0.0007366397767327726, -0.0663040354847908, 0.086556576192379], + [-0.06079341098666191, -0.09216593950986862, 0.047240495681762695], + [-0.008356397971510887, -0.07491207867860794, -0.11108863353729248] ], [ - [ - -0.04077182710170746, - -0.1041940450668335, - 0.07401486486196518 - ], - [ - -0.016950387507677078, - 0.07009042799472809, - 0.06624048203229904 - ], - [ - 0.010960990563035011, - -0.020952291786670685, - -0.07018402963876724 - ] + [-0.04077182710170746, -0.1041940450668335, 0.07401486486196518], + [-0.016950387507677078, 0.07009042799472809, 0.06624048203229904], + [0.010960990563035011, -0.020952291786670685, -0.07018402963876724] ] ] ], [ [ [ - [ - 0.030636340379714966, - -0.11833041161298752, - -0.06631190329790115 - ], - [ - 0.10852135717868805, - -0.02641327865421772, - 0.10978111624717712 - ], - [ - 0.08058465272188187, - -0.02868703380227089, - -0.10953208804130554 - ] + [0.030636340379714966, -0.11833041161298752, -0.06631190329790115], + [0.10852135717868805, -0.02641327865421772, 0.10978111624717712], + [0.08058465272188187, -0.02868703380227089, -0.10953208804130554] ], [ - [ - 0.10928711295127869, - 0.011463882401585579, - 0.12860336899757385 - ], - [ - -0.12307491153478622, - 0.028042973950505257, - -0.11724753677845001 - ], - [ - -0.01652207039296627, - -0.1192781999707222, - -0.12385933846235275 - ] + [0.10928711295127869, 0.011463882401585579, 0.12860336899757385], + [-0.12307491153478622, 0.028042973950505257, -0.11724753677845001], + [-0.01652207039296627, -0.1192781999707222, -0.12385933846235275] ], [ - [ - 0.0068649169988930225, - 0.13416090607643127, - 0.010427097789943218 - ], - [ - -0.012607605196535587, - 0.12684836983680725, - 0.012456738390028477 - ], - [ - -0.07598394900560379, - 0.08653328567743301, - 0.09710167348384857 - ] + [0.0068649169988930225, 0.13416090607643127, 0.010427097789943218], + [-0.012607605196535587, 0.12684836983680725, 0.012456738390028477], + [-0.07598394900560379, 0.08653328567743301, 0.09710167348384857] ] ], [ [ - [ - 0.11799715459346771, - 0.10701807588338852, - 0.12649768590927124 - ], - [ - -0.05047071725130081, - 0.019567115232348442, - -0.049657005816698074 - ], - [ - -0.018113935366272926, - 0.10758863389492035, - -0.10752318054437637 - ] + [0.11799715459346771, 0.10701807588338852, 0.12649768590927124], + [-0.05047071725130081, 0.019567115232348442, -0.049657005816698074], + [-0.018113935366272926, 0.10758863389492035, -0.10752318054437637] ], [ - [ - 0.07436436414718628, - -0.07862627506256104, - 0.0007462596404366195 - ], - [ - -0.016202278435230255, - -0.06129545718431473, - 0.011604465544223785 - ], - [ - -0.06893385201692581, - 0.12325625866651535, - -0.04926367849111557 - ] + [0.07436436414718628, -0.07862627506256104, 0.0007462596404366195], + [-0.016202278435230255, -0.06129545718431473, 0.011604465544223785], + [-0.06893385201692581, 0.12325625866651535, -0.04926367849111557] ], [ - [ - 0.08613324165344238, - -0.03241463378071785, - -0.10714203119277954 - ], - [ - 0.10563848167657852, - -0.037575751543045044, - -0.05637470632791519 - ], - [ - 0.010202044621109962, - -0.0013864414067938924, - 0.03840000927448273 - ] + [0.08613324165344238, -0.03241463378071785, -0.10714203119277954], + [0.10563848167657852, -0.037575751543045044, -0.05637470632791519], + [0.010202044621109962, -0.0013864414067938924, 0.03840000927448273] ] ] ] @@ -20260,426 +6151,106 @@ export const testData = { [ [ [ - [ - -0.5189220309257507, - -0.5165614485740662, - -0.6292287707328796, - -0.05756598338484764 - ], - [ - -0.856631338596344, - -0.3688551187515259, - -0.4376771152019501, - -0.0977354496717453 - ], - [ - -0.5509511232376099, - -0.01779169961810112, - -0.55179363489151, - 0.7810271382331848 - ], - [ - 0.2855244576931, - 0.06042236462235451, - -0.12005633115768433, - 0.60771244764328 - ] + [-0.5189220309257507, -0.5165614485740662, -0.6292287707328796, -0.05756598338484764], + [-0.856631338596344, -0.3688551187515259, -0.4376771152019501, -0.0977354496717453], + [-0.5509511232376099, -0.01779169961810112, -0.55179363489151, 0.7810271382331848], + [0.2855244576931, 0.06042236462235451, -0.12005633115768433, 0.60771244764328] ], [ - [ - -0.22281594574451447, - -0.30689749121665955, - 0.7004629969596863, - 0.8319418430328369 - ], - [ - -1.1546739339828491, - -0.6868062615394592, - -0.2238551527261734, - 0.9293049573898315 - ], - [ - -0.6667256951332092, - -0.23265919089317322, - -0.28645816445350647, - -0.6312382817268372 - ], - [ - 0.4375527799129486, - 0.3424995243549347, - 0.49018558859825134, - 0.1981693059206009 - ] + [-0.22281594574451447, -0.30689749121665955, 0.7004629969596863, 0.8319418430328369], + [-1.1546739339828491, -0.6868062615394592, -0.2238551527261734, 0.9293049573898315], + [-0.6667256951332092, -0.23265919089317322, -0.28645816445350647, -0.6312382817268372], + [0.4375527799129486, 0.3424995243549347, 0.49018558859825134, 0.1981693059206009] ], [ - [ - -0.05317973718047142, - -0.3206823766231537, - 0.8374507427215576, - -0.3056468963623047 - ], - [ - 0.2974139153957367, - 0.9845985770225525, - 0.44274604320526123, - 0.14024977385997772 - ], - [ - -0.48651963472366333, - 0.879676878452301, - 0.01909274235367775, - -0.15339325368404388 - ], - [ - -0.030385207384824753, - 0.1865607053041458, - 0.22969035804271698, - 0.18484054505825043 - ] + [-0.05317973718047142, -0.3206823766231537, 0.8374507427215576, -0.3056468963623047], + [0.2974139153957367, 0.9845985770225525, 0.44274604320526123, 0.14024977385997772], + [-0.48651963472366333, 0.879676878452301, 0.01909274235367775, -0.15339325368404388], + [-0.030385207384824753, 0.1865607053041458, 0.22969035804271698, 0.18484054505825043] ], [ - [ - 0.16490347683429718, - 0.9333891868591309, - 0.11205387115478516, - 0.035932887345552444 - ], - [ - 0.04396235570311546, - -0.31778234243392944, - -0.6915766596794128, - -0.7603960633277893 - ], - [ - 0.48135581612586975, - 0.5444054007530212, - -0.7927911877632141, - -0.41890159249305725 - ], - [ - -0.49668002128601074, - -0.559000551700592, - -0.1916334480047226, - 0.07035645842552185 - ] + [0.16490347683429718, 0.9333891868591309, 0.11205387115478516, 0.035932887345552444], + [0.04396235570311546, -0.31778234243392944, -0.6915766596794128, -0.7603960633277893], + [0.48135581612586975, 0.5444054007530212, -0.7927911877632141, -0.41890159249305725], + [-0.49668002128601074, -0.559000551700592, -0.1916334480047226, 0.07035645842552185] ] ], [ [ - [ - 0.027814757078886032, - -0.36531198024749756, - -0.2956852614879608, - -0.07494735717773438 - ], - [ - 0.317421019077301, - 0.20873019099235535, - -0.17261816561222076, - 0.18707580864429474 - ], - [ - -0.5448725819587708, - 0.4587745666503906, - 0.2725429832935333, - 0.6743288636207581 - ], - [ - -0.19684088230133057, - -0.13441979885101318, - -0.68226557970047, - 0.0015642233192920685 - ] + [0.027814757078886032, -0.36531198024749756, -0.2956852614879608, -0.07494735717773438], + [0.317421019077301, 0.20873019099235535, -0.17261816561222076, 0.18707580864429474], + [-0.5448725819587708, 0.4587745666503906, 0.2725429832935333, 0.6743288636207581], + [-0.19684088230133057, -0.13441979885101318, -0.68226557970047, 0.0015642233192920685] ], [ - [ - -0.18683089315891266, - -0.7692659497261047, - -0.39447149634361267, - 0.13065055012702942 - ], - [ - 0.48978617787361145, - 0.38429391384124756, - 0.47841736674308777, - -0.3207741677761078 - ], - [ - -0.3932279944419861, - 0.12875378131866455, - -0.8934746980667114, - 0.4101417660713196 - ], - [ - 0.5834230780601501, - 0.4180571138858795, - -0.631263792514801, - -0.5178388953208923 - ] + [-0.18683089315891266, -0.7692659497261047, -0.39447149634361267, 0.13065055012702942], + [0.48978617787361145, 0.38429391384124756, 0.47841736674308777, -0.3207741677761078], + [-0.3932279944419861, 0.12875378131866455, -0.8934746980667114, 0.4101417660713196], + [0.5834230780601501, 0.4180571138858795, -0.631263792514801, -0.5178388953208923] ], [ - [ - -0.03619886562228203, - -0.20496532320976257, - 0.5740773677825928, - -0.47996267676353455 - ], - [ - -0.12516352534294128, - 0.14540526270866394, - 0.6903879046440125, - -0.2156420648097992 - ], - [ - 0.1515147089958191, - -0.5476300716400146, - -0.7382059693336487, - -0.31151825189590454 - ], - [ - 0.13428078591823578, - -0.0961957573890686, - -0.005456414073705673, - 0.004339788109064102 - ] + [-0.03619886562228203, -0.20496532320976257, 0.5740773677825928, -0.47996267676353455], + [-0.12516352534294128, 0.14540526270866394, 0.6903879046440125, -0.2156420648097992], + [0.1515147089958191, -0.5476300716400146, -0.7382059693336487, -0.31151825189590454], + [0.13428078591823578, -0.0961957573890686, -0.005456414073705673, 0.004339788109064102] ], [ - [ - 0.11125026643276215, - -0.3502165377140045, - 0.3796243667602539, - -0.07001438736915588 - ], - [ - -0.44981685280799866, - -0.028404127806425095, - -0.19824430346488953, - 0.248864084482193 - ], - [ - -0.23346014320850372, - -0.5089297294616699, - -0.25922563672065735, - 0.11221137642860413 - ], - [ - 0.43701913952827454, - 0.23463225364685059, - 0.13308370113372803, - 0.27311310172080994 - ] + [0.11125026643276215, -0.3502165377140045, 0.3796243667602539, -0.07001438736915588], + [-0.44981685280799866, -0.028404127806425095, -0.19824430346488953, 0.248864084482193], + [-0.23346014320850372, -0.5089297294616699, -0.25922563672065735, 0.11221137642860413], + [0.43701913952827454, 0.23463225364685059, 0.13308370113372803, 0.27311310172080994] ] ], [ [ - [ - 0.71690434217453, - -0.37317198514938354, - -0.25998103618621826, - -0.3843086361885071 - ], - [ - 0.07634495943784714, - 0.3695131242275238, - 0.22529920935630798, - 0.4135698974132538 - ], - [ - -0.4950774908065796, - 0.509172260761261, - 0.032416440546512604, - -0.7605869770050049 - ], - [ - 0.2789137661457062, - -0.24722981452941895, - 0.33938825130462646, - 0.8772264719009399 - ] + [0.71690434217453, -0.37317198514938354, -0.25998103618621826, -0.3843086361885071], + [0.07634495943784714, 0.3695131242275238, 0.22529920935630798, 0.4135698974132538], + [-0.4950774908065796, 0.509172260761261, 0.032416440546512604, -0.7605869770050049], + [0.2789137661457062, -0.24722981452941895, 0.33938825130462646, 0.8772264719009399] ], [ - [ - 0.5783311128616333, - -0.032182641327381134, - -0.4945024847984314, - 0.10007165372371674 - ], - [ - -0.029323793947696686, - 0.2238347828388214, - 1.7685524225234985, - 0.19979894161224365 - ], - [ - -0.7016185522079468, - 0.08255937695503235, - 0.07554244250059128, - -0.13586947321891785 - ], - [ - 0.1221686378121376, - -0.34831491112709045, - -0.5361258387565613, - 0.36475053429603577 - ] + [0.5783311128616333, -0.032182641327381134, -0.4945024847984314, 0.10007165372371674], + [-0.029323793947696686, 0.2238347828388214, 1.7685524225234985, 0.19979894161224365], + [-0.7016185522079468, 0.08255937695503235, 0.07554244250059128, -0.13586947321891785], + [0.1221686378121376, -0.34831491112709045, -0.5361258387565613, 0.36475053429603577] ], [ - [ - -0.18205034732818604, - 0.009124837815761566, - 0.48837193846702576, - 0.18220144510269165 - ], - [ - 0.2875525653362274, - -0.7277586460113525, - 0.383545458316803, - 0.7922366857528687 - ], - [ - 0.35036027431488037, - 0.4647741913795471, - -0.02845963090658188, - 0.3766854405403137 - ], - [ - 0.625316858291626, - -0.13582804799079895, - 0.09993312507867813, - 0.10810399800539017 - ] + [-0.18205034732818604, 0.009124837815761566, 0.48837193846702576, 0.18220144510269165], + [0.2875525653362274, -0.7277586460113525, 0.383545458316803, 0.7922366857528687], + [0.35036027431488037, 0.4647741913795471, -0.02845963090658188, 0.3766854405403137], + [0.625316858291626, -0.13582804799079895, 0.09993312507867813, 0.10810399800539017] ], [ - [ - 0.0920933410525322, - -0.2327292561531067, - 0.1246594563126564, - -0.24508613348007202 - ], - [ - 0.0638505071401596, - -0.1594996154308319, - -0.43965858221054077, - -0.12859344482421875 - ], - [ - -0.48574507236480713, - 0.12709787487983704, - 0.10260476917028427, - 0.16429319977760315 - ], - [ - 0.05439956486225128, - -0.029498502612113953, - -0.11129797250032425, - -0.26847541332244873 - ] + [0.0920933410525322, -0.2327292561531067, 0.1246594563126564, -0.24508613348007202], + [0.0638505071401596, -0.1594996154308319, -0.43965858221054077, -0.12859344482421875], + [-0.48574507236480713, 0.12709787487983704, 0.10260476917028427, 0.16429319977760315], + [0.05439956486225128, -0.029498502612113953, -0.11129797250032425, -0.26847541332244873] ] ], [ [ - [ - -0.2452285885810852, - -0.06107306852936745, - 0.8597950339317322, - 0.394406795501709 - ], - [ - -0.17274555563926697, - -0.03637805953621864, - -0.8504515290260315, - 0.4729595482349396 - ], - [ - 0.2524721920490265, - -0.4057195782661438, - -0.11825022101402283, - 0.04109963774681091 - ], - [ - 0.9326950311660767, - -0.5181980133056641, - 0.3552418053150177, - 1.070439100265503 - ] + [-0.2452285885810852, -0.06107306852936745, 0.8597950339317322, 0.394406795501709], + [-0.17274555563926697, -0.03637805953621864, -0.8504515290260315, 0.4729595482349396], + [0.2524721920490265, -0.4057195782661438, -0.11825022101402283, 0.04109963774681091], + [0.9326950311660767, -0.5181980133056641, 0.3552418053150177, 1.070439100265503] ], [ - [ - -0.7024675607681274, - 0.5648580193519592, - 0.5240363478660583, - -0.7053726315498352 - ], - [ - -0.35612714290618896, - -0.6093287467956543, - 1.1249797344207764, - -0.8079068660736084 - ], - [ - -0.27538979053497314, - 0.832629382610321, - 0.5831271409988403, - 0.6093882918357849 - ], - [ - 0.2426019012928009, - 0.2856079041957855, - -0.05524546280503273, - 0.310916930437088 - ] + [-0.7024675607681274, 0.5648580193519592, 0.5240363478660583, -0.7053726315498352], + [-0.35612714290618896, -0.6093287467956543, 1.1249797344207764, -0.8079068660736084], + [-0.27538979053497314, 0.832629382610321, 0.5831271409988403, 0.6093882918357849], + [0.2426019012928009, 0.2856079041957855, -0.05524546280503273, 0.310916930437088] ], [ - [ - 0.26993316411972046, - 0.2278856486082077, - -0.07653680443763733, - -0.021051857620477676 - ], - [ - 0.7272006869316101, - 0.4395790696144104, - 0.01439421996474266, - -1.0826799869537354 - ], - [ - 0.10812952369451523, - 0.4959411323070526, - -0.31829285621643066, - -0.49640241265296936 - ], - [ - -0.3244398832321167, - -0.5352140665054321, - -0.4826482832431793, - -0.6389537453651428 - ] + [0.26993316411972046, 0.2278856486082077, -0.07653680443763733, -0.021051857620477676], + [0.7272006869316101, 0.4395790696144104, 0.01439421996474266, -1.0826799869537354], + [0.10812952369451523, 0.4959411323070526, -0.31829285621643066, -0.49640241265296936], + [-0.3244398832321167, -0.5352140665054321, -0.4826482832431793, -0.6389537453651428] ], [ - [ - -0.2555220425128937, - -0.0470096580684185, - 0.11474063992500305, - 0.7965570092201233 - ], - [ - -0.046865809708833694, - -0.4719932973384857, - -0.34037473797798157, - 0.059014324098825455 - ], - [ - 0.267282098531723, - 0.42551925778388977, - -0.2612544596195221, - -0.09305000305175781 - ], - [ - 0.14654460549354553, - -0.01344921812415123, - 0.03611213341355324, - -0.15932729840278625 - ] + [-0.2555220425128937, -0.0470096580684185, 0.11474063992500305, 0.7965570092201233], + [-0.046865809708833694, -0.4719932973384857, -0.34037473797798157, 0.059014324098825455], + [0.267282098531723, 0.42551925778388977, -0.2612544596195221, -0.09305000305175781], + [0.14654460549354553, -0.01344921812415123, 0.03611213341355324, -0.15932729840278625] ] ] ] @@ -20688,426 +6259,106 @@ export const testData = { [ [ [ - [ - 0.10447724163532257, - 0.2759958505630493, - 0.2759958505630493, - 0.27689602971076965 - ], - [ - 0.3304583430290222, - 0.8043910264968872, - 0.8043910264968872, - 0.748386025428772 - ], - [ - 0.3304583430290222, - 0.8043910264968872, - 0.8043910264968872, - 0.748386025428772 - ], - [ - 0.49931013584136963, - 0.8851284980773926, - 0.8851284980773926, - 0.8720530867576599 - ] + [0.10447724163532257, 0.2759958505630493, 0.2759958505630493, 0.27689602971076965], + [0.3304583430290222, 0.8043910264968872, 0.8043910264968872, 0.748386025428772], + [0.3304583430290222, 0.8043910264968872, 0.8043910264968872, 0.748386025428772], + [0.49931013584136963, 0.8851284980773926, 0.8851284980773926, 0.8720530867576599] ], [ - [ - 0.2669637203216553, - 0.47796863317489624, - 0.47796863317489624, - 0.33882027864456177 - ], - [ - 0.5041998624801636, - 0.8133538961410522, - 0.8133538961410522, - 0.6375466585159302 - ], - [ - 0.5041998624801636, - 0.8133538961410522, - 0.8133538961410522, - 0.6375466585159302 - ], - [ - 0.5654966235160828, - 0.6807993054389954, - 0.6807993054389954, - 0.6420475840568542 - ] + [0.2669637203216553, 0.47796863317489624, 0.47796863317489624, 0.33882027864456177], + [0.5041998624801636, 0.8133538961410522, 0.8133538961410522, 0.6375466585159302], + [0.5041998624801636, 0.8133538961410522, 0.8133538961410522, 0.6375466585159302], + [0.5654966235160828, 0.6807993054389954, 0.6807993054389954, 0.6420475840568542] ], [ - [ - 0.2669637203216553, - 0.47796863317489624, - 0.47796863317489624, - 0.33882027864456177 - ], - [ - 0.5041998624801636, - 0.8133538961410522, - 0.8133538961410522, - 0.6375466585159302 - ], - [ - 0.5041998624801636, - 0.8133538961410522, - 0.8133538961410522, - 0.6375466585159302 - ], - [ - 0.5654966235160828, - 0.6807993054389954, - 0.6807993054389954, - 0.6420475840568542 - ] + [0.2669637203216553, 0.47796863317489624, 0.47796863317489624, 0.33882027864456177], + [0.5041998624801636, 0.8133538961410522, 0.8133538961410522, 0.6375466585159302], + [0.5041998624801636, 0.8133538961410522, 0.8133538961410522, 0.6375466585159302], + [0.5654966235160828, 0.6807993054389954, 0.6807993054389954, 0.6420475840568542] ], [ - [ - 0.1181013435125351, - 0.3042549192905426, - 0.3042549192905426, - 0.2648759186267853 - ], - [ - 0.3148439824581146, - 0.41089382767677307, - 0.41089382767677307, - 0.3637365400791168 - ], - [ - 0.3148439824581146, - 0.41089382767677307, - 0.41089382767677307, - 0.3637365400791168 - ], - [ - 0.21775929629802704, - 0.12964285910129547, - 0.12964285910129547, - 0.21047258377075195 - ] + [0.1181013435125351, 0.3042549192905426, 0.3042549192905426, 0.2648759186267853], + [0.3148439824581146, 0.41089382767677307, 0.41089382767677307, 0.3637365400791168], + [0.3148439824581146, 0.41089382767677307, 0.41089382767677307, 0.3637365400791168], + [0.21775929629802704, 0.12964285910129547, 0.12964285910129547, 0.21047258377075195] ] ], [ [ - [ - 0.18058183789253235, - 0.3834855556488037, - 0.3834855556488037, - 0.6673980951309204 - ], - [ - 0.537636935710907, - 0.7813745141029358, - 0.7813745141029358, - 0.9144545793533325 - ], - [ - 0.537636935710907, - 0.7813745141029358, - 0.7813745141029358, - 0.9144545793533325 - ], - [ - 0.5520140528678894, - 0.5436312556266785, - 0.5436312556266785, - 0.4455137848854065 - ] + [0.18058183789253235, 0.3834855556488037, 0.3834855556488037, 0.6673980951309204], + [0.537636935710907, 0.7813745141029358, 0.7813745141029358, 0.9144545793533325], + [0.537636935710907, 0.7813745141029358, 0.7813745141029358, 0.9144545793533325], + [0.5520140528678894, 0.5436312556266785, 0.5436312556266785, 0.4455137848854065] ], [ - [ - 0.2939951717853546, - 0.4372510015964508, - 0.4372510015964508, - 0.49767136573791504 - ], - [ - 0.7392789721488953, - 1.0817437171936035, - 1.0817437171936035, - 0.7633848190307617 - ], - [ - 0.7392789721488953, - 1.0817437171936035, - 1.0817437171936035, - 0.7633848190307617 - ], - [ - 0.6086863875389099, - 0.568009078502655, - 0.568009078502655, - 0.13552002608776093 - ] + [0.2939951717853546, 0.4372510015964508, 0.4372510015964508, 0.49767136573791504], + [0.7392789721488953, 1.0817437171936035, 1.0817437171936035, 0.7633848190307617], + [0.7392789721488953, 1.0817437171936035, 1.0817437171936035, 0.7633848190307617], + [0.6086863875389099, 0.568009078502655, 0.568009078502655, 0.13552002608776093] ], [ - [ - 0.2939951717853546, - 0.4372510015964508, - 0.4372510015964508, - 0.49767136573791504 - ], - [ - 0.7392789721488953, - 1.0817437171936035, - 1.0817437171936035, - 0.7633848190307617 - ], - [ - 0.7392789721488953, - 1.0817437171936035, - 1.0817437171936035, - 0.7633848190307617 - ], - [ - 0.6086863875389099, - 0.568009078502655, - 0.568009078502655, - 0.13552002608776093 - ] + [0.2939951717853546, 0.4372510015964508, 0.4372510015964508, 0.49767136573791504], + [0.7392789721488953, 1.0817437171936035, 1.0817437171936035, 0.7633848190307617], + [0.7392789721488953, 1.0817437171936035, 1.0817437171936035, 0.7633848190307617], + [0.6086863875389099, 0.568009078502655, 0.568009078502655, 0.13552002608776093] ], [ - [ - 0.10174182057380676, - 0.13050755858421326, - 0.13050755858421326, - 0.182585209608078 - ], - [ - 0.5305261611938477, - 0.7380304336547852, - 0.7380304336547852, - 0.4065806269645691 - ], - [ - 0.5305261611938477, - 0.7380304336547852, - 0.7380304336547852, - 0.4065806269645691 - ], - [ - 0.45701250433921814, - 0.37933337688446045, - 0.37933337688446045, - -0.008228868246078491 - ] + [0.10174182057380676, 0.13050755858421326, 0.13050755858421326, 0.182585209608078], + [0.5305261611938477, 0.7380304336547852, 0.7380304336547852, 0.4065806269645691], + [0.5305261611938477, 0.7380304336547852, 0.7380304336547852, 0.4065806269645691], + [0.45701250433921814, 0.37933337688446045, 0.37933337688446045, -0.008228868246078491] ] ], [ [ - [ - -0.025542324408888817, - -0.17474104464054108, - -0.17474104464054108, - -0.21195659041404724 - ], - [ - 0.03435610979795456, - -0.12244029343128204, - -0.12244029343128204, - -0.3096188008785248 - ], - [ - 0.03435610979795456, - -0.12244029343128204, - -0.12244029343128204, - -0.3096188008785248 - ], - [ - -0.032347261905670166, - -0.15482750535011292, - -0.15482750535011292, - -0.12919452786445618 - ] + [-0.025542324408888817, -0.17474104464054108, -0.17474104464054108, -0.21195659041404724], + [0.03435610979795456, -0.12244029343128204, -0.12244029343128204, -0.3096188008785248], + [0.03435610979795456, -0.12244029343128204, -0.12244029343128204, -0.3096188008785248], + [-0.032347261905670166, -0.15482750535011292, -0.15482750535011292, -0.12919452786445618] ], [ - [ - 0.19978223741054535, - -0.06369980424642563, - -0.06369980424642563, - -0.055818624794483185 - ], - [ - 0.18761692941188812, - -0.030813774093985558, - -0.030813774093985558, - -0.11953065544366837 - ], - [ - 0.18761692941188812, - -0.030813774093985558, - -0.030813774093985558, - -0.11953065544366837 - ], - [ - -0.20366701483726501, - -0.3893524706363678, - -0.3893524706363678, - -0.19097280502319336 - ] + [0.19978223741054535, -0.06369980424642563, -0.06369980424642563, -0.055818624794483185], + [0.18761692941188812, -0.030813774093985558, -0.030813774093985558, -0.11953065544366837], + [0.18761692941188812, -0.030813774093985558, -0.030813774093985558, -0.11953065544366837], + [-0.20366701483726501, -0.3893524706363678, -0.3893524706363678, -0.19097280502319336] ], [ - [ - 0.19978223741054535, - -0.06369980424642563, - -0.06369980424642563, - -0.055818624794483185 - ], - [ - 0.18761692941188812, - -0.030813774093985558, - -0.030813774093985558, - -0.11953065544366837 - ], - [ - 0.18761692941188812, - -0.030813774093985558, - -0.030813774093985558, - -0.11953065544366837 - ], - [ - -0.20366701483726501, - -0.3893524706363678, - -0.3893524706363678, - -0.19097280502319336 - ] + [0.19978223741054535, -0.06369980424642563, -0.06369980424642563, -0.055818624794483185], + [0.18761692941188812, -0.030813774093985558, -0.030813774093985558, -0.11953065544366837], + [0.18761692941188812, -0.030813774093985558, -0.030813774093985558, -0.11953065544366837], + [-0.20366701483726501, -0.3893524706363678, -0.3893524706363678, -0.19097280502319336] ], [ - [ - 0.2710735499858856, - 0.20295241475105286, - 0.20295241475105286, - 0.27079930901527405 - ], - [ - 0.1559443175792694, - 0.1467614471912384, - 0.1467614471912384, - 0.17059043049812317 - ], - [ - 0.1559443175792694, - 0.1467614471912384, - 0.1467614471912384, - 0.17059043049812317 - ], - [ - -0.34812459349632263, - -0.49819377064704895, - -0.49819377064704895, - -0.1905551254749298 - ] + [0.2710735499858856, 0.20295241475105286, 0.20295241475105286, 0.27079930901527405], + [0.1559443175792694, 0.1467614471912384, 0.1467614471912384, 0.17059043049812317], + [0.1559443175792694, 0.1467614471912384, 0.1467614471912384, 0.17059043049812317], + [-0.34812459349632263, -0.49819377064704895, -0.49819377064704895, -0.1905551254749298] ] ], [ [ - [ - 0.16911828517913818, - 0.33074456453323364, - 0.33074456453323364, - 0.10321924090385437 - ], - [ - 0.15183815360069275, - 0.08283436298370361, - 0.08283436298370361, - -0.03318226337432861 - ], - [ - 0.15183815360069275, - 0.08283436298370361, - 0.08283436298370361, - -0.03318226337432861 - ], - [ - -0.194735586643219, - -0.4434100389480591, - -0.4434100389480591, - -0.2986520230770111 - ] + [0.16911828517913818, 0.33074456453323364, 0.33074456453323364, 0.10321924090385437], + [0.15183815360069275, 0.08283436298370361, 0.08283436298370361, -0.03318226337432861], + [0.15183815360069275, 0.08283436298370361, 0.08283436298370361, -0.03318226337432861], + [-0.194735586643219, -0.4434100389480591, -0.4434100389480591, -0.2986520230770111] ], [ - [ - 0.19907379150390625, - 0.3374386429786682, - 0.3374386429786682, - -0.02413615584373474 - ], - [ - 0.18061795830726624, - 0.05656883120536804, - 0.05656883120536804, - -0.2146604061126709 - ], - [ - 0.18061795830726624, - 0.05656883120536804, - 0.05656883120536804, - -0.2146604061126709 - ], - [ - -0.07470852136611938, - -0.34530121088027954, - -0.34530121088027954, - -0.3103943169116974 - ] + [0.19907379150390625, 0.3374386429786682, 0.3374386429786682, -0.02413615584373474], + [0.18061795830726624, 0.05656883120536804, 0.05656883120536804, -0.2146604061126709], + [0.18061795830726624, 0.05656883120536804, 0.05656883120536804, -0.2146604061126709], + [-0.07470852136611938, -0.34530121088027954, -0.34530121088027954, -0.3103943169116974] ], [ - [ - 0.19907379150390625, - 0.3374386429786682, - 0.3374386429786682, - -0.02413615584373474 - ], - [ - 0.18061795830726624, - 0.05656883120536804, - 0.05656883120536804, - -0.2146604061126709 - ], - [ - 0.18061795830726624, - 0.05656883120536804, - 0.05656883120536804, - -0.2146604061126709 - ], - [ - -0.07470852136611938, - -0.34530121088027954, - -0.34530121088027954, - -0.3103943169116974 - ] + [0.19907379150390625, 0.3374386429786682, 0.3374386429786682, -0.02413615584373474], + [0.18061795830726624, 0.05656883120536804, 0.05656883120536804, -0.2146604061126709], + [0.18061795830726624, 0.05656883120536804, 0.05656883120536804, -0.2146604061126709], + [-0.07470852136611938, -0.34530121088027954, -0.34530121088027954, -0.3103943169116974] ], [ - [ - -0.27180415391921997, - -0.14891774952411652, - -0.14891774952411652, - -0.27959930896759033 - ], - [ - -0.3019259572029114, - -0.3711758255958557, - -0.3711758255958557, - -0.44573020935058594 - ], - [ - -0.3019259572029114, - -0.3711758255958557, - -0.3711758255958557, - -0.44573020935058594 - ], - [ - -0.13937608897686005, - -0.2628017067909241, - -0.2628017067909241, - -0.2183668613433838 - ] + [-0.27180415391921997, -0.14891774952411652, -0.14891774952411652, -0.27959930896759033], + [-0.3019259572029114, -0.3711758255958557, -0.3711758255958557, -0.44573020935058594], + [-0.3019259572029114, -0.3711758255958557, -0.3711758255958557, -0.44573020935058594], + [-0.13937608897686005, -0.2628017067909241, -0.2628017067909241, -0.2183668613433838] ] ] ] @@ -21116,448 +6367,150 @@ export const testData = { [ [ [ - [ - 0.1067051887512207, - 0.20825695991516113, - 0.3233646750450134 - ], - [ - 1.075575828552246, - 0.9549298286437988, - 0.8322933912277222 - ], - [ - 2.7843332290649414, - 3.024883270263672, - 1.9580979347229004 - ] + [0.1067051887512207, 0.20825695991516113, 0.3233646750450134], + [1.075575828552246, 0.9549298286437988, 0.8322933912277222], + [2.7843332290649414, 3.024883270263672, 1.9580979347229004] ], [ - [ - -1.088132619857788, - -4.254583358764648, - -4.973104953765869 - ], - [ - 0.14743173122406006, - -2.7659130096435547, - -3.4836788177490234 - ], - [ - 2.8671376705169678, - 0.8264245986938477, - -1.714296817779541 - ] + [-1.088132619857788, -4.254583358764648, -4.973104953765869], + [0.14743173122406006, -2.7659130096435547, -3.4836788177490234], + [2.8671376705169678, 0.8264245986938477, -1.714296817779541] ], [ - [ - 2.8881595134735107, - -1.7971699237823486, - -5.078564167022705 - ], - [ - 4.171820163726807, - 0.5749964714050293, - -3.3589401245117188 - ], - [ - 5.7922539710998535, - 4.064516067504883, - -0.2995426654815674 - ] + [2.8881595134735107, -1.7971699237823486, -5.078564167022705], + [4.171820163726807, 0.5749964714050293, -3.3589401245117188], + [5.7922539710998535, 4.064516067504883, -0.2995426654815674] ] ], [ [ - [ - -3.8329830169677734, - -4.827998638153076, - -0.7829046249389648 - ], - [ - -2.6662209033966064, - 0.8226261138916016, - 6.516355037689209 - ], - [ - -1.1823781728744507, - 1.8469009399414062, - 5.310114860534668 - ] + [-3.8329830169677734, -4.827998638153076, -0.7829046249389648], + [-2.6662209033966064, 0.8226261138916016, 6.516355037689209], + [-1.1823781728744507, 1.8469009399414062, 5.310114860534668] ], [ - [ - -3.78059720993042, - -4.655887126922607, - 0.5805654525756836 - ], - [ - -6.100958824157715, - -3.0644690990448, - 3.488039016723633 - ], - [ - -5.953107833862305, - -2.9071502685546875, - 1.7705130577087402 - ] + [-3.78059720993042, -4.655887126922607, 0.5805654525756836], + [-6.100958824157715, -3.0644690990448, 3.488039016723633], + [-5.953107833862305, -2.9071502685546875, 1.7705130577087402] ], [ - [ - 5.147970199584961, - 4.8943281173706055, - 8.273162841796875 - ], - [ - -0.6796786785125732, - 0.45905232429504395, - 5.0116963386535645 - ], - [ - -2.6251235008239746, - -0.29294729232788086, - 3.885946750640869 - ] + [5.147970199584961, 4.8943281173706055, 8.273162841796875], + [-0.6796786785125732, 0.45905232429504395, 5.0116963386535645], + [-2.6251235008239746, -0.29294729232788086, 3.885946750640869] ] ] ], [ [ [ - [ - 0.1067051887512207, - 0.20825695991516113, - 0.3233646750450134 - ], - [ - 1.075575828552246, - 0.9549298286437988, - 0.8322933912277222 - ], - [ - 2.7843332290649414, - 3.024883270263672, - 1.9580979347229004 - ] + [0.1067051887512207, 0.20825695991516113, 0.3233646750450134], + [1.075575828552246, 0.9549298286437988, 0.8322933912277222], + [2.7843332290649414, 3.024883270263672, 1.9580979347229004] ], [ - [ - -1.088132619857788, - -4.254583358764648, - -4.973104953765869 - ], - [ - 0.14743173122406006, - -2.7659130096435547, - -3.4836788177490234 - ], - [ - 2.8671376705169678, - 0.8264245986938477, - -1.714296817779541 - ] + [-1.088132619857788, -4.254583358764648, -4.973104953765869], + [0.14743173122406006, -2.7659130096435547, -3.4836788177490234], + [2.8671376705169678, 0.8264245986938477, -1.714296817779541] ], [ - [ - 2.8881595134735107, - -1.7971699237823486, - -5.078564167022705 - ], - [ - 4.171820163726807, - 0.5749964714050293, - -3.3589401245117188 - ], - [ - 5.7922539710998535, - 4.064516067504883, - -0.2995426654815674 - ] + [2.8881595134735107, -1.7971699237823486, -5.078564167022705], + [4.171820163726807, 0.5749964714050293, -3.3589401245117188], + [5.7922539710998535, 4.064516067504883, -0.2995426654815674] ] ], [ [ - [ - -3.8329830169677734, - -4.827998638153076, - -0.7829046249389648 - ], - [ - -2.6662209033966064, - 0.8226261138916016, - 6.516355037689209 - ], - [ - -1.1823781728744507, - 1.8469009399414062, - 5.310114860534668 - ] + [-3.8329830169677734, -4.827998638153076, -0.7829046249389648], + [-2.6662209033966064, 0.8226261138916016, 6.516355037689209], + [-1.1823781728744507, 1.8469009399414062, 5.310114860534668] ], [ - [ - -3.78059720993042, - -4.655887126922607, - 0.5805654525756836 - ], - [ - -6.100958824157715, - -3.0644690990448, - 3.488039016723633 - ], - [ - -5.953107833862305, - -2.9071502685546875, - 1.7705130577087402 - ] + [-3.78059720993042, -4.655887126922607, 0.5805654525756836], + [-6.100958824157715, -3.0644690990448, 3.488039016723633], + [-5.953107833862305, -2.9071502685546875, 1.7705130577087402] ], [ - [ - 5.147970199584961, - 4.8943281173706055, - 8.273162841796875 - ], - [ - -0.6796786785125732, - 0.45905232429504395, - 5.0116963386535645 - ], - [ - -2.6251235008239746, - -0.29294729232788086, - 3.885946750640869 - ] + [5.147970199584961, 4.8943281173706055, 8.273162841796875], + [-0.6796786785125732, 0.45905232429504395, 5.0116963386535645], + [-2.6251235008239746, -0.29294729232788086, 3.885946750640869] ] ] ], [ [ [ - [ - 0.4483606815338135, - 1.7787113189697266, - 5.192532539367676 - ], - [ - -1.4723293781280518, - 4.892696380615234, - 2.2916412353515625 - ], - [ - -2.3301377296447754, - 4.890291213989258, - 1.6198128461837769 - ] + [0.4483606815338135, 1.7787113189697266, 5.192532539367676], + [-1.4723293781280518, 4.892696380615234, 2.2916412353515625], + [-2.3301377296447754, 4.890291213989258, 1.6198128461837769] ], [ - [ - 1.441436767578125, - -0.48497796058654785, - 1.6295900344848633 - ], - [ - -1.1605052947998047, - 1.7250769138336182, - -2.4838342666625977 - ], - [ - -1.411887288093567, - 3.0889787673950195, - -0.87584388256073 - ] + [1.441436767578125, -0.48497796058654785, 1.6295900344848633], + [-1.1605052947998047, 1.7250769138336182, -2.4838342666625977], + [-1.411887288093567, 3.0889787673950195, -0.87584388256073] ], [ - [ - -1.3780968189239502, - -1.879303216934204, - 0.6745200157165527 - ], - [ - -4.27053689956665, - -1.3108704090118408, - -1.585677146911621 - ], - [ - -3.8346633911132812, - -0.26355016231536865, - -1.8428313732147217 - ] + [-1.3780968189239502, -1.879303216934204, 0.6745200157165527], + [-4.27053689956665, -1.3108704090118408, -1.585677146911621], + [-3.8346633911132812, -0.26355016231536865, -1.8428313732147217] ] ], [ [ - [ - -4.0036540031433105, - -5.653046607971191, - -3.195122241973877 - ], - [ - -3.8981828689575195, - -5.734371185302734, - -2.761385202407837 - ], - [ - -1.9460368156433105, - -5.074745178222656, - -3.0354936122894287 - ] + [-4.0036540031433105, -5.653046607971191, -3.195122241973877], + [-3.8981828689575195, -5.734371185302734, -2.761385202407837], + [-1.9460368156433105, -5.074745178222656, -3.0354936122894287] ], [ - [ - 0.344696044921875, - -1.1834907531738281, - -1.1799216270446777 - ], - [ - 0.8071980476379395, - -0.7569489479064941, - 0.02341151237487793 - ], - [ - 1.2058725357055664, - -0.941962718963623, - -0.04741215705871582 - ] + [0.344696044921875, -1.1834907531738281, -1.1799216270446777], + [0.8071980476379395, -0.7569489479064941, 0.02341151237487793], + [1.2058725357055664, -0.941962718963623, -0.04741215705871582] ], [ - [ - -0.6712508201599121, - -1.8187532424926758, - -2.691244125366211 - ], - [ - -1.2874345779418945, - -2.0391221046447754, - -2.2225937843322754 - ], - [ - -2.137885570526123, - -3.181636333465576, - -1.6979775428771973 - ] + [-0.6712508201599121, -1.8187532424926758, -2.691244125366211], + [-1.2874345779418945, -2.0391221046447754, -2.2225937843322754], + [-2.137885570526123, -3.181636333465576, -1.6979775428771973] ] ] ], [ [ [ - [ - 0.4483606815338135, - 1.7787113189697266, - 5.192532539367676 - ], - [ - -1.4723293781280518, - 4.892696380615234, - 2.2916412353515625 - ], - [ - -2.3301377296447754, - 4.890291213989258, - 1.6198128461837769 - ] + [0.4483606815338135, 1.7787113189697266, 5.192532539367676], + [-1.4723293781280518, 4.892696380615234, 2.2916412353515625], + [-2.3301377296447754, 4.890291213989258, 1.6198128461837769] ], [ - [ - 1.441436767578125, - -0.48497796058654785, - 1.6295900344848633 - ], - [ - -1.1605052947998047, - 1.7250769138336182, - -2.4838342666625977 - ], - [ - -1.411887288093567, - 3.0889787673950195, - -0.87584388256073 - ] + [1.441436767578125, -0.48497796058654785, 1.6295900344848633], + [-1.1605052947998047, 1.7250769138336182, -2.4838342666625977], + [-1.411887288093567, 3.0889787673950195, -0.87584388256073] ], [ - [ - -1.3780968189239502, - -1.879303216934204, - 0.6745200157165527 - ], - [ - -4.27053689956665, - -1.3108704090118408, - -1.585677146911621 - ], - [ - -3.8346633911132812, - -0.26355016231536865, - -1.8428313732147217 - ] + [-1.3780968189239502, -1.879303216934204, 0.6745200157165527], + [-4.27053689956665, -1.3108704090118408, -1.585677146911621], + [-3.8346633911132812, -0.26355016231536865, -1.8428313732147217] ] ], [ [ - [ - -4.0036540031433105, - -5.653046607971191, - -3.195122241973877 - ], - [ - -3.8981828689575195, - -5.734371185302734, - -2.761385202407837 - ], - [ - -1.9460368156433105, - -5.074745178222656, - -3.0354936122894287 - ] + [-4.0036540031433105, -5.653046607971191, -3.195122241973877], + [-3.8981828689575195, -5.734371185302734, -2.761385202407837], + [-1.9460368156433105, -5.074745178222656, -3.0354936122894287] ], [ - [ - 0.344696044921875, - -1.1834907531738281, - -1.1799216270446777 - ], - [ - 0.8071980476379395, - -0.7569489479064941, - 0.02341151237487793 - ], - [ - 1.2058725357055664, - -0.941962718963623, - -0.04741215705871582 - ] + [0.344696044921875, -1.1834907531738281, -1.1799216270446777], + [0.8071980476379395, -0.7569489479064941, 0.02341151237487793], + [1.2058725357055664, -0.941962718963623, -0.04741215705871582] ], [ - [ - -0.6712508201599121, - -1.8187532424926758, - -2.691244125366211 - ], - [ - -1.2874345779418945, - -2.0391221046447754, - -2.2225937843322754 - ], - [ - -2.137885570526123, - -3.181636333465576, - -1.6979775428771973 - ] + [-0.6712508201599121, -1.8187532424926758, -2.691244125366211], + [-1.2874345779418945, -2.0391221046447754, -2.2225937843322754], + [-2.137885570526123, -3.181636333465576, -1.6979775428771973] ] ] ] ], - "bias": [ - -0.033017437905073166, - -0.039262499660253525, - 0.0744556114077568, - 0.06237300857901573 - ], - "expected_grad_bias": [ - 64.0, - 64.0, - 64.0, - 64.0 - ] + "bias": [-0.033017437905073166, -0.039262499660253525, 0.0744556114077568, 0.06237300857901573], + "expected_grad_bias": [64.0, 64.0, 64.0, 64.0] } ], "export": [ @@ -21565,33 +6518,14 @@ export const testData = { "test_name": "linear_relu", "model_type": "LinearReLU", "input": [ - [ - -1.1228563785552979, - -0.18632829189300537, - 2.2082014083862305 - ], - [ - -0.637997031211853, - 0.46165722608566284, - 0.2673508822917938 - ] + [-1.1228563785552979, -0.18632829189300537, 2.2082014083862305], + [-0.637997031211853, 0.46165722608566284, 0.2673508822917938] ], "weight": [ - [ - 0.4414065182209015, - 0.47920528054237366, - -0.1352572739124298 - ], - [ - 0.5303604602813721, - -0.1264995038509369, - 0.11650390923023224 - ] - ], - "bias": [ - -0.28108587861061096, - 0.3390677869319916 + [0.4414065182209015, 0.47920528054237366, -0.1352572739124298], + [0.5303604602813721, -0.1264995038509369, 0.11650390923023224] ], + "bias": [-0.28108587861061096, 0.3390677869319916], "in_features": 3, "out_features": 2, "expected_nodes": [ @@ -21600,64 +6534,42 @@ export const testData = { "name": "p_0_weight", "target": "p_0_weight", "args": [], - "val_shape": [ - 2, - 3 - ] + "val_shape": [2, 3] }, { "op": "placeholder", "name": "p_0_bias", "target": "p_0_bias", "args": [], - "val_shape": [ - 2 - ] + "val_shape": [2] }, { "op": "placeholder", "name": "input", "target": "input", "args": [], - "val_shape": [ - 2, - 3 - ] + "val_shape": [2, 3] }, { "op": "call_function", "name": "linear", "target": "aten.linear.default", - "args": [ - "input", - "p_0_weight", - "p_0_bias" - ], - "val_shape": [ - 2, - 2 - ] + "args": ["input", "p_0_weight", "p_0_bias"], + "val_shape": [2, 2] }, { "op": "call_function", "name": "relu", "target": "aten.relu.default", - "args": [ - "linear" - ], - "val_shape": [ - 2, - 2 - ] + "args": ["linear"], + "val_shape": [2, 2] }, { "op": "output", "name": "output", "target": "output", "args": [ - [ - "relu" - ] + ["relu"] ] } ], @@ -21686,60 +6598,20 @@ export const testData = { "test_name": "two_layer", "model_type": "TwoLayer", "input": [ - [ - -0.331889808177948, - -0.4784944951534271, - -0.2630537450313568, - -0.17855434119701385 - ], - [ - -1.1858534812927246, - -0.8860282301902771, - -0.7149547338485718, - 0.12802214920520782 - ] + [-0.331889808177948, -0.4784944951534271, -0.2630537450313568, -0.17855434119701385], + [-1.1858534812927246, -0.8860282301902771, -0.7149547338485718, 0.12802214920520782] ], "linear1_weight": [ - [ - 0.3822692632675171, - 0.4150039553642273, - -0.11713624000549316, - 0.45930564403533936 - ], - [ - -0.10955178737640381, - 0.10089534521102905, - -0.24342751502990723, - 0.2936413288116455 - ], - [ - 0.4407714605331421, - -0.3668140769004822, - 0.43459808826446533, - 0.09357964992523193 - ] - ], - "linear1_bias": [ - 0.3694044351577759, - 0.06771528720855713, - 0.24109405279159546 + [0.3822692632675171, 0.4150039553642273, -0.11713624000549316, 0.45930564403533936], + [-0.10955178737640381, 0.10089534521102905, -0.24342751502990723, 0.2936413288116455], + [0.4407714605331421, -0.3668140769004822, 0.43459808826446533, 0.09357964992523193] ], + "linear1_bias": [0.3694044351577759, 0.06771528720855713, 0.24109405279159546], "linear2_weight": [ - [ - -0.08151666074991226, - 0.44507113099098206, - 0.08533751219511032 - ], - [ - -0.26953014731407166, - 0.14716561138629913, - -0.2660064101219177 - ] - ], - "linear2_bias": [ - -0.06770750880241394, - -0.234495609998703 + [-0.08151666074991226, 0.44507113099098206, 0.08533751219511032], + [-0.26953014731407166, 0.14716561138629913, -0.2660064101219177] ], + "linear2_bias": [-0.06770750880241394, -0.234495609998703], "linear1_in": 4, "linear1_out": 3, "linear2_in": 3, @@ -21750,109 +6622,70 @@ export const testData = { "name": "p_0_weight", "target": "p_0_weight", "args": [], - "val_shape": [ - 3, - 4 - ] + "val_shape": [3, 4] }, { "op": "placeholder", "name": "p_0_bias", "target": "p_0_bias", "args": [], - "val_shape": [ - 3 - ] + "val_shape": [3] }, { "op": "placeholder", "name": "p_2_weight", "target": "p_2_weight", "args": [], - "val_shape": [ - 2, - 3 - ] + "val_shape": [2, 3] }, { "op": "placeholder", "name": "p_2_bias", "target": "p_2_bias", "args": [], - "val_shape": [ - 2 - ] + "val_shape": [2] }, { "op": "placeholder", "name": "input", "target": "input", "args": [], - "val_shape": [ - 2, - 4 - ] + "val_shape": [2, 4] }, { "op": "call_function", "name": "linear", "target": "aten.linear.default", - "args": [ - "input", - "p_0_weight", - "p_0_bias" - ], - "val_shape": [ - 2, - 3 - ] + "args": ["input", "p_0_weight", "p_0_bias"], + "val_shape": [2, 3] }, { "op": "call_function", "name": "relu", "target": "aten.relu.default", - "args": [ - "linear" - ], - "val_shape": [ - 2, - 3 - ] + "args": ["linear"], + "val_shape": [2, 3] }, { "op": "call_function", "name": "linear_1", "target": "aten.linear.default", - "args": [ - "relu", - "p_2_weight", - "p_2_bias" - ], - "val_shape": [ - 2, - 2 - ] + "args": ["relu", "p_2_weight", "p_2_bias"], + "val_shape": [2, 2] }, { "op": "call_function", "name": "sigmoid", "target": "aten.sigmoid.default", - "args": [ - "linear_1" - ], - "val_shape": [ - 2, - 2 - ] + "args": ["linear_1"], + "val_shape": [2, 2] }, { "op": "output", "name": "output", "target": "output", "args": [ - [ - "sigmoid" - ] + ["sigmoid"] ] } ], From c5b01a8cae2b05bdc8913ef8e510fdd4f4818c33 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 12:36:23 +0800 Subject: [PATCH 102/128] fix: export type --- src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 6ebd9675..f7329c92 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ -export { Tensor, TypedArray, NestedNumberArray } from './tensor'; +export { Tensor } from './tensor'; +export type { TypedArray, NestedNumberArray } from './tensor'; export { no_grad, enable_no_grad, disable_no_grad, is_grad_enabled } from './grad_mode'; export { TorchFunction, AccumulateGrad } from './functions/base'; From c66c99faa0fc083dd33b432fbb4c9fd4923842f8 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 12:49:06 +0800 Subject: [PATCH 103/128] feat: loss test and fix unary fn bug --- scripts/generate_tests.py | 2 + scripts/generator/loss.py | 44 ++++++++++ src/functions/ops.ts | 18 ++-- test/generated.test.js | 18 ++++ test/testcases.gen.js | 168 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 scripts/generator/loss.py diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index 4fe0bd0c..775f608b 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -11,6 +11,7 @@ from generator.expand import generate_expand_tests from generator.conv import generate_conv_tests from generator.export import generate_export_tests +from generator.loss import generate_loss_tests UNARY_OPS = ["log", "sqrt", "exp", "square", "abs", "sign", "neg", "reciprocal", "sin", "cos", "tan"] BINARY_OPS = ["add", "sub", "mul", "div", "pow", "maximum", "minimum"] @@ -29,6 +30,7 @@ "expand": generate_expand_tests(), "conv": generate_conv_tests(), "export": generate_export_tests(), + "loss": generate_loss_tests(), } print("export const testData = ", end="") diff --git a/scripts/generator/loss.py b/scripts/generator/loss.py new file mode 100644 index 00000000..9ae71aaf --- /dev/null +++ b/scripts/generator/loss.py @@ -0,0 +1,44 @@ +import torch +import torch.nn as nn + + +def generate_loss_tests(): + tests = [] + + cases = [ + # (LossClass, input_shape, target_shape, test_name, needs_sigmoid) + (nn.MSELoss, (5,), (5,), "mse_1d", False), + (nn.MSELoss, (3, 4), (3, 4), "mse_2d", False), + (nn.MSELoss, (2, 3, 4), (2, 3, 4), "mse_3d", False), + (nn.L1Loss, (5,), (5,), "l1_1d", False), + (nn.L1Loss, (3, 4), (3, 4), "l1_2d", False), + (nn.L1Loss, (2, 3, 4), (2, 3, 4), "l1_3d", False), + # BCE requires inputs in (0, 1) + (nn.BCELoss, (5,), (5,), "bce_1d", True), + (nn.BCELoss, (3, 4), (3, 4), "bce_2d", True), + ] + + for LossClass, input_shape, target_shape, desc, needs_sigmoid in cases: + if needs_sigmoid: + input = torch.sigmoid(torch.randn(*input_shape)).requires_grad_(True) + target = torch.rand(*target_shape) + else: + input = torch.randn(*input_shape, requires_grad=True) + target = torch.randn(*target_shape) + + loss_fn = LossClass() + output = loss_fn(input, target) + output.backward() + + tests.append( + { + "test_name": desc, + "loss_type": LossClass.__name__, + "input": input.detach().numpy().tolist(), + "target": target.detach().numpy().tolist(), + "expected_output": output.detach().numpy().tolist(), + "expected_grad_input": input.grad.numpy().tolist(), + } + ) + + return tests diff --git a/src/functions/ops.ts b/src/functions/ops.ts index c25b6c80..f38bce11 100644 --- a/src/functions/ops.ts +++ b/src/functions/ops.ts @@ -184,7 +184,7 @@ const Sqrt = UnaryFunctionMixin( const Exp = UnaryFunctionMixin( (a: number[], x: number) => Math.exp(a[x]), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.exp()))); + aFn.backward(dz.mul(a.exp())); }, "exp" ); @@ -192,7 +192,7 @@ const Exp = UnaryFunctionMixin( const Square = UnaryFunctionMixin( (a: number[], x: number) => a[x] * a[x], (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a).mul(new Tensor(2)))); + aFn.backward(dz.mul(a).mul(new Tensor(2))); }, "square" ); @@ -200,7 +200,7 @@ const Square = UnaryFunctionMixin( const Abs = UnaryFunctionMixin( (a: number[], x: number) => Math.abs(a[x]), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(functional.sign(a)))); + aFn.backward(dz.mul(functional.sign(a))); }, "abs" ); @@ -215,8 +215,8 @@ const Sign = UnaryFunctionMixin( const Neg = UnaryFunctionMixin( (a: number[], x: number) => -a[x], - (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(new Tensor(-1)))); + (_a, aFn, dz) => { + aFn.backward(dz.mul(new Tensor(-1))); }, "neg" ); @@ -224,7 +224,7 @@ const Neg = UnaryFunctionMixin( const Reciprocal = UnaryFunctionMixin( (a: number[], x: number) => 1 / a[x], (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.pow(-2))).neg()); + aFn.backward(dz.mul(a.pow(-2)).neg()); }, "reciprocal" ); @@ -404,7 +404,7 @@ registerOperation('expand', Expand) const Sin = UnaryFunctionMixin( (a: number[], x: number) => Math.sin(a[x]), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.cos()))); + aFn.backward(dz.mul(a.cos())); }, "sin" ); @@ -412,7 +412,7 @@ const Sin = UnaryFunctionMixin( const Cos = UnaryFunctionMixin( (a: number[], x: number) => Math.cos(a[x]), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.sin().neg()))); + aFn.backward(dz.mul(a.sin().neg())); }, "cos" ); @@ -420,7 +420,7 @@ const Cos = UnaryFunctionMixin( const Tan = UnaryFunctionMixin( (a: number[], x: number) => Math.tan(a[x]), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.cos().pow(-2)))); + aFn.backward(dz.mul(a.cos().pow(-2))); }, "tan" ); diff --git a/test/generated.test.js b/test/generated.test.js index 9f4752e1..48124685 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -163,6 +163,24 @@ describe('Automated Tests', () => { }); }); }); + + describe('Loss Functions', () => { + testData.loss?.forEach(test => { + it(test.test_name, () => { + const LossClass = torch.nn[test.loss_type]; + const loss_fn = new LossClass(); + + const input = new Tensor(test.input, { requires_grad: true }); + const target = new Tensor(test.target); + + const output = loss_fn.forward(input, target); + assertDeepCloseTo(output.toArray(), test.expected_output, `${test.test_name} output`); + + output.backward(); + assertDeepCloseTo(input.grad.toArray(), test.expected_grad_input, `${test.test_name} grad input`); + }); + }); + }); }); describe('Optimizers', () => { diff --git a/test/testcases.gen.js b/test/testcases.gen.js index a11eab31..0d889875 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -6718,5 +6718,173 @@ export const testData = { } ] } + ], + "loss": [ + { + "test_name": "mse_1d", + "loss_type": "MSELoss", + "input": [-0.16030240058898926, -2.2161147594451904, -0.6857729554176331, -0.32950884103775024, -0.2747350335121155], + "target": [-1.255190372467041, -0.7812865376472473, 0.2293395847082138, -1.2753872871398926, -1.9245343208312988], + "expected_output": 1.5422934293746948, + "expected_grad_input": [0.43795520067214966, -0.5739313364028931, -0.3660450279712677, 0.3783513903617859, 0.6599197387695312] + }, + { + "test_name": "mse_2d", + "loss_type": "MSELoss", + "input": [ + [0.4335620105266571, 0.664082407951355, -0.43367648124694824, -0.42010796070098877], + [-0.9499658942222595, -1.0013846158981323, -0.771919310092926, 1.3434035778045654], + [0.955953061580658, -1.0110232830047607, -0.356810599565506, 0.7146782279014587] + ], + "target": [ + [-0.23975907266139984, 0.21629300713539124, 0.5484155416488647, -0.44147154688835144], + [1.5815293788909912, -0.19812652468681335, 0.9553706645965576, -1.0901628732681274], + [2.595151424407959, 2.750434637069702, 0.648761510848999, 0.44963163137435913] + ], + "expected_output": 2.9579389095306396, + "expected_grad_input": [ + [0.11222018301486969, 0.07463157176971436, -0.1636820137500763, 0.003560597775503993], + [-0.4219158887863159, -0.13387635350227356, -0.28788167238235474, 0.40559443831443787], + [-0.27319973707199097, -0.6269096732139587, -0.16759535670280457, 0.0441744327545166] + ] + }, + { + "test_name": "mse_3d", + "loss_type": "MSELoss", + "input": [ + [ + [-0.35762301087379456, -0.31650829315185547, 0.5886339545249939, -0.8904569149017334], + [0.4098125100135803, -1.457029104232788, -0.10233523696660995, -0.5991530418395996], + [-1.1298598051071167, -0.1360345333814621, 1.6354095935821533, 0.6547407507896423] + ], + [ + [0.5760045647621155, -0.36090990900993347, -0.06059038266539574, 0.07325476408004761], + [0.9254348874092102, -0.3753443658351898, 1.0330873727798462, -0.6866509318351746], + [0.6368136405944824, 0.2175532579421997, -0.04665505886077881, -1.433521032333374] + ] + ], + "target": [ + [ + [1.450609803199768, 0.2694815397262573, -0.21037597954273224, -0.7328027486801147], + [0.10429783165454865, 1.0414010286331177, -0.3997306227684021, -2.293334484100342], + [1.1179102659225464, -1.2955713272094727, 0.05027642846107483, -0.5854812264442444] + ], + [ + [-0.3899965286254883, 0.03581761196255684, 0.12058872729539871, -0.8056637048721313], + [0.20801466703414917, -1.158583402633667, -0.9636622667312622, -0.3749968111515045], + [0.8032528162002563, -0.5187733173370361, -1.5012763738632202, -1.9266542196273804] + ] + ], + "expected_output": 1.4189788103103638, + "expected_grad_input": [ + [ + [-0.15068607032299042, -0.0488324873149395, 0.06658416241407394, -0.013137847185134888], + [0.02545955777168274, -0.20820252597332, 0.024782948195934296, 0.1411817967891693], + [-0.18731418251991272, 0.09662806987762451, 0.13209444284439087, 0.10335183143615723] + ], + [ + [0.08050009608268738, -0.03306062892079353, -0.01509825885295868, 0.07324320822954178], + [0.05978501960635185, 0.06526991724967957, 0.16639581322669983, -0.025971177965402603], + [-0.013869931921362877, 0.06136054918169975, 0.12121844291687012, 0.04109443351626396] + ] + ] + }, + { + "test_name": "l1_1d", + "loss_type": "L1Loss", + "input": [-0.3083152174949646, 1.010894775390625, 0.3823634088039398, -1.002435326576233, 1.3410226106643677], + "target": [1.0322986841201782, 0.883126974105835, 0.8391237258911133, -1.2442442178726196, -0.4766048491001129], + "expected_output": 0.7969156503677368, + "expected_grad_input": [-0.20000000298023224, 0.20000000298023224, -0.20000000298023224, 0.20000000298023224, 0.20000000298023224] + }, + { + "test_name": "l1_2d", + "loss_type": "L1Loss", + "input": [ + [-0.8057987689971924, 0.46343186497688293, 0.7677170634269714, -1.102782130241394], + [1.7588211297988892, -1.8872032165527344, -2.220559597015381, 0.3306517004966736], + [0.48136675357818604, 1.4244316816329956, -0.31612974405288696, 0.08585795760154724] + ], + "target": [ + [0.9491400718688965, -0.10296741127967834, 2.5101442337036133, 0.1954755336046219], + [-0.014661739580333233, 0.2708866000175476, -0.20515739917755127, -0.6051543354988098], + [-0.5226790308952332, 0.9970949292182922, 0.3249934911727905, 0.14241407811641693] + ], + "expected_output": 1.1978222131729126, + "expected_grad_input": [ + [-0.0833333358168602, 0.0833333358168602, -0.0833333358168602, -0.0833333358168602], + [0.0833333358168602, -0.0833333358168602, -0.0833333358168602, 0.0833333358168602], + [0.0833333358168602, 0.0833333358168602, -0.0833333358168602, -0.0833333358168602] + ] + }, + { + "test_name": "l1_3d", + "loss_type": "L1Loss", + "input": [ + [ + [-0.01884661614894867, -0.685481607913971, 0.5635589957237244, -1.507175087928772], + [-1.610666036605835, -1.4790465831756592, 0.4322742819786072, -0.1250254064798355], + [0.05792269483208656, 0.8637403845787048, -0.5890002846717834, -1.0340019464492798] + ], + [ + [-0.2178654670715332, 0.7986540794372559, 0.9104702472686768, -0.08801817893981934], + [-0.036629438400268555, -0.4807589650154114, 0.3163014054298401, 0.3865722119808197], + [0.7336946129798889, 0.2510286271572113, 0.07699853926897049, -0.2063409984111786] + ] + ], + "target": [ + [ + [-0.047562163323163986, 0.5229573249816895, 0.9717304110527039, -0.27785417437553406], + [-0.6115978360176086, -0.5571882724761963, -0.9683470726013184, 0.8712791800498962], + [1.3595633506774902, 0.4334380030632019, -0.7171905636787415, 1.055369257926941] + ], + [ + [-1.4533969163894653, 0.46515071392059326, 0.37139150500297546, -0.004656785633414984], + [0.05607975274324417, 0.3781784772872925, 0.7051141262054443, -1.7236974239349365], + [-0.8434810638427734, 0.4351435601711273, 0.26588720083236694, -0.5870985388755798] + ] + ], + "expected_output": 0.7964643836021423, + "expected_grad_input": [ + [ + [0.0416666679084301, -0.0416666679084301, -0.0416666679084301, -0.0416666679084301], + [-0.0416666679084301, -0.0416666679084301, 0.0416666679084301, -0.0416666679084301], + [-0.0416666679084301, 0.0416666679084301, 0.0416666679084301, -0.0416666679084301] + ], + [ + [0.0416666679084301, 0.0416666679084301, 0.0416666679084301, -0.0416666679084301], + [-0.0416666679084301, -0.0416666679084301, -0.0416666679084301, 0.0416666679084301], + [0.0416666679084301, -0.0416666679084301, -0.0416666679084301, 0.0416666679084301] + ] + ] + }, + { + "test_name": "bce_1d", + "loss_type": "BCELoss", + "input": [0.9015220999717712, 0.5855253338813782, 0.4241449534893036, 0.46762359142303467, 0.14062806963920593], + "target": [0.258492648601532, 0.16423600912094116, 0.6211971044540405, 0.637805163860321, 0.7739548683166504], + "expected_output": 1.1154000759124756, + "expected_grad_input": [1.4485907554626465, 0.34718963503837585, -0.16135546565055847, -0.1367185115814209, -1.0481046438217163] + }, + { + "test_name": "bce_2d", + "loss_type": "BCELoss", + "input": [ + [0.6885789632797241, 0.5632960200309753, 0.5165387392044067, 0.21918706595897675], + [0.6609245538711548, 0.26889950037002563, 0.4938890039920807, 0.5620960593223572], + [0.1478312611579895, 0.46731826663017273, 0.8081178069114685, 0.46147868037223816] + ], + "target": [ + [0.5905491709709167, 0.7722692489624023, 0.9141846299171448, 0.04094696044921875], + [0.8343076109886169, 0.14735394716262817, 0.6872336268424988, 0.9231226444244385], + [0.5070211887359619, 0.9549044966697693, 0.07397425174713135, 0.30902040004730225] + ], + "expected_output": 0.7156786918640137, + "expected_grad_input": [ + [0.0380956269800663, -0.07079222798347473, -0.132693812251091, 0.08678851276636124], + [-0.06447289884090424, 0.05152176693081856, -0.06445783376693726, -0.12222739309072495], + [-0.23760251700878143, -0.16322611272335052, 0.39453938603401184, 0.05112287402153015] + ] + } ] }; From 119c3117b3c53bc9cbc1b5b69f8f3e446f0a89fe Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 12:58:51 +0800 Subject: [PATCH 104/128] feat: activation and creation tests --- scripts/generate_tests.py | 2 + scripts/generator/activation.py | 35 ++++++++ src/broadcasting.ts | 64 -------------- src/nn/ops.ts | 2 +- test/creation.test.ts | 151 ++++++++++++++++++++++++++++++++ test/generated.test.js | 16 ++++ test/testcases.gen.js | 134 ++++++++++++++++++++++++++++ 7 files changed, 339 insertions(+), 65 deletions(-) create mode 100644 scripts/generator/activation.py create mode 100644 test/creation.test.ts diff --git a/scripts/generate_tests.py b/scripts/generate_tests.py index 775f608b..3fe9765b 100644 --- a/scripts/generate_tests.py +++ b/scripts/generate_tests.py @@ -12,6 +12,7 @@ from generator.conv import generate_conv_tests from generator.export import generate_export_tests from generator.loss import generate_loss_tests +from generator.activation import generate_activation_tests UNARY_OPS = ["log", "sqrt", "exp", "square", "abs", "sign", "neg", "reciprocal", "sin", "cos", "tan"] BINARY_OPS = ["add", "sub", "mul", "div", "pow", "maximum", "minimum"] @@ -31,6 +32,7 @@ "conv": generate_conv_tests(), "export": generate_export_tests(), "loss": generate_loss_tests(), + "activations": generate_activation_tests(), } print("export const testData = ", end="") diff --git a/scripts/generator/activation.py b/scripts/generator/activation.py new file mode 100644 index 00000000..215198b3 --- /dev/null +++ b/scripts/generator/activation.py @@ -0,0 +1,35 @@ +import torch +import torch.nn as nn + + +def generate_activation_tests(): + tests = [] + + cases = [ + # (ActivationClass, test_name) + (nn.ReLU, "relu_1d", (5,)), + (nn.ReLU, "relu_2d", (3, 4)), + (nn.ReLU, "relu_3d", (2, 3, 4)), + (nn.Sigmoid, "sigmoid_1d", (5,)), + (nn.Sigmoid, "sigmoid_2d", (3, 4)), + (nn.Sigmoid, "sigmoid_3d", (2, 3, 4)), + ] + + for ActivationClass, desc, input_shape in cases: + input = torch.randn(*input_shape, requires_grad=True) + + activation = ActivationClass() + output = activation(input) + output.sum().backward() + + tests.append( + { + "test_name": desc, + "activation_type": ActivationClass.__name__, + "input": input.detach().numpy().tolist(), + "expected_output": output.detach().numpy().tolist(), + "expected_grad_input": input.grad.numpy().tolist(), + } + ) + + return tests diff --git a/src/broadcasting.ts b/src/broadcasting.ts index 42c169b2..f80a7ee1 100644 --- a/src/broadcasting.ts +++ b/src/broadcasting.ts @@ -57,67 +57,3 @@ export function _get_original_index( } return original_index; } - -export function _get_original_index_kernel( - original_shape: number[], - new_shape: number[], - index: number -): number { - let original_index = 0; - let cur_stride = 1; - let temp_index = index; - - for (let i = this.constants.shape_length - 1; i >= 0; i--) { - if (original_shape[i] > 1) { - const dim_index = temp_index % new_shape[i]; - original_index = original_index + dim_index * cur_stride; - } - cur_stride = cur_stride * original_shape[i]; - temp_index = Math.floor(temp_index / new_shape[i]); - } - return original_index; -} - -export function _get_original_index_from_transposed_index( - original_shape: number[], - dim0: number, - dim1: number, - transposed_index: number -): number { - let original_index = 0; - let cur_stride = 1; - let temp_index = transposed_index; - - let dim0_index = 0; - let dim1_index = 0; - - for (let i = this.constants.shape_length - 1; i >= 0; i--) { - const dim_index = temp_index % original_shape[i]; - if (i == dim0) { - dim0_index = dim_index; - } - if (i == dim1) { - dim1_index = dim_index; - } - temp_index = Math.floor(temp_index / original_shape[i]); - } - - temp_index = transposed_index; - - for (let j = this.constants.shape_length - 1; j >= 0; j--) { - const dim_index = temp_index % original_shape[j]; - if (j == dim0) { - original_index = original_index + dim1_index * cur_stride; - } else if (j == dim1) { - original_index = original_index + dim0_index * cur_stride; - } else { - original_index = original_index + dim_index * cur_stride; - } - cur_stride = cur_stride * original_shape[j]; - temp_index = Math.floor(temp_index / original_shape[j]); - } - - return original_index; - - // return transposed_index; -} diff --git a/src/nn/ops.ts b/src/nn/ops.ts index a0d1bc76..496afb7c 100644 --- a/src/nn/ops.ts +++ b/src/nn/ops.ts @@ -3,7 +3,7 @@ import { UnaryFunctionMixin } from '../functions/mixin'; const Relu = UnaryFunctionMixin( (a: number[], x: number) => Math.max(a[x], 0), (a, aFn, dz) => { - aFn.backward(dz.mul(dz.mul(a.gt(0)))); + aFn.backward(dz.mul(a.gt(0))); }, "relu" ); diff --git a/test/creation.test.ts b/test/creation.test.ts new file mode 100644 index 00000000..94061bbc --- /dev/null +++ b/test/creation.test.ts @@ -0,0 +1,151 @@ +import { assert } from 'chai'; +import * as torch from 'torch'; +import { Tensor } from 'torch'; + +describe('Creation Functions', () => { + describe('ones', () => { + it('should create a 1D tensor of ones', () => { + const t = torch.ones(5); + assert.deepStrictEqual(t.toArray(), [1, 1, 1, 1, 1]); + assert.deepStrictEqual(t.shape, [5]); + }); + + it('should create a 2D tensor of ones', () => { + const t = torch.ones(2, 3); + assert.deepStrictEqual(t.toArray(), [[1, 1, 1], [1, 1, 1]]); + assert.deepStrictEqual(t.shape, [2, 3]); + }); + + it('should create a 3D tensor of ones', () => { + const t = torch.ones(2, 3, 4); + assert.deepStrictEqual(t.shape, [2, 3, 4]); + assert.strictEqual(t.toFlatArray().length, 24); + assert.isTrue(t.toFlatArray().every((v: number) => v === 1)); + }); + + it('should accept shape as an array', () => { + const t = torch.ones([3, 2]); + assert.deepStrictEqual(t.shape, [3, 2]); + assert.isTrue(t.toFlatArray().every((v: number) => v === 1)); + }); + }); + + describe('zeros', () => { + it('should create a 1D tensor of zeros', () => { + const t = torch.zeros(4); + assert.deepStrictEqual(t.toArray(), [0, 0, 0, 0]); + assert.deepStrictEqual(t.shape, [4]); + }); + + it('should create a 2D tensor of zeros', () => { + const t = torch.zeros(3, 2); + assert.deepStrictEqual(t.toArray(), [[0, 0], [0, 0], [0, 0]]); + assert.deepStrictEqual(t.shape, [3, 2]); + }); + + it('should accept shape as an array', () => { + const t = torch.zeros([2, 4]); + assert.deepStrictEqual(t.shape, [2, 4]); + assert.isTrue(t.toFlatArray().every((v: number) => v === 0)); + }); + }); + + describe('ones_like', () => { + it('should create a tensor of ones with the same shape', () => { + const original = new Tensor([[1, 2, 3], [4, 5, 6]]); + const t = torch.ones_like(original); + assert.deepStrictEqual(t.shape, [2, 3]); + assert.isTrue(t.toFlatArray().every((v: number) => v === 1)); + }); + }); + + describe('zeros_like', () => { + it('should create a tensor of zeros with the same shape', () => { + const original = new Tensor([[1, 2], [3, 4], [5, 6]]); + const t = torch.zeros_like(original); + assert.deepStrictEqual(t.shape, [3, 2]); + assert.isTrue(t.toFlatArray().every((v: number) => v === 0)); + }); + }); + + describe('rand', () => { + it('should create a tensor with the correct shape', () => { + const t = torch.rand(3, 4); + assert.deepStrictEqual(t.shape, [3, 4]); + assert.strictEqual(t.toFlatArray().length, 12); + }); + + it('should create values in [0, 1)', () => { + const t = torch.rand(10); + for (const v of t.toFlatArray()) { + assert.isAtLeast(v, 0); + assert.isBelow(v, 1); + } + }); + }); + + describe('randn', () => { + it('should create a tensor with the correct shape', () => { + const t = torch.randn(2, 5); + assert.deepStrictEqual(t.shape, [2, 5]); + assert.strictEqual(t.toFlatArray().length, 10); + }); + }); + + describe('randint', () => { + it('should create a tensor with the correct shape', () => { + const t = torch.randint(0, 10, [3, 3]); + assert.deepStrictEqual(t.shape, [3, 3]); + assert.strictEqual(t.toFlatArray().length, 9); + }); + + it('should create integer values in [low, high)', () => { + const t = torch.randint(5, 15, [20]); + for (const v of t.toFlatArray()) { + assert.isAtLeast(v, 5); + assert.isBelow(v, 15); + assert.strictEqual(v, Math.floor(v)); + } + }); + }); + + describe('linspace', () => { + it('should create evenly spaced values', () => { + const t = torch.linspace(0, 1, 5); + const expected = [0, 0.25, 0.5, 0.75, 1.0]; + assert.deepStrictEqual(t.shape, [5]); + const arr = t.toFlatArray(); + for (let i = 0; i < expected.length; i++) { + assert.closeTo(arr[i], expected[i], 1e-6); + } + }); + + it('should handle negative range', () => { + const t = torch.linspace(-1, 1, 3); + const arr = t.toFlatArray(); + assert.closeTo(arr[0], -1, 1e-6); + assert.closeTo(arr[1], 0, 1e-6); + assert.closeTo(arr[2], 1, 1e-6); + }); + }); + + describe('arange', () => { + it('should create a range of values', () => { + const t = torch.arange(0, 5); + assert.deepStrictEqual(t.toArray(), [0, 1, 2, 3, 4]); + }); + + it('should support custom step', () => { + const t = torch.arange(0, 10, 2); + assert.deepStrictEqual(t.toArray(), [0, 2, 4, 6, 8]); + }); + + it('should support negative step values with appropriate range', () => { + const t = torch.arange(1, 5, 0.5); + assert.deepStrictEqual(t.shape, [8]); + const arr = t.toFlatArray(); + assert.closeTo(arr[0], 1.0, 1e-6); + assert.closeTo(arr[7], 4.5, 1e-6); + }); + }); +}); diff --git a/test/generated.test.js b/test/generated.test.js index 48124685..0a5e3318 100644 --- a/test/generated.test.js +++ b/test/generated.test.js @@ -181,6 +181,22 @@ describe('Automated Tests', () => { }); }); }); + + describe('Activation Functions', () => { + testData.activations?.forEach(test => { + it(test.test_name, () => { + const activation = new torch.nn[test.activation_type](); + + const input = new Tensor(test.input, { requires_grad: true }); + + const output = activation.forward(input); + assertDeepCloseTo(output.toArray(), test.expected_output, `${test.test_name} output`); + + output.sum().backward(); + assertDeepCloseTo(input.grad.toArray(), test.expected_grad_input, `${test.test_name} grad input`); + }); + }); + }); }); describe('Optimizers', () => { diff --git a/test/testcases.gen.js b/test/testcases.gen.js index 0d889875..5bd2cbe0 100644 --- a/test/testcases.gen.js +++ b/test/testcases.gen.js @@ -6886,5 +6886,139 @@ export const testData = { [-0.23760251700878143, -0.16322611272335052, 0.39453938603401184, 0.05112287402153015] ] } + ], + "activations": [ + { + "test_name": "relu_1d", + "activation_type": "ReLU", + "input": [-0.2853364050388336, -0.315053254365921, 0.5482434034347534, 0.03692331537604332, -0.8128055930137634], + "expected_output": [0.0, 0.0, 0.5482434034347534, 0.03692331537604332, 0.0], + "expected_grad_input": [0.0, 0.0, 1.0, 1.0, 0.0] + }, + { + "test_name": "relu_2d", + "activation_type": "ReLU", + "input": [ + [0.012067895382642746, -0.6397443413734436, 0.6415984630584717, -0.5963875651359558], + [0.7354843616485596, 0.0723138153553009, 1.8586984872817993, -0.3944927752017975], + [0.7613471746444702, -1.7989355325698853, -0.6020540595054626, 0.673175573348999] + ], + "expected_output": [ + [0.012067895382642746, 0.0, 0.6415984630584717, 0.0], + [0.7354843616485596, 0.0723138153553009, 1.8586984872817993, 0.0], + [0.7613471746444702, 0.0, 0.0, 0.673175573348999] + ], + "expected_grad_input": [ + [1.0, 0.0, 1.0, 0.0], + [1.0, 1.0, 1.0, 0.0], + [1.0, 0.0, 0.0, 1.0] + ] + }, + { + "test_name": "relu_3d", + "activation_type": "ReLU", + "input": [ + [ + [-0.4702208340167999, -0.6086435317993164, -0.046192023903131485, -1.6457397937774658], + [-0.6960223317146301, 0.23589244484901428, 0.8280861377716064, 0.11044309288263321], + [2.366417407989502, -0.6323433518409729, -0.36151713132858276, -1.6916636228561401] + ], + [ + [-1.3838845491409302, 0.4868715703487396, -1.0020296573638916, 0.0329488180577755], + [1.516424536705017, -0.4389283359050751, -0.39990565180778503, -1.3291341066360474], + [1.591395616531372, -0.1208132952451706, -0.48302069306373596, 0.11329790204763412] + ] + ], + "expected_output": [ + [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.23589244484901428, 0.8280861377716064, 0.11044309288263321], + [2.366417407989502, 0.0, 0.0, 0.0] + ], + [ + [0.0, 0.4868715703487396, 0.0, 0.0329488180577755], + [1.516424536705017, 0.0, 0.0, 0.0], + [1.591395616531372, 0.0, 0.0, 0.11329790204763412] + ] + ], + "expected_grad_input": [ + [ + [0.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 1.0, 1.0], + [1.0, 0.0, 0.0, 0.0] + ], + [ + [0.0, 1.0, 0.0, 1.0], + [1.0, 0.0, 0.0, 0.0], + [1.0, 0.0, 0.0, 1.0] + ] + ] + }, + { + "test_name": "sigmoid_1d", + "activation_type": "Sigmoid", + "input": [0.1491728127002716, -1.0009846687316895, -1.501810908317566, 0.00793869886547327, 0.8266488909721375], + "expected_output": [0.5372242331504822, 0.26874786615371704, 0.18215559422969818, 0.5019846558570862, 0.6956458687782288], + "expected_grad_input": [0.2486143559217453, 0.19652244448661804, 0.1489749252796173, 0.24999606609344482, 0.21172268688678741] + }, + { + "test_name": "sigmoid_2d", + "activation_type": "Sigmoid", + "input": [ + [-1.0300014019012451, 1.7748093605041504, 0.24461546540260315, 1.4372375011444092], + [-0.706683874130249, 1.3421580791473389, 0.5234800577163696, -0.26403290033340454], + [-0.3285827040672302, -0.3712422847747803, -0.5473041534423828, 1.3824070692062378] + ], + "expected_output": [ + [0.2630838453769684, 0.8550547957420349, 0.5608507394790649, 0.8080264925956726], + [0.3303320109844208, 0.7928445935249329, 0.6279611587524414, 0.43437260389328003], + [0.41858553886413574, 0.4082408845424652, 0.36649009585380554, 0.7993773221969604] + ], + "expected_grad_input": [ + [0.19387073814868927, 0.12393609434366226, 0.2462971806526184, 0.15511967241764069], + [0.22121275961399078, 0.16424204409122467, 0.23362594842910767, 0.24569304287433624], + [0.24337168037891388, 0.24158024787902832, 0.2321750968694687, 0.16037322580814362] + ] + }, + { + "test_name": "sigmoid_3d", + "activation_type": "Sigmoid", + "input": [ + [ + [1.179942011833191, -0.33142781257629395, 0.6495042443275452, 0.09495851397514343], + [-0.7525874376296997, -0.647229790687561, -1.2822614908218384, 1.96529221534729], + [-0.8427883982658386, -1.6412683725357056, -0.718093991279602, -0.10895649343729019] + ], + [ + [-1.8299661874771118, 0.3647086024284363, 0.7893157005310059, -1.3340543508529663], + [-0.6752517223358154, -0.8103978037834167, -0.8329648971557617, 1.8296456336975098], + [0.7778829336166382, -0.05762312188744545, -1.3171327114105225, 0.15818659961223602] + ] + ], + "expected_output": [ + [ + [0.7649374008178711, 0.41789326071739197, 0.6568987369537354, 0.5237218141555786], + [0.3202577829360962, 0.3436140716075897, 0.2171655148267746, 0.8771045804023743], + [0.3009478449821472, 0.16229255497455597, 0.3278128504753113, 0.4727878272533417] + ], + [ + [0.13824230432510376, 0.5901797413825989, 0.6876844167709351, 0.2084895372390747], + [0.3373218774795532, 0.30780571699142456, 0.3030185401439667, 0.8617194890975952], + [0.6852236390113831, 0.48559820652008057, 0.2112957388162613, 0.5394644141197205] + ] + ], + "expected_grad_input": [ + [ + [0.17980816960334778, 0.24325847625732422, 0.22538278996944427, 0.24943727254867554], + [0.21769273281097412, 0.22554342448711395, 0.17000465095043182, 0.10779213905334473], + [0.2103782445192337, 0.13595367968082428, 0.22035159170627594, 0.24925948679447174] + ], + [ + [0.11913137137889862, 0.24186761677265167, 0.21477456390857697, 0.1650216430425644], + [0.22353583574295044, 0.2130613625049591, 0.21119830012321472, 0.11915901303291321], + [0.2156922072172165, 0.24979259073734283, 0.16664984822273254, 0.24844256043434143] + ] + ] + } ] }; From 89bf15bc8f1ceb402ecb23982240e906248b2b6b Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 13:55:58 +0800 Subject: [PATCH 105/128] fix: remove scratch files --- .gitignore | 8 +++++--- test.py | 12 ------------ 2 files changed, 5 insertions(+), 15 deletions(-) delete mode 100644 test.py diff --git a/.gitignore b/.gitignore index 32aca4cb..60309219 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ # See https://help.github.com/ignore-files/ for more about ignoring files. /docs +.direnv +.idea +/test.js +/test.py + # dependencies /node_modules @@ -52,6 +57,3 @@ yarn-error.log # We use .node-version /.tool-versions - -.direnv -.idea diff --git a/test.py b/test.py deleted file mode 100644 index e17ff8c3..00000000 --- a/test.py +++ /dev/null @@ -1,12 +0,0 @@ -import torch - -x = torch.nn.Linear(2, 3) -with torch.no_grad(): - x.weight.copy_(torch.tensor([[1, 2], [3, 4], [5, 6]], dtype=torch.float32)) - x.bias.copy_(torch.tensor([1, 2, 3], dtype=torch.float32)) - -input = torch.tensor([1, 2], dtype=torch.float32) -output = x(input).sum() -output.backward() -print(x.weight.grad) -print(x.bias.grad) \ No newline at end of file From 491a0ff675048ad0b3db339c86dbdf06121f6338 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 14:01:45 +0800 Subject: [PATCH 106/128] docs: remove done todo --- src/tensor.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/tensor.ts b/src/tensor.ts index 841d1fbb..45501d99 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -2,11 +2,6 @@ import { AccumulateGrad, TorchFunction, resultRequiresGrad } from './functions/b import { getOperationCache, createOperation } from './functions/registry'; import { getNextId, eventBus, events } from './util'; -/* - * TODO: - * - Add support for Textures to be stored in Tensors - */ - export type TypedArray = | Int8Array | Uint8Array @@ -170,8 +165,6 @@ export class Tensor { backward(grad?: Tensor | null): void { if (!this.requires_grad) { - // If this tensor does not require gradients, stop propagation. - // TODO: check pytorch behaviour return; } From f4729e9efb7e166b0f1c2b57d35a4f3b7f5ea211 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 14:21:33 +0800 Subject: [PATCH 107/128] ci: clarify workflow test descriptions. --- .github/workflows/build-test-publish.yml | 6 +++--- .github/workflows/verify-generated-tests.yml | 8 -------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 6fa5d4fc..e38321b6 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -23,13 +23,13 @@ jobs: - name: Install dependencies run: yarn install --immutable - - name: Test on src/ + - name: Test on src/ and get test coverage run: yarn test:coverage - name: Build run: yarn build - - name: Test on build/ + - name: Test on build/ to check minification does not break functionality run: yarn test:build - name: Build docs @@ -59,7 +59,7 @@ jobs: uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs # The folder the action should deploy. + publish_dir: ./docs - name: Publish package run: yarn pkg-pr-new publish diff --git a/.github/workflows/verify-generated-tests.yml b/.github/workflows/verify-generated-tests.yml index 2b1a3d86..15df3396 100644 --- a/.github/workflows/verify-generated-tests.yml +++ b/.github/workflows/verify-generated-tests.yml @@ -34,20 +34,12 @@ jobs: - name: Sanity Check Generated File Length run: | - # 1. Count lines of the file currently checked into Git COMMITTED_LINES=$(wc -l < test/testcases.gen.js) - - # 2. Regenerate the file using your script yarn update-tests - - # 3. Count lines of the newly generated file GENERATED_LINES=$(wc -l < test/testcases.gen.js) - - # 4. Compare and fail if different if [ "$COMMITTED_LINES" -ne "$GENERATED_LINES" ]; then echo "❌ Line count mismatch! Committed: $COMMITTED_LINES, Generated: $GENERATED_LINES." echo "Please run 'yarn update-tests' locally and commit the updated test file." exit 1 fi - echo "✅ Line counts match ($COMMITTED_LINES lines). Sanity check passed." From d93f5065241502d36ff91ef9591263d1529c3829 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 11 Mar 2026 14:21:49 +0800 Subject: [PATCH 108/128] chore: remove jest config as we use mocha --- jest.config.js | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 jest.config.js diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index fcd798d5..00000000 --- a/jest.config.js +++ /dev/null @@ -1,15 +0,0 @@ -export default { - preset: 'ts-jest', - testEnvironment: 'node', - roots: ['/test'], - testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'], - transform: { - '^.+\\.ts$': 'ts-jest', - }, - collectCoverageFrom: [ - 'src/**/*.ts', - '!src/**/*.d.ts', - ], - moduleFileExtensions: ['ts', 'js', 'json'], - testTimeout: 10000, -}; From b9309e82245a4c1cd4c853e9d1cebb10702d7bb9 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Mon, 16 Mar 2026 19:21:31 +0800 Subject: [PATCH 109/128] docs: pyodide example as package --- examples/pyodide/.gitignore | 144 ++++++++++++++++++++++++++++++++++ examples/pyodide/package.json | 10 +++ examples/pyodide/yarn.lock | 53 +++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 examples/pyodide/.gitignore create mode 100644 examples/pyodide/package.json create mode 100644 examples/pyodide/yarn.lock diff --git a/examples/pyodide/.gitignore b/examples/pyodide/.gitignore new file mode 100644 index 00000000..2aa8c99a --- /dev/null +++ b/examples/pyodide/.gitignore @@ -0,0 +1,144 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.* +!.env.example + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist +.output + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Sveltekit cache directory +.svelte-kit/ + +# vitepress build output +**/.vitepress/dist + +# vitepress cache directory +**/.vitepress/cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# Firebase cache directory +.firebase/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# pnpm +.pnpm-store + +# yarn v3 +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# Vite files +vite.config.js.timestamp-* +vite.config.ts.timestamp-* +.vite/ diff --git a/examples/pyodide/package.json b/examples/pyodide/package.json new file mode 100644 index 00000000..1e5aa0cc --- /dev/null +++ b/examples/pyodide/package.json @@ -0,0 +1,10 @@ +{ + "name": "example-pyodide", + "version": "0.1.0", + "private": true, + "type": "module", + "dependencies": { + "pyodide": "^0.29.3", + "torch": "portal:../../" + } +} diff --git a/examples/pyodide/yarn.lock b/examples/pyodide/yarn.lock new file mode 100644 index 00000000..0c93a3a3 --- /dev/null +++ b/examples/pyodide/yarn.lock @@ -0,0 +1,53 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@types/emscripten@npm:^1.41.4": + version: 1.41.5 + resolution: "@types/emscripten@npm:1.41.5" + checksum: 10c0/ae816da716f896434e59df7a71b67c71ae7e85ca067a32aef1616572fc4757459515d42ade6f5b8fd8d69733a9dbd0cf23010fec5b2f41ce52c09501aa350e45 + languageName: node + linkType: hard + +"example-pyodide@workspace:.": + version: 0.0.0-use.local + resolution: "example-pyodide@workspace:." + dependencies: + pyodide: "npm:^0.29.3" + torch: "portal:../../" + languageName: unknown + linkType: soft + +"pyodide@npm:^0.29.3": + version: 0.29.3 + resolution: "pyodide@npm:0.29.3" + dependencies: + "@types/emscripten": "npm:^1.41.4" + ws: "npm:^8.5.0" + checksum: 10c0/4c8108e9af7cd8997812507a01c3dd48789ab58973bdef3ac5a336c38837e7495146195be7fb8b0798bcc3c4f79e98877efaf0672d18e088488512eefbf1d3ca + languageName: node + linkType: hard + +"torch@portal:../../::locator=example-pyodide%40workspace%3A.": + version: 0.0.0-use.local + resolution: "torch@portal:../../::locator=example-pyodide%40workspace%3A." + languageName: node + linkType: soft + +"ws@npm:^8.5.0": + version: 8.19.0 + resolution: "ws@npm:8.19.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/4741d9b9bc3f9c791880882414f96e36b8b254e34d4b503279d6400d9a4b87a033834856dbdd94ee4b637944df17ea8afc4bce0ff4a1560d2166be8855da5b04 + languageName: node + linkType: hard From 60c44652dea6ede61d34f8c752f53878578c2c5b Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Tue, 17 Mar 2026 14:29:01 +0800 Subject: [PATCH 110/128] feat: support pyodide and tests --- .github/workflows/pyodide-test.yml | 45 ++ examples/pyodide/bridge.py | 615 +++++++++++++++++++++++---- examples/pyodide/index.html | 108 ++--- examples/pyodide/main.js | 120 ++++++ examples/pyodide/package.json | 4 + examples/pyodide/py/basic_ops.py | 122 ++++++ examples/pyodide/py/custom_module.py | 88 ++++ examples/pyodide/py/linear_model.py | 83 ++++ examples/pyodide/py/no_grad.py | 53 +++ examples/pyodide/py/training_sgd.py | 81 ++++ src/creation/initializers.ts | 6 +- src/functions/functional.ts | 4 + src/tensor.ts | 11 + test/functional.test.js | 43 ++ 14 files changed, 1249 insertions(+), 134 deletions(-) create mode 100644 .github/workflows/pyodide-test.yml create mode 100644 examples/pyodide/main.js create mode 100644 examples/pyodide/py/basic_ops.py create mode 100644 examples/pyodide/py/custom_module.py create mode 100644 examples/pyodide/py/linear_model.py create mode 100644 examples/pyodide/py/no_grad.py create mode 100644 examples/pyodide/py/training_sgd.py diff --git a/.github/workflows/pyodide-test.yml b/.github/workflows/pyodide-test.yml new file mode 100644 index 00000000..9e81f6d0 --- /dev/null +++ b/.github/workflows/pyodide-test.yml @@ -0,0 +1,45 @@ +name: Pyodide Test + +on: [push] + +jobs: + pyodide-test: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out source code + uses: actions/checkout@v6 + + - name: Enable Corepack + run: corepack enable + + - name: Use Node.js 💻 + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: yarn + + - name: Install root dependencies + run: yarn install --immutable + + - name: Build library + run: yarn build + + - name: Install Pyodide example dependencies + run: cd examples/pyodide && yarn install --immutable + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.14' + cache: 'pip' + cache-dependency-path: scripts/requirements.txt + + - name: Install Python Dependencies + run: pip install -r scripts/requirements.txt + + - name: Generate PyTorch output + run: cd examples/pyodide && yarn gen-cache + + - name: Run Pyodide Tests + run: cd examples/pyodide && yarn test-pyodide diff --git a/examples/pyodide/bridge.py b/examples/pyodide/bridge.py index cadf36bb..63ff0f53 100644 --- a/examples/pyodide/bridge.py +++ b/examples/pyodide/bridge.py @@ -1,142 +1,597 @@ -# This is a very rough draft. +# bridge.py +# Provides a PyTorch-compatible Python API over js_torch (the TypeScript torch library). +# +# Before loading this file, set the following globals in Pyodide: +# js_torch - the torch module (window.torch from the UMD build) -# assume js_torch is available from pyodide.ffi import JsProxy, to_js + +# --------------------------------------------------------------------------- +# Internal helpers +# --------------------------------------------------------------------------- + +def _wrap_result(result): + """ + Wrap a JS return value: + - JsProxy (JS object/Tensor) -> Python Tensor + - Python primitive (int, float, bool) -> return as-is + JS primitives are automatically converted to Python by Pyodide, + so they will NOT be JsProxy instances. + """ + if isinstance(result, JsProxy): + return Tensor(result) + return result + + def _transform(obj): + """Convert Python objects to JS-compatible types before passing to JS.""" if isinstance(obj, Tensor): - return obj.get_tensor() - elif isinstance(obj, list) or isinstance(obj, tuple): - return torch_utils.to_js_list(obj) - else: - return obj + return obj._js + if isinstance(obj, (list, tuple)): + return to_js([_transform(item) for item in obj]) + return obj + def _transform_args(args): - return list(map(_transform, args)) + return [_transform(a) for a in args] + -def _transform_kwargs(kwargs): - return to_js({k: _transform(v) for k, v in kwargs.items()}) +# --------------------------------------------------------------------------- +# Tensor +# --------------------------------------------------------------------------- class Tensor: - # dealing with when .grad is None + """Python wrapper around a JS Tensor, mirroring the PyTorch Tensor API.""" + + # ------------------------------------------------------------------ + # Construction + # ------------------------------------------------------------------ + def __new__(cls, data, requires_grad=False): - if(data is None): + # Return None for missing tensors so e.g. `tensor.grad` returns None + # when there is no gradient — matching PyTorch behaviour. + # Pyodide may represent JS null as a special JsNull type (not JsProxy, not None). + if data is None or type(data).__name__ in ('JsNull', 'JsUndefined'): return None return super().__new__(cls) def __init__(self, data, requires_grad=False): - # print(type(data)) - # self.data = js_torch.tensor(data) if isinstance(data, JsProxy): - self.data = data + self._js = data else: - # print("creating tensor from data", data) - self.data = torch_utils.create_tensor_from_python_data(data, requires_grad) - # print("created tensor", self.tolist()) + js_data = to_js(data) if isinstance(data, (list, tuple)) else data + self._js = js_torch.tensor(js_data, requires_grad) + + # ------------------------------------------------------------------ + # Representation + # ------------------------------------------------------------------ def __repr__(self): - return f"Tensor(data={self.tolist()}{', requires_grad=True' if self.get_tensor().requires_grad else ''})" + extra = ", requires_grad=True" if self.requires_grad else "" + return f"tensor({self.tolist()}{extra})" + + # ------------------------------------------------------------------ + # Data access + # ------------------------------------------------------------------ def tolist(self): - return torch_utils.get_data_from_tensor(self.data).to_py() + """Return tensor data as a (nested) Python list, or a Python scalar for 0-d tensors.""" + result = self._js.toArray() + if isinstance(result, JsProxy): + return result.to_py() + return result # scalar - def get_tensor(self): - return self.data + def item(self): + return self._js.item() - def backward(self): - self.get_tensor().backward() - - @property - def grad(self): - return Tensor(self.get_tensor().grad) + # ------------------------------------------------------------------ + # Properties + # ------------------------------------------------------------------ @property def shape(self): - return self.get_tensor().shape.to_py() + return tuple(self._js.shape.to_py()) - def item(self): - return self.get_tensor().item() + @property + def data(self): + """Detached view of the tensor data (no gradient).""" + return self.detach() - def sum(self, dim=-1, keepdim=False): - return Tensor(self.get_tensor().sum(dim, keepdim)) + @property + def requires_grad(self): + return bool(self._js.requires_grad) - def zero_grad(self): - self.get_tensor().zero_grad() + @requires_grad.setter + def requires_grad(self, value): + self._js.requires_grad = value - def __try_op__(self, op, other, func): - other_data = other.get_tensor() if isinstance(other, Tensor) else other - return Tensor(func(self.get_tensor(), other_data)) + @property + def grad(self): + raw = self._js.grad + if raw is None or type(raw).__name__ in ('JsNull', 'JsUndefined'): + return None + return Tensor(raw) - def __add__(self, other): - return self.__try_op__("add", other, lambda a, b: a.add(b)) + @grad.setter + def grad(self, value): + self._js.grad = value._js if isinstance(value, Tensor) else None - def __radd__(self, other): - return self.__try_op__("radd", other, lambda a, b: a.add(b)) + @property + def T(self): + if len(self.shape) < 2: + return self + return Tensor(self._js.transpose(0, 1)) + + # ------------------------------------------------------------------ + # Grad utilities + # ------------------------------------------------------------------ + + def backward(self, gradient=None): + if gradient is None: + self._js.backward() + else: + self._js.backward(gradient._js) - def __mul__(self, other): - return self.__try_op__("mul", other, lambda a, b: a.mul(b)) + def detach(self): + return Tensor(self._js.detach()) - def __rmul__(self, other): - return self.__try_op__("rmul", other, lambda a, b: a.mul(b)) + def zero_(self): + self._js.zero_() + return self - def __truediv__(self, other): - return self.__try_op__("truediv", other, lambda a, b: a.div(b)) + def retain_grad(self): + self._js.retain_grad() - def __sub__(self, other): - return self.__try_op__("sub", other, lambda a, b: a.sub(b)) + # ------------------------------------------------------------------ + # Shape utilities + # ------------------------------------------------------------------ - def __pow__(self, other): - return self.__try_op__("pow", other, lambda a, b: a.pow(b)) + def size(self, dim=None): + s = self.shape + return s if dim is None else s[dim] - def __matmul__(self, other): - return self.__try_op__("matmul", other, lambda a, b: a.matmul(b)) + def dim(self): + return len(self.shape) - # For when doing e.g. {a:.5f} - def __format__(self, format_spec): - return format(self.item(), format_spec) + def numel(self): + n = 1 + for s in self.shape: + n *= s + return n def reshape(self, *args): - return Tensor(self.get_tensor().reshape( - torch_utils.to_js_list(args) - )) - + shape = list(args[0]) if len(args) == 1 and isinstance(args[0], (list, tuple)) else list(args) + return Tensor(self._js.reshape(to_js(shape))) + + def view(self, *args): + return self.reshape(*args) + + def squeeze(self, dim=None): + if dim is None: + new_shape = [s for s in self.shape if s != 1] + return Tensor(self._js.reshape(to_js(new_shape or [1]))) + return Tensor(self._js.squeeze(dim)) + + def unsqueeze(self, dim): + return Tensor(self._js.unsqueeze(dim)) + + def expand(self, *args): + shape = list(args[0]) if len(args) == 1 and isinstance(args[0], (list, tuple)) else list(args) + return Tensor(self._js.expand(to_js(shape))) + + def transpose(self, dim0, dim1): + return Tensor(self._js.transpose(dim0, dim1)) + + def flatten(self, start_dim=0, end_dim=-1): + n = self.numel() + return self.reshape([n]) + + # ------------------------------------------------------------------ + # Reductions — default (no dim) sums all elements, matching PyTorch + # ------------------------------------------------------------------ + + def sum(self, dim=None, keepdim=False): + return Tensor(self._js.sum() if dim is None else self._js.sum(dim, keepdim)) + + def mean(self, dim=None, keepdim=False): + return Tensor(self._js.mean() if dim is None else self._js.mean(dim, keepdim)) + + def max(self, dim=None, keepdim=False): + return Tensor(self._js.max() if dim is None else self._js.max(dim, keepdim)) + + def min(self, dim=None, keepdim=False): + return Tensor(self._js.min() if dim is None else self._js.min(dim, keepdim)) + + # ------------------------------------------------------------------ + # Arithmetic — explicit methods + # ------------------------------------------------------------------ + + def _to_js(self, other): + return other._js if isinstance(other, Tensor) else other + + def add(self, other): return Tensor(self._js.add(self._to_js(other))) + def sub(self, other): return Tensor(self._js.sub(self._to_js(other))) + def mul(self, other): return Tensor(self._js.mul(self._to_js(other))) + def div(self, other): return Tensor(self._js.div(self._to_js(other))) + def pow(self, other): return Tensor(self._js.pow(self._to_js(other))) + def matmul(self, other): return Tensor(self._js.matmul(self._to_js(other))) + + # ------------------------------------------------------------------ + # Arithmetic operators + # ------------------------------------------------------------------ + + def __add__(self, other): return self.add(other) + def __radd__(self, other): return self.add(other) # add is commutative + def __sub__(self, other): return self.sub(other) + def __rsub__(self, other): + o = other if isinstance(other, Tensor) else Tensor(other) + return o.sub(self) + def __mul__(self, other): return self.mul(other) + def __rmul__(self, other): return self.mul(other) # mul is commutative + def __truediv__(self, other): return self.div(other) + def __rtruediv__(self, other): + o = other if isinstance(other, Tensor) else Tensor(other) + return o.div(self) + def __pow__(self, other): return self.pow(other) + def __rpow__(self, other): + o = other if isinstance(other, Tensor) else Tensor(other) + return o.pow(self) + def __matmul__(self, other): return self.matmul(other) + def __neg__(self): return Tensor(self._js.neg()) + def __abs__(self): return Tensor(self._js.abs()) + + # ------------------------------------------------------------------ + # Unary operations + # ------------------------------------------------------------------ + + def neg(self): return Tensor(self._js.neg()) + def abs(self): return Tensor(self._js.abs()) + def log(self): return Tensor(self._js.log()) + def exp(self): return Tensor(self._js.exp()) + def sqrt(self): return Tensor(self._js.sqrt()) + def square(self): return Tensor(self._js.square()) + def sin(self): return Tensor(self._js.sin()) + def cos(self): return Tensor(self._js.cos()) + def tan(self): return Tensor(self._js.tan()) + def sigmoid(self): return Tensor(self._js.sigmoid()) + def relu(self): return Tensor(js_torch.nn.functional.relu(self._js)) + def sign(self): return Tensor(self._js.sign()) + def reciprocal(self): return Tensor(self._js.reciprocal()) + def nan_to_num(self): return Tensor(self._js.nan_to_num()) + + # ------------------------------------------------------------------ + # Comparison + # ------------------------------------------------------------------ + + def lt(self, other): return Tensor(self._js.lt(self._to_js(other))) + def gt(self, other): return Tensor(self._js.gt(self._to_js(other))) + def le(self, other): return Tensor(self._js.le(self._to_js(other))) + def ge(self, other): return Tensor(self._js.ge(self._to_js(other))) + def eq(self, other): return Tensor(self._js.eq(self._to_js(other))) + def ne(self, other): return Tensor(self._js.ne(self._to_js(other))) + def allclose(self, other, rtol=1e-5, atol=1e-8, equal_nan=False): - return self.get_tensor().allclose(other.get_tensor(), rtol, atol, equal_nan) + return bool(js_torch.allclose(self._js, other._js, rtol, atol, equal_nan)) + + # ------------------------------------------------------------------ + # Type conversions + # ------------------------------------------------------------------ + + def __float__(self): return float(self.item()) + def __int__(self): return int(self.item()) + def __bool__(self): return bool(self.item()) + def __format__(self, fmt): return format(self.item(), fmt) + + # ------------------------------------------------------------------ + # Iteration and length + # ------------------------------------------------------------------ + + def __len__(self): + return self.shape[0] - # Make iterable so that can unpack def __iter__(self): - return iter(self.tolist()) + data = self.tolist() + if not isinstance(data, list): + raise TypeError("iteration over a 0-d tensor") + for item in data: + yield Tensor(item) + + # ------------------------------------------------------------------ + # Catch-all: delegate unknown attribute accesses to the JS tensor. + # Returned JsProxy objects are wrapped in Tensor; primitives pass through. + # ------------------------------------------------------------------ def __getattr__(self, name): - return lambda *args, **kwargs: Tensor(self.get_tensor().__getattribute__(name)( - *_transform_args(args), _transform_kwargs(kwargs) - )) + if name.startswith('_'): + raise AttributeError(name) + def method(*args, **kwargs): + js_args = _transform_args(args) + return _wrap_result(self._js.__getattribute__(name)(*js_args)) + return method + + +# --------------------------------------------------------------------------- +# no_grad context manager — actually disables grad in the JS engine +# --------------------------------------------------------------------------- class _NoGrad: def __enter__(self): - pass + self._prev = js_torch.enable_no_grad() + return self + + def __exit__(self, *args): + js_torch.disable_no_grad(self._prev) + + +# --------------------------------------------------------------------------- +# Parameter +# --------------------------------------------------------------------------- + +class Parameter(Tensor): + """A Tensor that is automatically registered as a parameter.""" + def __init__(self, data, requires_grad=True): + if isinstance(data, Tensor): + self._js = js_torch.nn.Parameter.new(data._js) + elif isinstance(data, JsProxy): + self._js = js_torch.nn.Parameter.new(data) + else: + self._js = js_torch.nn.Parameter.new(js_torch.tensor(data)) + if not requires_grad: + self._js.requires_grad = False + + +# --------------------------------------------------------------------------- +# Module — pure-Python base class for user-defined models +# --------------------------------------------------------------------------- + +class Module: + """ + Pure-Python nn.Module. Subclass this to build models using bridge Tensors. + Assign `Parameter` or `_NNModule` instances as attributes and they are + automatically tracked by `parameters()`. + """ + + def __init__(self): + object.__setattr__(self, '_parameters', {}) + object.__setattr__(self, '_modules', {}) + + def __setattr__(self, name, value): + try: + params = object.__getattribute__(self, '_parameters') + modules = object.__getattribute__(self, '_modules') + except AttributeError: + object.__setattr__(self, name, value) + return + + if isinstance(value, Tensor) and value.requires_grad: + params[name] = value + elif isinstance(value, (Module, _NNModule)): + modules[name] = value + object.__setattr__(self, name, value) + + def __call__(self, *args, **kwargs): + return self.forward(*args, **kwargs) + + def forward(self, *args, **kwargs): + raise NotImplementedError + + def parameters(self): + params = list(object.__getattribute__(self, '_parameters').values()) + for mod in object.__getattribute__(self, '_modules').values(): + params.extend(mod.parameters()) + return params + + def named_parameters(self, prefix=''): + result = [] + for name, p in object.__getattribute__(self, '_parameters').items(): + full = f"{prefix}.{name}" if prefix else name + result.append((full, p)) + for mod_name, mod in object.__getattribute__(self, '_modules').items(): + full_mod = f"{prefix}.{mod_name}" if prefix else mod_name + result.extend(mod.named_parameters(full_mod)) + return result + + def zero_grad(self): + for p in self.parameters(): + p.grad = None + + +# --------------------------------------------------------------------------- +# _NNModule — wraps a JS nn.Module instance +# --------------------------------------------------------------------------- + +class _NNModule: + """Wraps a JS nn.Module returned by the nn factory functions.""" + + def __init__(self, js_module): + self._module = js_module + + def __call__(self, *args): + js_args = [a._js if isinstance(a, Tensor) else a for a in args] + return Tensor(self._module.forward(*js_args)) + + def forward(self, *args): + return self(*args) + + def parameters(self): + return [Tensor(p) for p in self._module.parameters().to_py()] + + def named_parameters(self, prefix=''): + raw = self._module.named_parameters(prefix).to_py() + return [(pair[0], Tensor(pair[1])) for pair in raw] + + def zero_grad(self): + for p in self.parameters(): + p.grad = None + + +# --------------------------------------------------------------------------- +# nn.functional +# --------------------------------------------------------------------------- + +class _NNFunctional: + def relu(self, input): + return Tensor(js_torch.nn.functional.relu(input._js)) + + def sigmoid(self, input): + return Tensor(js_torch.nn.functional.sigmoid(input._js)) + + def __getattr__(self, name): + if name.startswith('_'): + raise AttributeError(name) + def fn(*args, **kwargs): + return _wrap_result(js_torch.nn.functional.__getattribute__(name)(*_transform_args(args))) + return fn + + +# --------------------------------------------------------------------------- +# nn namespace +# --------------------------------------------------------------------------- + +class _NNNamespace: + def __init__(self): + self.functional = _NNFunctional() + self.Module = Module + self.Parameter = Parameter + + def Linear(self, in_features, out_features): + return _NNModule(js_torch.nn.Linear.new(in_features, out_features)) + + def ReLU(self): + return _NNModule(js_torch.nn.ReLU.new()) + + def Sigmoid(self): + return _NNModule(js_torch.nn.Sigmoid.new()) - def __exit__(self, type, value, traceback): - pass + def Sequential(self, *modules): + js_mods = [m._module for m in modules] + return _NNModule(js_torch.nn.Sequential.new(*js_mods)) + + def MSELoss(self): + return _NNModule(js_torch.nn.MSELoss.new()) + + def L1Loss(self): + return _NNModule(js_torch.nn.L1Loss.new()) + + def BCELoss(self): + return _NNModule(js_torch.nn.BCELoss.new()) + + +# --------------------------------------------------------------------------- +# optim wrappers +# --------------------------------------------------------------------------- + +class _Optimizer: + def __init__(self, js_optim): + self._optim = js_optim + + def step(self): + self._optim.step() + + def zero_grad(self): + self._optim.zero_grad() + + +class _OptimNamespace: + def SGD(self, params, lr=0.001, momentum=0.0, dampening=0.0, + weight_decay=0.0, nesterov=False, maximize=False): + js_params = to_js([p._js for p in params]) + return _Optimizer(js_torch.optim.SGD.new( + js_params, lr, momentum, dampening, weight_decay, nesterov, maximize + )) + + def Adam(self, params, lr=0.001, betas=(0.9, 0.999), eps=1e-8, + weight_decay=0.0, amsgrad=False, maximize=False): + js_params = to_js([p._js for p in params]) + js_betas = to_js(list(betas)) + return _Optimizer(js_torch.optim.Adam.new( + js_params, lr, js_betas, eps, weight_decay, amsgrad, maximize + )) + + +# --------------------------------------------------------------------------- +# torch namespace +# --------------------------------------------------------------------------- class _Torch: - no_grad = _NoGrad + def __init__(self): + self.nn = _NNNamespace() + self.optim = _OptimNamespace() + self.no_grad = _NoGrad @property def tensor(self): return Tensor - def __getattr__(self, name): - return lambda *args, **kwargs: Tensor(js_torch.__getattribute__(name)( - *_transform_args(args), _transform_kwargs(kwargs) - )) + # --- creation functions --- - def Size(self, shape): - return shape + def _shape_from_args(self, args): + return list(args[0]) if len(args) == 1 and isinstance(args[0], (list, tuple)) else list(args) + + def zeros(self, *args, **kwargs): + return Tensor(js_torch.zeros(to_js(self._shape_from_args(args)))) + + def ones(self, *args, **kwargs): + return Tensor(js_torch.ones(to_js(self._shape_from_args(args)))) + + def zeros_like(self, input): + return Tensor(js_torch.zeros_like(input._js)) + + def ones_like(self, input): + return Tensor(js_torch.ones_like(input._js)) + + def randn(self, *args, **kwargs): + return Tensor(js_torch.randn(to_js(self._shape_from_args(args)))) + + def rand(self, *args, **kwargs): + return Tensor(js_torch.rand(to_js(self._shape_from_args(args)))) + + def arange(self, start, end=None, step=1): + if end is None: + end = start + start = 0 + return Tensor(js_torch.arange(start, end, step)) + + def linspace(self, start, end, steps): + return Tensor(js_torch.linspace(start, end, steps)) + + # --- functional wrappers --- + + def sum(self, input, dim=None, keepdim=False): + return input.sum(dim, keepdim) + + def mean(self, input, dim=None, keepdim=False): + return input.mean(dim, keepdim) + + def allclose(self, a, b, rtol=1e-5, atol=1e-8, equal_nan=False): + return a.allclose(b, rtol, atol, equal_nan) + + def is_grad_enabled(self): + return bool(js_torch.is_grad_enabled()) def cat(self, tensors, dim=0): - return Tensor(js_torch.cat(torch_utils.to_js_list(list(map(lambda x: x.get_tensor(), tensors))), dim)) + """Concatenate tensors along dim. NOTE: gradient is not tracked.""" + if dim != 0: + raise NotImplementedError("torch.cat only supports dim=0 in this bridge") + result = [] + for t in tensors: + data = t.tolist() + if isinstance(data, list): + result.extend(data) + else: + result.append(data) + return Tensor(result) + + def Size(self, shape): + return list(shape) + + def __getattr__(self, name): + if name.startswith('_'): + raise AttributeError(name) + def fn(*args, **kwargs): + return _wrap_result(js_torch.__getattribute__(name)(*_transform_args(args))) + return fn -# torch = lambda: None -torch = _Torch() \ No newline at end of file +torch = _Torch() diff --git a/examples/pyodide/index.html b/examples/pyodide/index.html index e5381f2f..89e82bd2 100644 --- a/examples/pyodide/index.html +++ b/examples/pyodide/index.html @@ -11,24 +11,26 @@

Torch + Pyodide

- + +
+
+
@@ -42,44 +44,28 @@

Output:

diff --git a/examples/pyodide/main.js b/examples/pyodide/main.js new file mode 100644 index 00000000..e2bd329d --- /dev/null +++ b/examples/pyodide/main.js @@ -0,0 +1,120 @@ +import { loadPyodide } from 'pyodide'; +import * as torch from 'torch'; +import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync } from 'fs'; +import { execSync } from 'child_process'; +import path from 'path'; + +const PY_DIR = './py'; +const CACHE_DIR = './.cache'; + +function getPyFiles() { + return readdirSync(PY_DIR).filter(f => f.endsWith('.py')).sort(); +} + +async function setupPyodide() { + const pyodide = await loadPyodide(); + pyodide.globals.set('js_torch', torch); + pyodide.globals.set('_js_is_null', (x) => x == null); + pyodide.runPython(readFileSync('./bridge.py', 'utf8')); + return pyodide; +} + +async function runWithPyodide(pyodide, code) { + // Reset grad state to enabled before each file. + // disable_no_grad(prev) restores a previous state; passing True enables grad. + pyodide.runPython('js_torch.disable_no_grad(True)'); + pyodide.globals.set('_test_code', code); + pyodide.runPython(` +import sys, builtins +from io import StringIO +_ns = {'torch': torch, '__builtins__': builtins} +_saved = sys.stdout +sys.stdout = StringIO() +try: + exec(_test_code, _ns) + _output = sys.stdout.getvalue() +finally: + sys.stdout = _saved +`); + return pyodide.globals.get('_output'); +} + +async function cmdGen() { + if (!existsSync(CACHE_DIR)) mkdirSync(CACHE_DIR); + const files = getPyFiles(); + let ok = 0, fail = 0; + for (const file of files) { + const name = path.basename(file, '.py'); + try { + const output = execSync( + `python3 -c "import torch, builtins; exec(open('${PY_DIR}/${file}').read(), {'torch': torch, '__builtins__': builtins})"`, + { encoding: 'utf8' } + ); + writeFileSync(path.join(CACHE_DIR, `${name}.out`), output); + console.log(`✓ ${name}`); + ok++; + } catch (e) { + console.error(`✗ ${name}: ${e.stderr?.trim() ?? e.message}`); + fail++; + } + } + console.log(`\n${ok} generated, ${fail} failed`); + if (fail > 0) process.exit(1); +} + +async function cmdTest() { + const files = getPyFiles(); + const pyodide = await setupPyodide(); + let passed = 0, failed = 0; + + for (const file of files) { + const name = path.basename(file, '.py'); + const cachePath = path.join(CACHE_DIR, `${name}.out`); + if (!existsSync(cachePath)) { + console.log(`✗ ${name}: no cache (run 'yarn gen-cache' first)`); + failed++; + continue; + } + + const code = readFileSync(path.join(PY_DIR, file), 'utf8'); + let actual; + try { + actual = await runWithPyodide(pyodide, code); + } catch (e) { + console.log(`✗ ${name}: ${e.message}`); + failed++; + continue; + } + + const expected = readFileSync(cachePath, 'utf8'); + const aMarked = actual.split('\n').filter(l => l.startsWith('>')); + const eMarked = expected.split('\n').filter(l => l.startsWith('>')); + const mismatches = []; + const maxLen = Math.max(aMarked.length, eMarked.length); + for (let i = 0; i < maxLen; i++) { + if (aMarked[i] !== eMarked[i]) { + mismatches.push(` [assertion ${i + 1}] expected: ${JSON.stringify(eMarked[i] ?? '(missing)')}`); + mismatches.push(` [assertion ${i + 1}] actual: ${JSON.stringify(aMarked[i] ?? '(missing)')}`); + } + } + if (mismatches.length === 0) { + console.log(`✓ ${name} (${aMarked.length} assertions)`); + passed++; + } else { + console.log(`✗ ${name}: ${mismatches.length / 2} assertion(s) failed`); + mismatches.forEach(l => console.log(l)); + failed++; + } + } + + console.log(`\n${passed} passed, ${failed} failed`); + if (failed > 0) process.exit(1); +} + +const [mode] = process.argv.slice(2); +if (mode === 'gen') cmdGen().catch(e => { console.error(e); process.exit(1); }); +else if (mode === 'test') cmdTest().catch(e => { console.error(e); process.exit(1); }); +else { + console.error('Usage: node main.js [gen|test]'); + process.exit(1); +} diff --git a/examples/pyodide/package.json b/examples/pyodide/package.json index 1e5aa0cc..c7b84a73 100644 --- a/examples/pyodide/package.json +++ b/examples/pyodide/package.json @@ -3,6 +3,10 @@ "version": "0.1.0", "private": true, "type": "module", + "scripts": { + "gen-cache": "node main.js gen", + "test-pyodide": "node main.js test" + }, "dependencies": { "pyodide": "^0.29.3", "torch": "portal:../../" diff --git a/examples/pyodide/py/basic_ops.py b/examples/pyodide/py/basic_ops.py new file mode 100644 index 00000000..7043b094 --- /dev/null +++ b/examples/pyodide/py/basic_ops.py @@ -0,0 +1,122 @@ +# basic_ops.py — Basic tensor operations, autograd, and backward pass. +# Verifies: creation, arithmetic operators, reductions, backward, grad access. + +print("=== Basic tensor creation ===") +x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) +y = torch.tensor([4.0, 5.0, 6.0], requires_grad=True) +print("x:", x) +print("y:", y) +print("x.shape:", x.shape) +print("x.requires_grad:", x.requires_grad) +print("> x.requires_grad:", x.requires_grad) + +print("\n=== Arithmetic operators ===") +print("x + y:", x + y) +print("x - y:", x - y) +print("x * y:", x * y) +print("x / y:", x / y) +print("x ** 2:", x ** 2) +print("> x+y correct:", (x + y).allclose(torch.tensor([5.0, 7.0, 9.0]))) +print("> x*y correct:", (x * y).allclose(torch.tensor([4.0, 10.0, 18.0]))) +print("> x/y correct:", (x / y).allclose(torch.tensor([0.25, 0.4, 0.5]))) + +print("\n=== Scalar arithmetic (reversed operators) ===") +print("2 + x:", 2 + x) # __radd__ +print("10 - x:", 10 - x) # __rsub__ +print("2 * x:", 2 * x) # __rmul__ +print("1 / x:", 1 / x) # __rtruediv__ +print("2 ** x:", 2 ** x) # __rpow__ +print("> 2+x correct:", (2 + x).allclose(torch.tensor([3.0, 4.0, 5.0]))) +print("> 2*x correct:", (2 * x).allclose(torch.tensor([2.0, 4.0, 6.0]))) + +print("\n=== Unary operations ===") +print("-x:", -x) +print("x.neg():", x.neg()) +print("x.abs():", torch.tensor([-1.0, 2.0, -3.0]).abs()) +print("x.sqrt():", x.sqrt()) +print("x.exp():", x.exp()) +print("x.log():", x.log()) +print("x.sigmoid():", x.sigmoid()) +print("x.relu():", torch.tensor([-1.0, 0.0, 2.0]).relu()) +print("> neg correct:", (-x).allclose(torch.tensor([-1.0, -2.0, -3.0]))) +print("> sqrt correct:", x.sqrt().allclose(torch.tensor([1.0, 1.4142, 1.7321]), atol=1e-4)) +print("> relu correct:", torch.tensor([-1.0, 0.0, 2.0]).relu().allclose(torch.tensor([0.0, 0.0, 2.0]))) + +print("\n=== Reductions ===") +a = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) +print("a:", a) +print("a.sum():", a.sum()) # sum all +print("a.sum(dim=0):", a.sum(dim=0)) # sum along rows +print("a.sum(dim=1):", a.sum(dim=1)) # sum along cols +print("a.mean():", a.mean()) +print("a.max():", a.max()) +print("a.min():", a.min()) +print("> a.sum() correct:", a.sum().allclose(torch.tensor(21.0))) +print("> a.sum(dim=0) correct:", a.sum(dim=0).allclose(torch.tensor([5.0, 7.0, 9.0]))) +print("> a.mean() correct:", a.mean().allclose(torch.tensor(3.5))) + +print("\n=== Shape utilities ===") +print("a.shape:", a.shape) +print("a.size():", a.size()) +print("a.size(0):", a.size(0)) +print("a.dim():", a.dim()) +print("a.numel():", a.numel()) +print("a.reshape(3, 2):", a.reshape(3, 2)) +print("a.reshape([6]):", a.reshape([6])) +print("a.T:", a.T) +print("a.transpose(0, 1):", a.transpose(0, 1)) +print("> a.size(0):", a.size(0)) +print("> a.dim():", a.dim()) +print("> a.numel():", a.numel()) + +print("\n=== Comparison operators ===") +b = torch.tensor([1.0, 3.0, 3.0]) +c = torch.tensor([2.0, 2.0, 3.0]) +print("b:", b, " c:", c) +print("b.lt(c):", b.lt(c)) +print("b.gt(c):", b.gt(c)) +print("b.eq(c):", b.eq(c)) + +print("\n=== Backward pass (z = sum(x * y)) ===") +x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) +y = torch.tensor([4.0, 5.0, 6.0], requires_grad=True) +z = (x * y).sum() +print("z:", z) +z.backward() +print("x.grad (expected [4,5,6]):", x.grad) +print("y.grad (expected [1,2,3]):", y.grad) +print("> x.grad correct:", x.grad is not None and x.grad.allclose(torch.tensor([4.0, 5.0, 6.0]))) +print("> y.grad correct:", y.grad is not None and y.grad.allclose(torch.tensor([1.0, 2.0, 3.0]))) + +print("\n=== Backward with chain rule (z = sum((x+1)^2)) ===") +x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) +z = ((x + 1) ** 2).sum() +z.backward() +# dz/dx = 2*(x+1) = [4, 6, 8] +print("x.grad (expected [4,6,8]):", x.grad) +print("> x.grad correct:", x.grad is not None and x.grad.allclose(torch.tensor([4.0, 6.0, 8.0]))) + +print("\n=== allclose ===") +a = torch.tensor([1.0, 2.0, 3.0]) +b = torch.tensor([1.0, 2.0, 3.0000001]) +print("allclose (expected True):", a.allclose(b)) +print("> allclose (expected True):", a.allclose(b)) +b2 = torch.tensor([1.0, 2.0, 4.0]) +print("allclose (expected False):", a.allclose(b2)) +print("> allclose (expected False):", a.allclose(b2)) + +print("\n=== Iteration ===") +t = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) +for row in t: + print("row:", row) +print("> num rows:", sum(1 for _ in torch.tensor([[1.0, 2.0], [3.0, 4.0]]))) + +print("\n=== item(), float(), int() ===") +s = torch.tensor([42.0]) +print("s.item():", s.item()) +print("float(s):", float(s)) +print("int(s):", int(s)) +print("> float(s):", float(s)) +print("> int(s):", int(s)) + +print("\nAll basic_ops checks passed.") diff --git a/examples/pyodide/py/custom_module.py b/examples/pyodide/py/custom_module.py new file mode 100644 index 00000000..ac6ed975 --- /dev/null +++ b/examples/pyodide/py/custom_module.py @@ -0,0 +1,88 @@ +# custom_module.py — User-defined Module subclass (pure Python), training loop. +# Verifies: Module subclassing, parameter registration, forward(), parameters(). + +class TwoLayerNet(torch.nn.Module): + def __init__(self, in_dim, hidden_dim, out_dim): + super().__init__() + self.fc1 = torch.nn.Linear(in_dim, hidden_dim) + self.fc2 = torch.nn.Linear(hidden_dim, out_dim) + + def forward(self, x): + x = self.fc1(x) + x = x.relu() + x = self.fc2(x) + return x + + +print("=== Custom Module construction ===") +model = TwoLayerNet(2, 4, 1) + +x = torch.tensor([[1.0, 2.0], [3.0, 4.0]]) +out = model(x) +print("input shape:", x.shape) +print("output shape:", out.shape) +print("output:", out) + +print("\n=== parameters() collects from all sub-modules ===") +params = list(model.parameters()) +print("number of parameters:", len(params)) +# 2 layers × (weight + bias) = 4 parameters +print("expected 4:", len(params) == 4) +print("> n_params == 4:", len(params) == 4) + +print("\n=== named_parameters() ===") +for name, p in model.named_parameters(): + print(f" {name}: shape={p.shape}") + +print("\n=== Backward through custom Module ===") +loss = out.sum() +loss.backward() +print("All parameter grads computed:") +for name, p in model.named_parameters(): + print(f" {name}.grad is not None:", p.grad is not None) +print("> all param grads computed:", all(p.grad is not None for p in model.parameters())) + +print("\n=== Training loop with custom Module ===") + +# XOR-like dataset (linearly separable approximation) +xs = torch.tensor([ + [0.0, 0.0], + [0.0, 1.0], + [1.0, 0.0], + [1.0, 1.0], +]) +ys = torch.tensor([[0.0], [1.0], [1.0], [0.0]]) + +model = TwoLayerNet(2, 8, 1) +loss_fn = torch.nn.MSELoss() +opt = torch.optim.Adam(model.parameters(), lr=0.05) + +initial_loss = None +for epoch in range(300): + opt.zero_grad() + pred = model(xs) + loss = loss_fn(pred, ys) + loss.backward() + opt.step() + if epoch == 0: + initial_loss = loss.item() + if epoch % 50 == 0: + print(f" epoch {epoch:3d} loss={loss:.4f}") + +print("Loss decreased:", loss.item() < initial_loss) +print("> loss decreased:", loss.item() < initial_loss) + +print("\n=== Module.zero_grad() clears all parameter grads ===") +# Run one backward pass +opt.zero_grad() +model(xs).sum().backward() +grads_exist = all(p.grad is not None for p in model.parameters()) +print("Grads exist after backward:", grads_exist) +print("> grads exist after backward:", grads_exist) + +model.zero_grad() +grads_cleared = all(p.grad is None for p in model.parameters()) +print("Grads cleared after zero_grad:", grads_cleared) +print("> grads cleared after zero_grad:", grads_cleared) + +print("\nAll custom_module checks passed.") diff --git a/examples/pyodide/py/linear_model.py b/examples/pyodide/py/linear_model.py new file mode 100644 index 00000000..4494a4b6 --- /dev/null +++ b/examples/pyodide/py/linear_model.py @@ -0,0 +1,83 @@ +# linear_model.py — torch.nn.Linear forward pass, loss computation, backward. +# Verifies: nn.Linear, MSELoss, BCELoss, Sequential, nn.ReLU, gradient flow. + +print("=== nn.Linear forward pass ===") +fc = torch.nn.Linear(3, 2) +x = torch.tensor([[1.0, 2.0, 3.0]]) # batch of 1, 3 features +out = fc(x) +print("input shape:", x.shape) +print("output shape:", out.shape) +print("output:", out) + +print("\n=== nn.Linear parameters ===") +params = list(fc.parameters()) +print("number of parameters:", len(params)) +print("param shapes:", [p.shape for p in params]) +print("all require grad:", all(p.requires_grad for p in params)) +print("> n_params:", len(params)) +print("> all require grad:", all(p.requires_grad for p in params)) + +print("\n=== named_parameters ===") +for name, p in fc.named_parameters(): + print(f" {name}: shape={p.shape}") + +print("\n=== MSELoss ===") +pred = torch.tensor([1.0, 2.0, 3.0]) +target = torch.tensor([1.5, 2.5, 2.0]) +loss_fn = torch.nn.MSELoss() +loss = loss_fn(pred, target) +print("MSELoss:", loss) +# Expected: mean([(0.5)^2, (0.5)^2, (1)^2]) = mean([0.25, 0.25, 1.0]) = 0.5 +expected = ((1.0-1.5)**2 + (2.0-2.5)**2 + (3.0-2.0)**2) / 3 +print("Expected:", expected) +print("Close:", abs(loss.item() - expected) < 1e-6) +print("> MSELoss close:", abs(loss.item() - expected) < 1e-6) + +print("\n=== L1Loss ===") +loss_fn = torch.nn.L1Loss() +loss = loss_fn(pred, target) +print("L1Loss:", loss) +expected_l1 = (0.5 + 0.5 + 1.0) / 3 +print("Expected:", expected_l1) +print("Close:", abs(loss.item() - expected_l1) < 1e-6) +print("> L1Loss close:", abs(loss.item() - expected_l1) < 1e-6) + +print("\n=== Backward through Linear ===") +fc = torch.nn.Linear(2, 1) +x = torch.tensor([[1.0, 2.0]], requires_grad=True) +out = fc(x) +loss = out.sum() +loss.backward() +print("x.grad (should be non-None):", x.grad) +for name, p in fc.named_parameters(): + print(f" {name}.grad is not None:", p.grad is not None) +print("> x.grad is not None:", x.grad is not None) +print("> all param grads computed:", all(p.grad is not None for p in fc.parameters())) + +print("\n=== Sequential ===") +model = torch.nn.Sequential( + torch.nn.Linear(4, 8), + torch.nn.ReLU(), + torch.nn.Linear(8, 2), +) +x = torch.tensor([[1.0, 0.5, -1.0, 2.0]]) +out = model(x) +print("Sequential output shape:", out.shape) +print("Sequential output:", out) +params = list(model.parameters()) +print("Total parameters:", len(params)) +print("> sequential n_params:", len(params)) + +print("\n=== zero_grad clears gradients ===") +fc = torch.nn.Linear(2, 1) +x = torch.tensor([[1.0, 1.0]]) +out = fc(x).sum() +out.backward() +for name, p in fc.named_parameters(): + print(f" {name}.grad before zero_grad:", p.grad) +fc.zero_grad() +for name, p in fc.named_parameters(): + print(f" {name}.grad after zero_grad (expected None):", p.grad) +print("> grads cleared:", all(p.grad is None for p in fc.parameters())) + +print("\nAll linear_model checks passed.") diff --git a/examples/pyodide/py/no_grad.py b/examples/pyodide/py/no_grad.py new file mode 100644 index 00000000..682ff6ea --- /dev/null +++ b/examples/pyodide/py/no_grad.py @@ -0,0 +1,53 @@ +# no_grad.py — Verify that torch.no_grad() actually disables gradient tracking. + +print("=== no_grad context manager ===") + +x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True) + +print("Grad enabled outside context:", torch.is_grad_enabled()) +print("> Grad enabled outside context:", torch.is_grad_enabled()) + +with torch.no_grad(): + print("Grad enabled inside context:", torch.is_grad_enabled()) + print("> Grad enabled inside context:", torch.is_grad_enabled()) + y = x * 2 + print("y.requires_grad inside no_grad (expected False):", y.requires_grad) + print("> y.requires_grad inside no_grad:", y.requires_grad) + # y has no grad_fn, so backward would be a no-op + +print("Grad enabled after context:", torch.is_grad_enabled()) +print("> Grad enabled after context:", torch.is_grad_enabled()) + +# Outside no_grad, requires_grad propagates normally +z = x * 2 +print("z.requires_grad outside no_grad (expected True):", z.requires_grad) +print("> z.requires_grad outside no_grad:", z.requires_grad) + +print("\n=== Gradient NOT computed inside no_grad ===") +x = torch.tensor([3.0], requires_grad=True) +with torch.no_grad(): + y = x * x # should not build computation graph + print("y:", y) + print("y.requires_grad (expected False):", y.requires_grad) + print("> y.requires_grad inside no_grad:", y.requires_grad) + +# x.grad should still be None since we didn't call backward +print("x.grad after no_grad block (expected None):", x.grad) +print("> x.grad after no_grad block is None:", x.grad is None) + +print("\n=== Gradient IS computed outside no_grad ===") +x = torch.tensor([3.0], requires_grad=True) +y = x * x +y.backward() +print("x.grad after backward (expected 6.0):", x.grad) +print("> x.grad correct:", x.grad is not None and x.grad.allclose(torch.tensor([6.0]))) + +print("\n=== Nested no_grad blocks restore state correctly ===") +print("is_grad_enabled:", torch.is_grad_enabled()) +print("> is_grad_enabled before outer:", torch.is_grad_enabled()) +with torch.no_grad(): + print("inside outer no_grad:", torch.is_grad_enabled()) +print("after outer no_grad (expected True):", torch.is_grad_enabled()) +print("> is_grad_enabled after outer:", torch.is_grad_enabled()) + +print("\nAll no_grad checks passed.") diff --git a/examples/pyodide/py/training_sgd.py b/examples/pyodide/py/training_sgd.py new file mode 100644 index 00000000..ae7133be --- /dev/null +++ b/examples/pyodide/py/training_sgd.py @@ -0,0 +1,81 @@ +# training_sgd.py — Full training loop: fit y = 2x + 1 with SGD and Adam. +# Verifies: optimizer.step(), optimizer.zero_grad(), loss decreases. + +print("=== Training y = 2x + 1 with SGD ===") + +# Dataset: y = 2*x + 1 +xs = torch.tensor([[1.0], [2.0], [3.0], [4.0], [5.0]]) +ys = torch.tensor([[3.0], [5.0], [7.0], [9.0], [11.0]]) + +model = torch.nn.Linear(1, 1) +loss_fn = torch.nn.MSELoss() +opt = torch.optim.SGD(model.parameters(), lr=0.01) + +losses = [] +for epoch in range(200): + opt.zero_grad() + pred = model(xs) + loss = loss_fn(pred, ys) + loss.backward() + opt.step() + if epoch % 40 == 0: + losses.append(loss.item()) + print(f" epoch {epoch:3d} loss={loss:.6f}") + +print("Loss decreased:", losses[-1] < losses[0]) +print("> SGD loss decreased:", losses[-1] < losses[0]) + +with torch.no_grad(): + pred = model(xs) +print("Final predictions:", pred) +print("Expected: ", ys) + +# Check weights are approximately correct (w≈2, b≈1) +params = {name: p for name, p in model.named_parameters()} +w = params['weight'].item() +b = params['bias'].item() +print(f"Learned weight={w:.3f} (expected ~2), bias={b:.3f} (expected ~1)") +print("Weight close:", abs(w - 2.0) < 0.2) +print("Bias close: ", abs(b - 1.0) < 0.5) + +print("\n=== Training y = 2x + 1 with Adam ===") + +model = torch.nn.Linear(1, 1) +loss_fn = torch.nn.MSELoss() +opt = torch.optim.Adam(model.parameters(), lr=0.05) + +losses = [] +for epoch in range(200): + opt.zero_grad() + pred = model(xs) + loss = loss_fn(pred, ys) + loss.backward() + opt.step() + if epoch % 40 == 0: + losses.append(loss.item()) + print(f" epoch {epoch:3d} loss={loss:.6f}") + +print("Loss decreased:", losses[-1] < losses[0]) +print("> Adam loss decreased:", losses[-1] < losses[0]) +params = {name: p for name, p in model.named_parameters()} +w = params['weight'].item() +b = params['bias'].item() +print(f"Learned weight={w:.3f} (expected ~2), bias={b:.3f} (expected ~1)") + +print("\n=== Optimizer.zero_grad() resets gradients ===") +fc = torch.nn.Linear(2, 1) +opt = torch.optim.SGD(fc.parameters(), lr=0.1) + +x = torch.tensor([[1.0, 2.0]]) +fc(x).sum().backward() + +grads_before = [p.grad.tolist() for p in fc.parameters()] +print("Grads after first backward:", grads_before) +print("> grads exist after backward:", all(p.grad is not None for p in fc.parameters())) + +opt.zero_grad() +grads_after = [p.grad for p in fc.parameters()] +print("Grads after zero_grad (expected all None):", grads_after) +print("> grads None after zero_grad:", all(p.grad is None for p in fc.parameters())) + +print("\nAll training_sgd checks passed.") diff --git a/src/creation/initializers.ts b/src/creation/initializers.ts index 4c1cd2ba..93a531f0 100644 --- a/src/creation/initializers.ts +++ b/src/creation/initializers.ts @@ -1,6 +1,10 @@ -import { Tensor } from '../tensor'; +import { Tensor, NestedNumberArray } from '../tensor'; import { get_shape_from_args } from './utils'; +export function tensor(data: NestedNumberArray, requires_grad: boolean = false): Tensor { + return new Tensor(data, { requires_grad }); +} + export function ones(...args: number[] | number[][]): Tensor { const shape = get_shape_from_args(args); const tensor = new Tensor(Array(shape.reduce((a, b) => a * b, 1)).fill(1)); diff --git a/src/functions/functional.ts b/src/functions/functional.ts index b7a8f98d..6d516ac3 100644 --- a/src/functions/functional.ts +++ b/src/functions/functional.ts @@ -92,3 +92,7 @@ export const le = generate_binary_function('le'); export const ge = generate_binary_function('ge'); export const eq = generate_binary_function('eq'); export const ne = generate_binary_function('ne'); + +export function allclose(a: Tensor, b: Tensor, rtol: number = 1e-5, atol: number = 1e-8, equal_nan: boolean = false): boolean { + return a.allclose(b, rtol, atol, equal_nan); +} diff --git a/src/tensor.ts b/src/tensor.ts index 45501d99..911c43b3 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -345,6 +345,17 @@ export class Tensor { return this._executeBinaryOp('ne', other); } + allclose(other: Tensor, rtol: number = 1e-5, atol: number = 1e-8, equal_nan: boolean = false): boolean { + if (this.data.length !== other.data.length) return false; + for (let i = 0; i < this.data.length; i++) { + const av = this.data[i], bv = other.data[i]; + if (equal_nan && isNaN(av) && isNaN(bv)) continue; + if (isNaN(av) || isNaN(bv)) return false; + if (Math.abs(av - bv) > atol + rtol * Math.abs(bv)) return false; + } + return true; + } + // other sigmoid(): Tensor { diff --git a/test/functional.test.js b/test/functional.test.js index d1f6c1a5..5cfaae0c 100644 --- a/test/functional.test.js +++ b/test/functional.test.js @@ -120,4 +120,47 @@ describe('Functional', () => { assert.deepStrictEqual(result.shape, [2, 2]); }); }); + + describe('allclose', () => { + it('returns true for identical tensors', () => { + const a = new Tensor([1, 2, 3]); + assert.strictEqual(torch.allclose(a, a), true); + }); + + it('returns true for tensors within default tolerance', () => { + const a = new Tensor([1.0, 2.0, 3.0]); + const b = new Tensor([1.0, 2.0, 3.0 + 1e-7]); + assert.strictEqual(torch.allclose(a, b), true); + }); + + it('returns false for tensors outside default tolerance', () => { + const a = new Tensor([1.0, 2.0, 3.0]); + const b = new Tensor([1.0, 2.0, 4.0]); + assert.strictEqual(torch.allclose(a, b), false); + }); + + it('returns false for tensors of different sizes', () => { + const a = new Tensor([1, 2, 3]); + const b = new Tensor([1, 2]); + assert.strictEqual(torch.allclose(a, b), false); + }); + + it('returns false for NaN when equal_nan=false', () => { + const a = new Tensor([1, NaN, 3]); + const b = new Tensor([1, NaN, 3]); + assert.strictEqual(torch.allclose(a, b, 1e-5, 1e-8, false), false); + }); + + it('returns true for NaN when equal_nan=true', () => { + const a = new Tensor([1, NaN, 3]); + const b = new Tensor([1, NaN, 3]); + assert.strictEqual(torch.allclose(a, b, 1e-5, 1e-8, true), true); + }); + + it('tensor.allclose() method matches torch.allclose()', () => { + const a = new Tensor([1.0, 2.0, 3.0]); + const b = new Tensor([1.0, 2.0, 3.0 + 1e-7]); + assert.strictEqual(a.allclose(b), torch.allclose(a, b)); + }); + }); }); From 78a5f9590e74acb97c3d2a2ae3d8f25d1735086d Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 18 Mar 2026 19:48:14 +0800 Subject: [PATCH 111/128] feat: shape and toString --- package.json | 5 ++++- src/tensor.ts | 44 ++++++++++++++++++++++++++++++++++++++++- test/creation.test.ts | 46 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9a7e1405..44b277bd 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "packageManager": "yarn@4.10.3", "version": "0.1.0", "description": "machine-learning libraries for Source Academy", - "repository": "git@github.com/source-academy/torch.git", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/source-academy/torch.git" + }, "license": "Apache-2.0", "files": [ "build", diff --git a/src/tensor.ts b/src/tensor.ts index 911c43b3..4215935f 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -28,6 +28,34 @@ function _get_shape(data: NestedNumberArray): number[] { return shape; } +function _assert_shape(data: NestedNumberArray, shape: number[]): void { + if (Array.isArray(data)) { + if (data.length !== shape[0]) { + throw new Error(`Shape mismatch at dim ${shape.length}: expected ${shape[0]}, got ${data.length}`); + } + for (let i = 0; i < data.length; i++) { + _assert_shape(data[i], shape.slice(1)); + } + } else if (ArrayBuffer.isView(data)) { + if (shape.length !== 1) { + throw new Error(`Shape mismatch at dim ${shape.length}: expected 1D, got ${shape}`); + } + if (data.length !== shape[0]) { + throw new Error(`Shape mismatch at dim ${shape.length}: expected ${shape[0]}, got ${data.length}`); + } + } else { + if (shape.length !== 0) { + throw new Error(`Shape mismatch at dim ${shape.length}: expected scalar, got ${data}`); + } + } +} + +function _get_and_assert_shape(data: NestedNumberArray): number[] { + const shape = _get_shape(data); + _assert_shape(data, shape); + return shape; +} + function _flatten(data: NestedNumberArray): number[] { if (Array.isArray(data)) { return data.flatMap(item => _flatten(item)); @@ -65,7 +93,7 @@ export class Tensor { this.name = options.name; } - this.shape = internal_options.shape ?? _get_shape(data); + this.shape = internal_options.shape ?? _get_and_assert_shape(data); this.grad_fn = internal_options.operation ?? null; if (this.requires_grad && !this.grad_fn) { @@ -110,6 +138,20 @@ export class Tensor { return buildDimension(0); } + toString(): string { + let extra = ""; + if (this.name) { + extra += `, name="${this.name}"`; + } + if (this.dataLength() == 0 && this.shape.length > 0) { + extra += `, size=(${this.shape.join(', ')})`; + } + if (this.requires_grad) { + extra += ", requires_grad=True"; + } + return `Tensor(${JSON.stringify(this.toArray())}${extra})`; + } + dataLength(): number { return this.data.length; } diff --git a/test/creation.test.ts b/test/creation.test.ts index 94061bbc..85585b0c 100644 --- a/test/creation.test.ts +++ b/test/creation.test.ts @@ -3,6 +3,52 @@ import * as torch from 'torch'; import { Tensor } from 'torch'; describe('Creation Functions', () => { + describe('tensor', () => { + it('should create a scalar tensor', () => { + const t = torch.tensor(5); + assert.deepStrictEqual(t.toArray(), 5); + assert.deepStrictEqual(t.shape, []); + }); + + it('should create a tensor with 1D array', () => { + const t = torch.tensor([1, 2, 3]); + assert.deepStrictEqual(t.toArray(), [1, 2, 3]); + assert.deepStrictEqual(t.shape, [3]); + }); + + it('should create a tensor with nested 2D array', () => { + const t = torch.tensor([[1, 2], [3, 4]]); + assert.deepStrictEqual(t.toArray(), [[1, 2], [3, 4]]); + assert.deepStrictEqual(t.shape, [2, 2]); + }); + + it('should create a tensor with nested 3D array', () => { + const t = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]); + assert.deepStrictEqual(t.toArray(), [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]); + assert.deepStrictEqual(t.shape, [2, 2, 2]); + }); + + it('should create empty tensors', () => { + const t = torch.tensor([]); + assert.deepStrictEqual(t.toArray(), []); + assert.deepStrictEqual(t.shape, [0]); + + const t2 = torch.tensor([[]]); + assert.deepStrictEqual(t2.toArray(), [[]]); + assert.deepStrictEqual(t2.shape, [1, 0]); + + const t3 = torch.tensor([[], []]); + assert.deepStrictEqual(t3.toArray(), [[], []]); + assert.deepStrictEqual(t3.shape, [2, 0]); + }); + + it('should not create tensor with inconsistent shape', () => { + assert.throws(() => torch.tensor([[1, 2], [3]])); + assert.throws(() => torch.tensor([1, [2, 3]])); + assert.throws(() => torch.tensor([[1, 2], [3, 4, 5]])); + assert.throws(() => torch.tensor([[[1, 2], [3, 4]], [[5, 6]]])); + }); + }); describe('ones', () => { it('should create a 1D tensor of ones', () => { const t = torch.ones(5); From 8e7aedb5c4ffeb84861f1de0c79c4be2f85deb06 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 18 Mar 2026 19:50:42 +0800 Subject: [PATCH 112/128] feat: tensor.size() --- src/tensor.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/tensor.ts b/src/tensor.ts index 4215935f..78594d0d 100644 --- a/src/tensor.ts +++ b/src/tensor.ts @@ -103,6 +103,19 @@ export class Tensor { } } + size(dim?: number): number | number[] { + if (dim !== undefined) { + if (dim < 0) { + dim += this.shape.length; + } + if (dim < 0 || dim >= this.shape.length) { + throw new Error(`Dimension out of range (expected to be in range of [${-this.shape.length}, ${this.shape.length - 1}], but got ${dim})`); + } + return this.shape[dim]; + } + return this.shape; + } + toArray_(): void { return; } From 23fca0d5706d01ac54efdb04f15d23ab9ea3e355 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Wed, 18 Mar 2026 21:21:50 +0800 Subject: [PATCH 113/128] ci: docs/examples --- .github/workflows/build-test-publish.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index e38321b6..c001079e 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -48,6 +48,12 @@ jobs: cp -r build docs/media/build fi + - name: Copy examples to docs/examples + run: | + if [ -d "examples" ]; then + cp -r examples docs/examples + fi + - name: Copy examples to docs/media/examples run: | if [ -d "examples" ]; then From 88cbd07e3e094505558c2d65bea9b9394f7355f6 Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 20 Mar 2026 16:29:51 +0800 Subject: [PATCH 114/128] feat: no minify for npm, minify for cdn --- .github/workflows/build-test-publish.yml | 2 +- examples/browser/index.html | 2 +- examples/pyodide/index.html | 2 +- package.json | 10 +++-- test/optimizers.test.js | 6 +-- test/torch-bridge.js | 26 +++++++++++++ test/umd.html | 48 ++++++++++++++++++++++++ vite.config.browser.ts | 11 ++---- vite.config.cdn.ts | 20 ++++++++++ vite.config.node.ts | 3 +- 10 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 test/torch-bridge.js create mode 100644 test/umd.html create mode 100644 vite.config.cdn.ts diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index c001079e..905d4dd8 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -29,7 +29,7 @@ jobs: - name: Build run: yarn build - - name: Test on build/ to check minification does not break functionality + - name: Test on build/ run: yarn test:build - name: Build docs diff --git a/examples/browser/index.html b/examples/browser/index.html index 58c29572..fad64e69 100644 --- a/examples/browser/index.html +++ b/examples/browser/index.html @@ -5,7 +5,7 @@ torch.js browser backprop example - + diff --git a/examples/pyodide/index.html b/examples/pyodide/index.html index 89e82bd2..f3ea57b1 100644 --- a/examples/pyodide/index.html +++ b/examples/pyodide/index.html @@ -5,7 +5,7 @@ torch+pyodide browser backprop example - + diff --git a/package.json b/package.json index 44b277bd..f071a032 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,14 @@ "license": "Apache-2.0", "files": [ "build", - "examples", - "vendor" + "src", + "examples" ], "main": "./build/node/torch.node.cjs", "module": "./build/node/torch.node.es.mjs", "types": "./build/types/src/index.d.ts", + "unpkg": "./build/torch.min.js", + "jsdelivr": "./build/torch.min.js", "exports": { ".": { "torch-src": "./src/index.ts", @@ -35,8 +37,10 @@ "build:browser:watch": "vite build --config vite.config.browser.ts --watch", "build:node": "vite build --config vite.config.node.ts", "build:node:watch": "vite build --config vite.config.node.ts --watch", + "build:cdn": "vite build --config vite.config.cdn.ts", + "build:cdn:watch": "vite build --config vite.config.cdn.ts --watch", "build:types": "tsc -p tsconfig.build.json", - "build": "yarn clean && concurrently \"yarn build:node\" \"yarn build:browser\" \"yarn build:types\"", + "build": "yarn clean && concurrently \"yarn build:node\" \"yarn build:browser\" \"yarn build:cdn\" \"yarn build:types\"", "dev": "concurrently \"yarn:build:browser:watch\" \"yarn:build:node:watch\" \"yarn:test:watch\" \"yarn:serve\"", "docs": "typedoc --out docs src", "lint": "eslint src", diff --git a/test/optimizers.test.js b/test/optimizers.test.js index f3df1300..c19e76b8 100644 --- a/test/optimizers.test.js +++ b/test/optimizers.test.js @@ -8,10 +8,10 @@ describe('Optimizers', () => { it('should update parameters', () => { const x = new torch.Tensor([1.0], { requires_grad: true }); const sgd = new torch.optim.SGD([x], 0.01); - + const y = x.mul(new torch.Tensor(2.0)); y.backward(); - + /** * x = 1, grad = 2 * x_new = x - lr * grad = 1 - 0.01 * 2 = 0.98 @@ -46,7 +46,7 @@ describe('Optimizers', () => { y = x.pow(2); y.backward(); sgd.step(); - + actual = x.data[0]; assert.closeTo(actual, 0.32, EPS); }); diff --git a/test/torch-bridge.js b/test/torch-bridge.js new file mode 100644 index 00000000..86190f0e --- /dev/null +++ b/test/torch-bridge.js @@ -0,0 +1,26 @@ +const _torch = window.torch; + +export const { + Tensor, + no_grad, + enable_no_grad, + disable_no_grad, + is_grad_enabled, + TorchFunction, + AccumulateGrad, + nn, + optim, + eventBus, + events, + export_, + ExportedProgram, + add, + matmul, + relu, + mul, + randn, + allclose, + __right_index__, + __left_index__, + // etc... +} = window.torch; diff --git a/test/umd.html b/test/umd.html new file mode 100644 index 00000000..d35e29e3 --- /dev/null +++ b/test/umd.html @@ -0,0 +1,48 @@ + + + + + + Mocha Tests + + + + + +
+ + + + + + + + + + + + diff --git a/vite.config.browser.ts b/vite.config.browser.ts index 1b825bb6..9122ad90 100644 --- a/vite.config.browser.ts +++ b/vite.config.browser.ts @@ -3,22 +3,17 @@ import path from 'path'; export default defineConfig({ build: { - minify: true, + minify: false, sourcemap: true, lib: { entry: path.resolve(__dirname, 'src/index.ts'), name: 'torch', fileName: (format) => `torch.browser.${format}.js`, - formats: ['es', 'umd'] + formats: ['es'] // umd -> see cdn build }, outDir: 'build/browser', rollupOptions: { - treeshake: false, - output: { - compact: false, - inlineDynamicImports: false, - minifyInternalExports: false, - } + treeshake: true, }, }, esbuild: { diff --git a/vite.config.cdn.ts b/vite.config.cdn.ts new file mode 100644 index 00000000..dbfcb741 --- /dev/null +++ b/vite.config.cdn.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'vite'; +import path from 'path'; + +export default defineConfig({ + build: { + minify: 'esbuild', + sourcemap: true, + lib: { + entry: path.resolve(__dirname, 'src/index.ts'), + name: 'torch', + fileName: () => `torch.min.js`, + formats: ['umd'] + }, + emptyOutDir: false, + outDir: 'build', + }, + esbuild: { + keepNames: true, + } +}); diff --git a/vite.config.node.ts b/vite.config.node.ts index 4d071889..174682bc 100644 --- a/vite.config.node.ts +++ b/vite.config.node.ts @@ -3,6 +3,8 @@ import path from 'path'; export default defineConfig({ build: { + minify: false, // don't minify for npm package + sourcemap: true, lib: { entry: path.resolve(__dirname, 'src/index.ts'), fileName: (format) => format === 'es' ? 'torch.node.es.mjs' : 'torch.node.cjs', @@ -10,6 +12,5 @@ export default defineConfig({ }, outDir: 'build/node', target: 'node20', - minify: true, }, }); From df63799eb53c5bc5123b86800592301e0a56384b Mon Sep 17 00:00:00 2001 From: Hua Zhi Vee Date: Fri, 20 Mar 2026 16:36:23 +0800 Subject: [PATCH 115/128] ci: test in browser --- .github/workflows/build-test-publish.yml | 7 +++++++ test/index.html | 1 - test/umd.html | 1 - 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 905d4dd8..880c4448 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -32,6 +32,13 @@ jobs: - name: Test on build/ run: yarn test:build + - name: Test in browser + run: | + yarn serve & + npx wait-on tcp:8080 + npx mocha-headless-chrome -a no-sandbox -t 60000 -f http://127.0.0.1:8080/test/index.html + npx mocha-headless-chrome -a no-sandbox -t 60000 -f http://127.0.0.1:8080/test/umd.html + - name: Build docs run: yarn docs diff --git a/test/index.html b/test/index.html index dc286ba8..aad0bda7 100644 --- a/test/index.html +++ b/test/index.html @@ -16,7 +16,6 @@